{"id":"CVE-2025-71399","aliases":["GHSA-x732-6j76-qmhm"],"url":"https://o3.security/vulnerability/CVE-2025-71399","summary":"Better Auth before 1.4.5 Path Normalization Bypass via rou3","details":"## Summary\n\nAn issue in the underlying router library **rou3** can cause `/path` and `//path` to be treated as identical routes. If your environment does **not** normalize incoming URLs (e.g., by collapsing multiple slashes), this can allow bypasses of `disabledPaths` and path-based rate limits.\n\n## Details\n\nBetter Auth uses **better-call**, which internally relies on **rou3** for routing. Affected versions of rou3 normalize paths by removing empty segments. As a result:\n\n* `/sign-in/email`\n* `//sign-in/email`\n* `///sign-in/email`\n\n…all resolve to the same route.\n\nSome production setups *automatically* collapse multiple slashes. This includes:\n\n* Vercel with Nextjs (default)\n* Cloudflare - when normalize to urls origin is enabled (https://developers.cloudflare.com/rules/normalization/settings/#normalize-urls-to-origin)\n\nIn these environments and other configurations where `//path` reach Better Auth as `/path`, the issue does not apply.\n\n## Fix\n\nUpdating rou3 to the latest version resolves the issue:\n\n* better-call previously depended on `\"rou3\": \"^0.5.1\"`\n* The fix was introduced after that version\n  (commit: [https://github.com/h3js/rou3/commit/f60b43fa648399534507c9ac7db36d705b8874c3](https://github.com/h3js/rou3/commit/f60b43fa648399534507c9ac7db36d705b8874c3))\n\nBetter Auth recommends:\n\n1. **Upgrading to Better Auth v1.4.5 or later**, which includes the updated rou3.\n2. Ensuring the proxy normalizes URLs.\n3. If project maintainers cannot upgrade yet, they can protect their app by normalizing url before it reaches better-auth handler. See example below:\n```ts\nconst req = new Request(...) // this would be the actual request object\nconst url = new URL(req.url);\nconst normalizedPath = url.pathname.replace(/\\/+/g, \"/\");\n\nif (url.pathname !== normalizedPath) {\n  url.pathname = normalizedPath;\n  // Update the raw request pathname\n  Object.defineProperty(req, \"url\", {\n    value: url.toString(),\n    writable: true,\n    configurable: true,\n  });\n}\n```\n\n## Impact\n\n* Bypass `disabledPaths`\n* Bypass path-based rate limits\n\nThe impact of bypassing disabled paths could vary based on a project's configuration.","published":"2026-08-02T12:15:22.129Z","modified":"2026-10-28T02:31:00.122005634Z","cvss":null,"epss":{"score":0.00306,"percentile":0.23301,"asOf":"2026-09-16"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"better-auth","fixedVersion":"1.4.5"}],"fix":{"url":"https://github.com/better-auth/better-auth/commit/f60b43fa648399534507c9ac7db36d705b8874c3","label":"better-auth/better-auth@f60b43f"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/71xxx/CVE-2025-71399.json"},{"type":"ADVISORY","url":"https://github.com/better-auth/better-auth/security/advisories/GHSA-x732-6j76-qmhm"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-71399"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/better-auth-before-path-normalization-bypass-via-rou3"},{"type":"FIX","url":"https://github.com/better-auth/better-auth/commit/f60b43fa648399534507c9ac7db36d705b8874c3"},{"type":"PACKAGE","url":"https://github.com/better-auth/better-auth"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-28T02:31:00.122005634Z"}}