An 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.
Better Auth uses better-call, which internally relies on rou3 for routing. Affected versions of rou3 normalize paths by removing empty segments. As a result:
/sign-in/email//sign-in/email///sign-in/email…all resolve to the same route.
Some production setups automatically collapse multiple slashes. This includes:
In these environments and other configurations where //path reach Better Auth as /path, the issue does not apply.
Updating rou3 to the latest version resolves the issue:
"rou3": "^0.5.1"Better Auth recommends:
const req = new Request(...) // this would be the actual request object
const url = new URL(req.url);
const normalizedPath = url.pathname.replace(/\/+/g, "/");
if (url.pathname !== normalizedPath) {
url.pathname = normalizedPath;
// Update the raw request pathname
Object.defineProperty(req, "url", {
value: url.toString(),
writable: true,
configurable: true,
});
}
disabledPathsThe impact of bypassing disabled paths could vary based on a project's configuration.
{
"cwe_ids": [
"CWE-400",
"CWE-41"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-16T21:22:45Z",
"nvd_published_at": null,
"severity": "HIGH"
}