Every CVE Search/ Get API key

CVE-2026-45364

Better Auth: Rate limiter keys IPv6 addresses individually and is bypassable via prefix rotation

7.3 HighFix available

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.4.17 and 1.5.0-beta.9, Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys. This vulnerability is fixed in 1.4.17 and 1.5.0-beta.9.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
Low
Availability
Low

Exploit likelihood

0.29%Up 0.2 points since May 29, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.3

Better Auth: Rate limiter keys IPv6 addresses individually and is bypassable via prefix rotation

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.4.17 and 1.5.0-beta.9, Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys. This vulnerability is fixed in 1.4.17 and 1.5.0-beta.9.

Record
CVE-2026-45364
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-307
Updated
2026-11-02
EUVDEUVD-2026-33073 7.3

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.4.17 and 1.5.0-beta.9, Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys. This vulnerability is fixed in 1.4.17 and 1.5.0-beta.9.

Record
EUVD-2026-33073
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-p6v2-xcpg-h6xw 7.3

Better Auth: Rate limiter keys IPv6 addresses individually and is bypassable via prefix rotation

Am I affected?

Users are affected if all of the following are true:

  • Their app uses better-auth at a version < 1.4.17, or at a v1.5 prerelease tagged <= 1.5.0-beta.8.
  • The apps authentication endpoints serve clients reachable over IPv6. Most managed hosts including Cloudflare, Vercel, Fly.io, AWS Application Load Balancer, and Google Cloud Load Balancing advertise IPv6 by default.
  • The app's rate-limit configuration is enabled (the production default) and relies on the leftmost x-forwarded-for value (the stock setup) or any other configured IP-bearing header.

If users are on 1.4.16 specifically, the normalizeIP helper exists in your version but the IPv6 prefix length defaults to /128. Stock config still permits prefix rotation because no prefix mask is applied. Either upgrade to 1.4.17 or set advanced.ipAddress.ipv6Subnet: 64 in the config.

If applications do not use the rate limiter, or if the deployment serves only IPv4 clients, the prefix-rotation vector does not apply. The representation-aliasing vector still applies to IPv6 addresses delivered over IPv4 transport in some edge cases (an upstream proxy carrying an IPv4-mapped IPv6 source), but it is rare in practice.

Fix:

  1. Upgrade to [email protected] or later. The current stable line 1.6.x and the pre-release line 1.7.0-beta both carry the fix.
  2. If applications cannot upgrade, see workarounds below.

Summary

Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys.

Details

The pre-fix getIp function returned the leftmost x-forwarded-for value verbatim after a single validity check, and onRequestRateLimit constructed the rate-limit key by string concatenation of that value with the request path. Two facts of IPv6 made the key space larger than the population of clients:

  • ISPs and cloud providers assign prefixes, not addresses. RFC 6177 recommends /56 for residential users; cloud providers commonly assign /29 to /48. An attacker controlling a single /64 therefore controls 2^64 source addresses without doing anything unusual.
  • IPv6 has multiple textual representations for the same address. RFC 5952 specifies a canonical form, but RFC 4291 §2.2 permits the older mixed forms, and ::ffff:0:0/96 IPv4-mapped addresses can be written as either dotted-decimal or hex-encoded.

The fix in [email protected] introduces normalizeIP and applies it to every getIp result. Normalization expands compressed IPv6 forms, lowercases hex digits, collapses IPv4-mapped IPv6 to plain IPv4, and applies a default /64 prefix mask. The rate-limit key construction now uses an explicit | separator to prevent key-construction collisions across address-and-path joins.

The /64 default matches the smallest commonly-allocated IPv6 unit, so a single client cannot use prefix rotation to defeat rate limiting on stock config. Operators who serve clients on coarser allocations (/56 for residential ISPs, larger for cloud) can configure advanced.ipAddress.ipv6Subnet accordingly.

Patches

Fixed in [email protected] on the v1.4.x maintenance line and in [email protected] on the v1.5.x line. PR #7470 introduced the normalization primitive (packages/core/src/utils/ip.ts) and applied it to getIp and the rate-limit key. PR #7509 changed the IPv6 prefix-length default from /128 to /64 so that stock config closes the prefix-rotation vector without requiring users…

Record
GHSA-p6v2-xcpg-h6xw
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-307
Updated
2026-11-02
NVD 7.3

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.4.17 and 1.5.0-beta.9, Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys. This vulnerability is fixed in 1.4.17 and 1.5.0-beta.9.

Record
CVE-2026-45364
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-307
Updated
2026-11-02
OSV 7.3

