mirror of
https://github.com/better-auth/better-auth.git
synced 2026-07-26 22:42:35 -05:00
fix(auth)!: ignore x-forwarded headers by default on dynamic baseURL (#9134)
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
---
|
||||
"better-auth": minor
|
||||
---
|
||||
|
||||
The dynamic `baseURL` config now ignores `x-forwarded-host` and `x-forwarded-proto` unless you set `advanced.trustedProxyHeaders: true`.
|
||||
|
||||
Requests using `baseURL: { allowedHosts }` now resolve the auth origin from `Host` by default, so forwarded headers cannot select another allowed host unless trusted proxy headers are enabled.
|
||||
|
||||
**Breaking change:** if your proxy exposes the public hostname only through `x-forwarded-host`, set `advanced.trustedProxyHeaders: true`. Deployments where the proxy rewrites `Host` to the public hostname (nginx default, Vercel, Cloudflare, and Netlify) are unaffected.
|
||||
|
||||
**Migration:**
|
||||
|
||||
```ts
|
||||
betterAuth({
|
||||
baseURL: { allowedHosts: [...] },
|
||||
advanced: {
|
||||
trustedProxyHeaders: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -1029,6 +1029,27 @@ describe("dynamic baseURL resolution", () => {
|
||||
expect(sharedCtx.baseURL).toBe("");
|
||||
});
|
||||
|
||||
/**
|
||||
* @see https://github.com/better-auth/better-auth/pull/9134
|
||||
*/
|
||||
it("should ignore x-forwarded headers when trustedProxyHeaders is not configured", async () => {
|
||||
const authContext = init({
|
||||
baseURL: {
|
||||
allowedHosts: ["example.com", "proxy.example.com"],
|
||||
},
|
||||
});
|
||||
const authEndpoints = toAuthEndpoints(endpoints, authContext);
|
||||
|
||||
const res = await authEndpoints.readBaseURL({
|
||||
headers: new Headers({
|
||||
host: "example.com",
|
||||
"x-forwarded-host": "proxy.example.com",
|
||||
"x-forwarded-proto": "http",
|
||||
}),
|
||||
});
|
||||
expect(res.baseURL).toBe("https://example.com/api/auth");
|
||||
});
|
||||
|
||||
it("should ignore x-forwarded-host when trustedProxyHeaders is explicitly disabled", async () => {
|
||||
const authContext = init({
|
||||
baseURL: {
|
||||
|
||||
@@ -190,14 +190,15 @@ export function pickSource(
|
||||
|
||||
/**
|
||||
* Returns the effective `trustedProxyHeaders` value for dynamic `baseURL`
|
||||
* resolution. When the user hasn't set `advanced.trustedProxyHeaders`,
|
||||
* proxy headers (`x-forwarded-host` / `x-forwarded-proto`) are trusted by
|
||||
* default so deployments behind a reverse proxy work without extra config.
|
||||
* resolution. Proxy headers (`x-forwarded-host` / `x-forwarded-proto`) are
|
||||
* ignored unless the user opts in with `advanced.trustedProxyHeaders: true`,
|
||||
* matching the static-config path. Deployments behind a reverse proxy that
|
||||
* only exposes the public host via `x-forwarded-host` must set the flag.
|
||||
*/
|
||||
export function resolveDynamicTrustedProxyHeaders(
|
||||
options: BetterAuthOptions,
|
||||
): boolean {
|
||||
return options.advanced?.trustedProxyHeaders ?? true;
|
||||
return options.advanced?.trustedProxyHeaders ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user