The vulnerability lies in how Better Auth's rate limiter identifies clients. The system used the raw IP address string from the x-forwarded-for header to create a rate-limiting key. This approach is flawed for IPv6 due to two main factors:
-
Representation Aliasing: IPv6 addresses have multiple valid textual representations (e.g., compressed with ::, uppercase/lowercase hex digits, IPv4-mapped formats). The vulnerable code treated each unique string as a separate client, allowing an attacker to bypass rate limits by simply reformatting the same IP address.
-
Prefix Rotation: ISPs and cloud providers assign large blocks of IPv6 addresses (typically a /64 subnet containing 2^64 addresses) to a single client. The vulnerable code keyed on individual IP addresses, allowing an attacker to easily cycle through their vast allocation to generate a near-infinite number of unique rate-limit keys, effectively making the rate limiter useless.
The primary vulnerable function was getIp, which extracted the IP without normalization. This un-normalized IP was then used in onRequestRateLimit to construct a weak rate-limit key via simple string concatenation. The fix involved introducing a normalizeIP function to canonicalize IPv6 addresses and, crucially, to group them by a /64 subnet by default, ensuring all traffic from a single client's network is treated as a single entity for rate-limiting purposes.