Better Auth: Rate limiter keys IPv6 addresses individually and is bypassable via prefix rotation

Better Auth is an authentication and authorization library for TypeScript. Prior to 1.4.17 and 1.5.0-beta.9, Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys. This vulnerability is fixed in 1.4.17 and 1.5.0-beta.9.

Record
CVE-2026-45364
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-307
Updated
2026-11-02
OSVGHSA-p6v2-xcpg-h6xw 7.3

Better Auth: Rate limiter keys IPv6 addresses individually and is bypassable via prefix rotation

Am I affected?

Users are affected if all of the following are true:

  • Their app uses better-auth at a version < 1.4.17, or at a v1.5 prerelease tagged <= 1.5.0-beta.8.
  • The apps authentication endpoints serve clients reachable over IPv6. Most managed hosts including Cloudflare, Vercel, Fly.io, AWS Application Load Balancer, and Google Cloud Load Balancing advertise IPv6 by default.
  • The app's rate-limit configuration is enabled (the production default) and relies on the leftmost x-forwarded-for value (the stock setup) or any other configured IP-bearing header.

If users are on 1.4.16 specifically, the normalizeIP helper exists in your version but the IPv6 prefix length defaults to /128. Stock config still permits prefix rotation because no prefix mask is applied. Either upgrade to 1.4.17 or set advanced.ipAddress.ipv6Subnet: 64 in the config.

If applications do not use the rate limiter, or if the deployment serves only IPv4 clients, the prefix-rotation vector does not apply. The representation-aliasing vector still applies to IPv6 addresses delivered over IPv4 transport in some edge cases (an upstream proxy carrying an IPv4-mapped IPv6 source), but it is rare in practice.

Fix:

  1. Upgrade to [email protected] or later. The current stable line 1.6.x and the pre-release line 1.7.0-beta both carry the fix.
  2. If applications cannot upgrade, see workarounds below.

Summary

Better Auth's HTTP rate limiter keyed each request by the exact textual IP address it received in x-forwarded-for (or the configured IP-bearing header). IPv6 clients controlling a typical /64 allocation could rotate through 2^64 distinct source addresses without exhausting the per-address counter, defeating rate limiting on /sign-in/email, /sign-up/email, /forget-password, and every other path the limiter protects. The same bug allowed a single client to vary the textual encoding of one IPv6 address (uppercase, compression, IPv4-mapped, hex-encoded IPv4-in-IPv6) and produce multiple distinct keys.

Details

The pre-fix getIp function returned the leftmost x-forwarded-for value verbatim after a single validity check, and onRequestRateLimit constructed the rate-limit key by string concatenation of that value with the request path. Two facts of IPv6 made the key space larger than the population of clients:

  • ISPs and cloud providers assign prefixes, not addresses. RFC 6177 recommends /56 for residential users; cloud providers commonly assign /29 to /48. An attacker controlling a single /64 therefore controls 2^64 source addresses without doing anything unusual.
  • IPv6 has multiple textual representations for the same address. RFC 5952 specifies a canonical form, but RFC 4291 §2.2 permits the older mixed forms, and ::ffff:0:0/96 IPv4-mapped addresses can be written as either dotted-decimal or hex-encoded.

The fix in [email protected] introduces normalizeIP and applies it to every getIp result. Normalization expands compressed IPv6 forms, lowercases hex digits, collapses IPv4-mapped IPv6 to plain IPv4, and applies a default /64 prefix mask. The rate-limit key construction now uses an explicit | separator to prevent key-construction collisions across address-and-path joins.

The /64 default matches the smallest commonly-allocated IPv6 unit, so a single client cannot use prefix rotation to defeat rate limiting on stock config. Operators who serve clients on coarser allocations (/56 for residential ISPs, larger for cloud) can configure advanced.ipAddress.ipv6Subnet accordingly.

Patches

Fixed in [email protected] on the v1.4.x maintenance line and in [email protected] on the v1.5.x line. PR #7470 introduced the normalization primitive (packages/core/src/utils/ip.ts) and applied it to getIp and the rate-limit key. PR #7509 changed the IPv6 prefix-length default from /128 to /64 so that stock config closes the prefix-rotation vector without requiring users…

Record
GHSA-p6v2-xcpg-h6xw
CVSS 3.1
7.3 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
Weakness
CWE-307
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
better-auth
npm
before 1.4.17
1.4.17
better-auth
npm
1.5.0-beta.1 up to 1.5.0-beta.9
1.5.0-beta.9

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-45364 is a high vulnerability (CVSS 7.3) in Better-auth, published May 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.29%, the 22nd percentile. Fixed in better-auth 1.4.17.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open