[Bug]: "Invalid callback URL - must be same-origin" with reverse proxy #3275

Closed
opened 2026-04-25 00:14:42 +02:00 by adam · 4 comments
Owner

Originally created by @hanjo on GitHub (Mar 23, 2026).

What happened?

Hi,

I have set up OIDC in audiobookshelf and it works fine locally. By locally I mean I can access audiobookshelf within my network by using my custom DNS name, let's say abs.int, which points to a local (internal) reverse proxy.

When I try access audibookshelf through my internet facing reverse proxy (who in turn connects to the local reverse proxy) by using the internet DNS name, let's say abs.ext, the OIDC auth fails with the error message

Invalid callback URL - must be same-origin

and I see the following lines in the log:

[2026-03-23 17:54:48.010] WARN: [OidcAuth] Rejected callback URL to different origin: https://abs.ext/audiobookshelf/login (expected https://abs.int)
[2026-03-23 17:54:48.011] WARN: [Auth] Rejected invalid callback URL: https://abs.ext/audiobookshelf/login

I understand why this is happening (because the internet facing reverse proxy is using https://abs.int to access the audiobookshelf through the local (internal) proxy), but not how to fix it in my setup / configuration.

Any suggestion is highly appreciated.
Thanks!

What did you expect to happen?

Accept external URL as well.

Steps to reproduce the issue

  1. Configure external and internal reverse proxy with different DNS names. Point external reverse proxy to internal reverse proxy and internal reverse proxy to audiobookshelf (I'm using Caddy for the internal reverse proxy and pangolin/newt for the external reverse proxy, if that makes any difference). Configure the the external reverse proxy IP addresses as trusted in the internal reverse proxy configuration).
  2. Set up OIDC.
  3. Login to internal DNS name
  4. Login to external DNS name

Audiobookshelf version

v2.33.1

How are you running audiobookshelf?

Docker

What OS is your Audiobookshelf server hosted from?

Linux

If the issue is being seen in the UI, what browsers are you seeing the problem on?

Firefox

Logs

[2026-03-23 17:54:48.010] WARN: [OidcAuth] Rejected callback URL to different origin: https://abs.ext/audiobookshelf/login (expected https://abs.int)
[2026-03-23 17:54:48.011] WARN: [Auth] Rejected invalid callback URL: https://abs.ext/audiobookshelf/login

Additional Notes

No response

Originally created by @hanjo on GitHub (Mar 23, 2026). ### What happened? Hi, I have set up OIDC in audiobookshelf and it works fine locally. By locally I mean I can access audiobookshelf within my network by using my custom DNS name, let's say `abs.int`, which points to a local (internal) reverse proxy. When I try access audibookshelf through my internet facing reverse proxy (who in turn connects to the local reverse proxy) by using the internet DNS name, let's say `abs.ext`, the OIDC auth fails with the error message ``` Invalid callback URL - must be same-origin ``` and I see the following lines in the log: ``` [2026-03-23 17:54:48.010] WARN: [OidcAuth] Rejected callback URL to different origin: https://abs.ext/audiobookshelf/login (expected https://abs.int) [2026-03-23 17:54:48.011] WARN: [Auth] Rejected invalid callback URL: https://abs.ext/audiobookshelf/login ``` I understand why this is happening (because the internet facing reverse proxy is using `https://abs.int` to access the audiobookshelf through the local (internal) proxy), but not how to fix it in my setup / configuration. Any suggestion is highly appreciated. Thanks! ### What did you expect to happen? Accept external URL as well. ### Steps to reproduce the issue 1. Configure external and internal reverse proxy with different DNS names. Point external reverse proxy to internal reverse proxy and internal reverse proxy to audiobookshelf (I'm using Caddy for the internal reverse proxy and pangolin/newt for the external reverse proxy, if that makes any difference). Configure the the external reverse proxy IP addresses as trusted in the internal reverse proxy configuration). 2. Set up OIDC. 3. Login to internal DNS name 4. Login to external DNS name ### Audiobookshelf version v2.33.1 ### How are you running audiobookshelf? Docker ### What OS is your Audiobookshelf server hosted from? Linux ### If the issue is being seen in the UI, what browsers are you seeing the problem on? Firefox ### Logs ```shell [2026-03-23 17:54:48.010] WARN: [OidcAuth] Rejected callback URL to different origin: https://abs.ext/audiobookshelf/login (expected https://abs.int) [2026-03-23 17:54:48.011] WARN: [Auth] Rejected invalid callback URL: https://abs.ext/audiobookshelf/login ``` ### Additional Notes _No response_
adam added the bug label 2026-04-25 00:14:42 +02:00
adam closed this issue 2026-04-25 00:14:42 +02:00
Author
Owner

@Vito0912 commented on GitHub (Mar 23, 2026):

Your proxy has to pass the correct host. This is not an ABS bug, but a misconfiguration in your reverse proxy. You need to pass along the original host, not the one from your RP. As your second RP sees your first RP as host, it probably sends that as a host.
How to solve that is better asked in the forums of the RPs you use instead of here imho

Edit: If you use Pangolin anyways, the intended way is to just use that as the RP directly, instead of going trough another RP

@Vito0912 commented on GitHub (Mar 23, 2026): Your proxy has to pass the correct host. This is not an ABS bug, but a misconfiguration in your reverse proxy. You need to pass along the original host, not the one from your RP. As your second RP sees your first RP as host, it probably sends that as a host. How to solve that is better asked in the forums of the RPs you use instead of here imho Edit: If you use Pangolin anyways, the intended way is to just use that as the RP directly, instead of going trough another RP
Author
Owner

@hanjo commented on GitHub (Mar 23, 2026):

Yeah, I'm doing that already, the Host-Header is set to abs.int as well as the SNI to avoid any certificate issues.

And from what I can see from the logs it also works (as can be seen in the first line at the end after "expected"). However, the callback URL is showing the external fqdn:

https://abs.ext/audiobookshelf/auth/openid?callback=https://abs.ext/audiobookshelf/login

which makes sense, since the redirect needs to be to the external URL (the internal URL wouldn't be reachable from the internet). But this is where the error occurs.

@hanjo commented on GitHub (Mar 23, 2026): Yeah, I'm doing that already, the Host-Header is set to `abs.int` as well as the SNI to avoid any certificate issues. And from what I can see from the logs it also works (as can be seen in the first line at the end after "expected"). However, the callback URL is showing the external fqdn: ``` https://abs.ext/audiobookshelf/auth/openid?callback=https://abs.ext/audiobookshelf/login ``` which makes sense, since the redirect needs to be to the external URL (the internal URL wouldn't be reachable from the internet). But this is where the error occurs.
Author
Owner

@Vito0912 commented on GitHub (Mar 23, 2026):

Yeah, I'm doing that already, the Host-Header is set to abs.int as well as the SNI to avoid any certificate issues.

That is exactly your issue here. As stated above, it expects external, because you access it from external. You can't do it that way. You need to pass the correct host. external needs the external host. Internal needs the internal host.

Otherwise the whole callback wouldn't work too. This was added a few versions back due to extreme security issues this would lead to if that was not the case. The callback has to match the host it sends from

@Vito0912 commented on GitHub (Mar 23, 2026): > Yeah, I'm doing that already, the Host-Header is set to abs.int as well as the SNI to avoid any certificate issues. That is exactly your issue here. As stated above, it expects external, because you access it from external. You can't do it that way. You need to pass the correct host. external needs the external host. Internal needs the internal host. Otherwise the whole callback wouldn't work too. This was added a few versions back due to extreme security issues this would lead to if that was not the case. The callback has to match the host it sends from
Author
Owner

@hanjo commented on GitHub (Mar 23, 2026):

Ah, I can see the security implications. This makes sense, thanks for point me in the right direction.

I agree this is not a bug, so I will close this. For anyone coming here later, this is how I fixed it for me:

I configured caddy to overwrite the Host-header when the X-Forwarded-Host-header from the upstream reverse proxy matches my external domain and the request is coming from my trusted upstream reverse proxy.
This is my config:

https://abs.int:443 {
        encode gzip zstd
        @trusted {
                # reverse proxy IPs
                remote_ip 192.168.123.45 fd4e::abcd
                # original request host
                expression {header.X-Forwarded-Host} == "abs.ext"
        }
        reverse_proxy @trusted abs:80 {
                header_up Host {header.X-Forwarded-Host}
        }
        reverse_proxy abs:80
}

Of course, an alternative to this would be to point the outer reverse proxy directly to audiobookshelf, but I appreciated the challenge 🤓

@hanjo commented on GitHub (Mar 23, 2026): Ah, I can see the security implications. This makes sense, thanks for point me in the right direction. I agree this is not a bug, so I will close this. For anyone coming here later, this is how I fixed it for me: I configured caddy to overwrite the `Host`-header when the `X-Forwarded-Host`-header from the upstream reverse proxy matches my external domain and the request is coming from my trusted upstream reverse proxy. This is my config: ``` https://abs.int:443 { encode gzip zstd @trusted { # reverse proxy IPs remote_ip 192.168.123.45 fd4e::abcd # original request host expression {header.X-Forwarded-Host} == "abs.ext" } reverse_proxy @trusted abs:80 { header_up Host {header.X-Forwarded-Host} } reverse_proxy abs:80 } ``` Of course, an alternative to this would be to point the outer reverse proxy directly to audiobookshelf, but I appreciated the challenge 🤓
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#3275