Skip to content

Commit c083be9

Browse files
authored
improvement(auth): bump better-auth to 1.6.23 and add trusted-proxy client IP resolution (#5857)
* improvement(auth): bump better-auth to 1.6.23 and add trusted-proxy client IP resolution * chore(billing): record checkout-scope mirror re-verification against @better-auth/stripe 1.6.23 * chore(deploy): expose AUTH_TRUSTED_PROXIES in docker-compose.prod and Helm chart
1 parent 49d3804 commit c083be9

10 files changed

Lines changed: 66 additions & 23 deletions

File tree

apps/sim/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ BETTER_AUTH_URL=http://localhost:3000
1919
NEXT_PUBLIC_APP_URL=http://localhost:3000
2020
# INTERNAL_API_BASE_URL=http://sim-app.default.svc.cluster.local:3000 # Optional: internal URL for server-side /api self-calls; defaults to NEXT_PUBLIC_APP_URL
2121
# TRUSTED_ORIGINS=https://www.example.com,https://app.example.com # Optional: comma-separated additional public origins to trust for auth (apex+www, alias domains). Merged into Better Auth trustedOrigins.
22+
# AUTH_TRUSTED_PROXIES=10.0.0.0/24,192.0.2.10 # Optional: reverse-proxy IPs/CIDRs in front of the app. Better Auth walks x-forwarded-for right to left, skips these hops, and uses the first untrusted address as the client IP (prevents forwarded-header spoofing). Use your proxies' actual addresses, not broad private ranges that also cover clients.
2223

2324
# Security (Required)
2425
ENCRYPTION_KEY=your_encryption_key # Use `openssl rand -hex 32` to generate, used to encrypt environment variables

apps/sim/lib/auth/auth.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ if (validStripeKey) {
193193
})
194194
}
195195

196+
/**
197+
* Reverse-proxy hops trusted for forwarded-IP resolution. When configured,
198+
* Better Auth walks the x-forwarded-for chain right to left, skips these
199+
* hops, and records the first untrusted address as the session client IP —
200+
* preventing header spoofing behind multi-hop proxies.
201+
*/
202+
const trustedProxies = (env.AUTH_TRUSTED_PROXIES ?? '')
203+
.split(',')
204+
.map((entry) => entry.trim())
205+
.filter(Boolean)
206+
196207
export const auth = betterAuth({
197208
baseURL: getBaseUrl(),
198209
trustedOrigins: [
@@ -216,6 +227,11 @@ export const auth = betterAuth({
216227
updateAge: 24 * 60 * 60, // 24 hours (how often to refresh the expiry)
217228
freshAge: 0,
218229
},
230+
advanced: {
231+
ipAddress: {
232+
...(trustedProxies.length > 0 ? { trustedProxies } : {}),
233+
},
234+
},
219235
user: {
220236
deleteUser: {
221237
enabled: false,

apps/sim/lib/billing/authorization.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ const logger = createLogger('BillingAuthorization')
1616
/**
1717
* Classify a `/subscription/upgrade` request as a personal checkout using
1818
* the same reference resolution as the Better Auth Stripe plugin
19-
* (`@better-auth/stripe` 1.6.13): an explicit `referenceId` defines the
19+
* (`@better-auth/stripe` 1.6.23, `referenceMiddleware` — classification
20+
* unchanged from 1.6.13; 1.6.23 only moved the resolved `referenceId` into
21+
* the middleware return value): an explicit `referenceId` defines the
2022
* reference (personal iff it is the session user); without one, the
2123
* reference defaults to the user unless `customerType: 'organization'`
2224
* selects the session's active organization.

apps/sim/lib/core/config/env.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ export const env = createEnv({
477477
REACT_GRAB_ENABLED: z.boolean().optional(), // Enable React Grab for UI element debugging in Cursor/AI agents (dev only)
478478
REACT_SCAN_ENABLED: z.boolean().optional(), // Enable React Scan for performance debugging (dev only)
479479

480+
// Network / proxy trust
481+
AUTH_TRUSTED_PROXIES: z.string().optional(), // Comma-separated reverse-proxy IPs or CIDR ranges. When set, Better Auth walks the forwarded-IP chain right to left, skips these trusted hops, and uses the first untrusted address as the client IP. Leave unset to trust only single-value IP headers.
482+
480483
// SSO Configuration (for script-based registration)
481484
SSO_ENABLED: z.boolean().optional(), // Enable SSO functionality
482485
SSO_PROVIDER_TYPE: z.enum(['oidc', 'saml']).optional(), // [REQUIRED] SSO provider type

apps/sim/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@
6060
"@aws-sdk/s3-request-presigner": "3.1032.0",
6161
"@azure/communication-email": "1.0.0",
6262
"@azure/storage-blob": "12.27.0",
63-
"@better-auth/sso": "1.6.13",
64-
"@better-auth/stripe": "1.6.13",
63+
"@better-auth/sso": "1.6.23",
64+
"@better-auth/stripe": "1.6.23",
6565
"@browserbasehq/stagehand": "^3.2.1",
6666
"@calcom/embed-react": "1.5.3",
6767
"@cerebras/cerebras_cloud_sdk": "^1.23.0",
@@ -129,7 +129,7 @@
129129
"@trigger.dev/sdk": "4.4.3",
130130
"@typescript/typescript6": "^6.0.2",
131131
"ajv": "8.18.0",
132-
"better-auth": "1.6.13",
132+
"better-auth": "1.6.23",
133133
"binary-extensions": "3.1.0",
134134
"browser-image-compression": "^2.0.2",
135135
"busboy": "1.6.0",

bun.lock

Lines changed: 24 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)