From ae90b482d09ff7085aae1df24cfbce541b525ef6 Mon Sep 17 00:00:00 2001 From: Taesu <166604494+bytaesu@users.noreply.github.com> Date: Tue, 23 Dec 2025 15:08:58 +0900 Subject: [PATCH] fix: correct wildcard pattern matching for `trustedOrigins` (#6904) --- docs/content/docs/integrations/expo.mdx | 10 +++---- docs/content/docs/reference/options.mdx | 27 +++++++++++++++++-- docs/content/docs/reference/security.mdx | 4 +-- .../better-auth/src/auth/trusted-origins.ts | 4 ++- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/docs/content/docs/integrations/expo.mdx b/docs/content/docs/integrations/expo.mdx index b44060aefb..3b89e980ab 100644 --- a/docs/content/docs/integrations/expo.mdx +++ b/docs/content/docs/integrations/expo.mdx @@ -160,16 +160,16 @@ Expo is a popular framework for building cross-platform apps with React Native. // Development mode - Expo's exp:// scheme with local IP ranges ...(process.env.NODE_ENV === "development" ? [ - "exp://*/*", // Trust all Expo development URLs - "exp://10.0.0.*:*/*", // Trust 10.0.0.x IP range - "exp://192.168.*.*:*/*", // Trust 192.168.x.x IP range - "exp://172.*.*.*:*/*", // Trust 172.x.x.x IP range - "exp://localhost:*/*" // Trust localhost + "exp://", // Trust all Expo URLs (prefix matching) + "exp://**", // Trust all Expo URLs (wildcard matching) + "exp://192.168.*.*:*/**", // Trust 192.168.x.x IP range with any port and path ] : []) ] }) ``` + For more information about trusted origins, see [here](/docs/reference/options#trustedorigins). + The wildcard patterns for `exp://` should only be used in development. In production, use your app's specific scheme (e.g., `myapp://`). diff --git a/docs/content/docs/reference/options.mdx b/docs/content/docs/reference/options.mdx index 135e69371f..43e6b3d4f3 100644 --- a/docs/content/docs/reference/options.mdx +++ b/docs/content/docs/reference/options.mdx @@ -95,8 +95,31 @@ export const auth = betterAuth({ }) ``` - - Make sure to provide the protocol prefix when using wildcard patterns. For example, `https://*.example.com` instead of `*.example.com`. +#### Pattern Syntax + +| Pattern | Description | +|---------|-------------| +| `?` | Matches exactly one character (except `/`) | +| `*` | Matches zero or more characters that don't cross `/` | +| `**` | Matches zero or more characters including `/` | + +#### Pattern Examples + +| Pattern | Matches | Does Not Match | +|---------|---------|----------------| +| `http://*.example.com` | `http://api.example.com`
`http://app.example.com`
`http://api.app.example.com` | `https://api.example.com`
`http://example.com` | +| `https://**.example.com` | `https://api.example.com`
`https://api.app.example.com` | `http://api.example.com` | +| `https://example.com` | `https://example.com`
`https://example.com/path` | `https://api.example.com`
`http://example.com` | +| `exp://192.168.*.*:*/**` | `exp://192.168.1.100:8081/path`
`exp://192.168.50.200:19000/auth/callback` | `exp://10.0.0.29:8081/path` | +| `myapp://` | All URLs starting with `myapp://` | - | + + + +**Notes** + +- For `http://` and `https://` URLs, patterns match the full origin. Paths and query strings are ignored. +- For custom schemes (like `exp://` or `myapp://`), patterns match against the full URL including paths when wildcards are present, or use prefix matching when no wildcards exist. +- The separator is `/` (forward slash). This means `http://*.example.com` matches both `http://api.example.com` and `http://api.app.example.com`. ## `secret` diff --git a/docs/content/docs/reference/security.mdx b/docs/content/docs/reference/security.mdx index 3c8fd3520c..4e401bdd0f 100644 --- a/docs/content/docs/reference/security.mdx +++ b/docs/content/docs/reference/security.mdx @@ -161,8 +161,8 @@ Trusted origins also support custom schemes for mobile apps and browser extensio trustedOrigins: [ "myapp://", // Mobile app scheme "chrome-extension://YOUR_EXTENSION_ID", // Browser extension - "exp://*/*", // Trust all Expo development URLs - "exp://10.0.0.*:*/*", // Trust 10.0.0.x IP range with any port + "exp://**", // Trust all Expo development URLs + "exp://10.0.0.*:*/**", // Trust 10.0.0.x IP range with any port ] } ``` diff --git a/packages/better-auth/src/auth/trusted-origins.ts b/packages/better-auth/src/auth/trusted-origins.ts index fea9e5c097..0ceb8a2886 100644 --- a/packages/better-auth/src/auth/trusted-origins.ts +++ b/packages/better-auth/src/auth/trusted-origins.ts @@ -26,7 +26,9 @@ export const matchesOriginPattern = ( return false; } - if (pattern.includes("*")) { + // Check if pattern contains wildcard characters (*, **, or ?) + const hasWildcard = pattern.includes("*") || pattern.includes("?"); + if (hasWildcard) { // For protocol-specific wildcards, match the full origin if (pattern.includes("://")) { return wildcardMatch(pattern)(getOrigin(url) || url);