fix: secure authentication request identity
Replace Better Auth's default trust of a caller-controlled X-Forwarded-For with a platform-owned client-address resolution boundary: direct mode (the safe default) trusts only the real socket peer, and an explicit trusted-proxy mode requires a header name, a concrete trusted-proxy list, and only honors a forwarded chain from an actual trusted peer. This closes a rate-limit bypass where rotating a spoofed header let a caller choose a fresh bucket on every request. Public sign-up is also disabled by default and requires an explicit typed opt-in, using Better Auth's own disableSignUp gate so no email-existence leak or second signup path is introduced. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5e09330001
commit
cafd513019
+11
-1
@@ -4,6 +4,11 @@ import {
|
||||
type IdentityConfig,
|
||||
type IdentityConfigInput,
|
||||
} from "@ekklesia/core/identity";
|
||||
import {
|
||||
type ClientAddressConfig,
|
||||
type ClientAddressConfigInput,
|
||||
createClientAddressConfig,
|
||||
} from "./client-address.js";
|
||||
|
||||
export type ApiConfigErrorCode =
|
||||
| "DATABASE_URL_INVALID"
|
||||
@@ -37,6 +42,7 @@ const defaultHost = "127.0.0.1";
|
||||
const defaultPort = 3000;
|
||||
|
||||
export interface ApiRuntimeConfig {
|
||||
readonly clientAddress: ClientAddressConfig;
|
||||
readonly databaseUrl: string;
|
||||
readonly host: string;
|
||||
readonly identity: IdentityConfig;
|
||||
@@ -44,6 +50,9 @@ export interface ApiRuntimeConfig {
|
||||
}
|
||||
|
||||
export interface ApiRuntimeConfigInput {
|
||||
/** Optional. Defaults to direct mode (trusts only the actual immediate socket peer) — no proxy
|
||||
* trust unless explicitly configured. See `./client-address.js`. */
|
||||
readonly clientAddress?: ClientAddressConfigInput;
|
||||
readonly databaseUrl?: unknown;
|
||||
readonly host?: unknown;
|
||||
readonly identity: IdentityConfigInput;
|
||||
@@ -112,6 +121,7 @@ export function createApiRuntimeConfig(
|
||||
input.identity,
|
||||
options.environment === undefined ? {} : { environment: options.environment },
|
||||
);
|
||||
const clientAddress = createClientAddressConfig(input.clientAddress);
|
||||
|
||||
return Object.freeze({ databaseUrl, host, identity, port });
|
||||
return Object.freeze({ clientAddress, databaseUrl, host, identity, port });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user