Rate Limiting Does Not Work
I'm trying to test rate limiting on dev, but unfortunately it doesn't limit anything.
This is my config:
This is how I try to test the rate limiting:
Due to the config, I'd expect that I can only log in once per minute. But unfortunately, I'm not getting rate limited.
Any ideas?
27 Replies
Have you tried with redis as a storage?
No, I thought "memory" is a valid option.
I mean you can use it i think, but its not a valid approach for production apps
In addition to the default settings, Better Auth provides custom rules for specific paths. For example:
/sign-in/email: Is limited to 3 requests within 10 seconds.
In addition, plugins also define custom rules for specific paths. For example, twoFactor plugin has custom rules:
/two-factor/verify: Is limited to 3 requests within 10 seconds.
These custom rules ensure that sensitive operations are protected with stricter limits.
have you read the docs?
maybe you have to change the custom path
i mean
yes, I checked the docs and also tried with the custom rules. also did not work.
try adding the window and max to the /sign-in/email
then try using redis as your storage
if these not work
I changed to storage: "database", but it still doesn't work.
Same here! So far, I haven't managed to get it to work locally. I've enabled it in the config, but I've only been making API calls from the API explorer, so idk if those requests don't get rate-limited. I'll try with the actual client apps soon.
Hey guys, just tested on my end and things are not working either :/
It's odd because I'm pretty certain we have unit-tests on this, I'll dig further and let yall know if I find anything.
Yeah, auth.api doesn't get rate-limited.
Okay just talked to Bekacru, and it's most likely because there may not be an ip address in dev.
Please everyone check that your session table has
ip_address
field not empty, if it's empty then rate-limits can't be capturedThat's exactly the problem. The "rateLimit" table was empty the whole time. I just re-tested using ngrok and it works.
Any idea how we can work around that in dev?
I'm not too sure. I'll ask Bekacru and if he has a solution then I'll get back to you.
awesome, thanks!!
I don't think theres a way right now sadly
Thank you anyways for double-checking.
For others having the same issue: try using ngrok or Localcan with public URLs.
@Ping Why do you only capture rate limits when
ip_address
is available on the session?
Does this mean that hits to /api/auth*
without a session (or session.ip_address
) are not rate limited? Or are those not persisted to the database? Are those stored in memory? Or not rate limited at all?
Effectively I'm asking how this would protect us from brute force attacks on say an email+password login field.the ip_address is captured from headers, right? which one?
@Ping May I ask, if there's an update on this?
We currently rely on the
ip_address
that would theoretically be available on the session. However, if no proxy or middleware is configured to add IP headers, requests won't be rate-limited. In the future, we plan to introduce more advanced strategies to handle cases where the IP is unavailable - such as falling back to user data or implementing fingerprinting - but these features are still under consideration.I see so to be safe, I would need to add middleware that adds IP headers for non-authenticated users trying to break in?
Yeah. For example lots of people use Cloudflare.
how would I then provide these headers to the rate limiter? e.g. in the forget route, currently our users could easily send thousands of emails and a session is not available, as they are not logged in
which header?
X-Forwarded-For
?Options | Better Auth
Better Auth configuration options reference.
even with that, e.g. the forget route can spammed
Sounds like the best approach would be to add another rate limiter on that path, until the BA rate limiter is improved.
This appears to be quite an enumeration risk vector.
So you would set
ipAddressHeaders: ["x-client-ip", "x-forwarded-for"]
in the advanced settings, and then need to ensure these are set via middleware for non-authenticated interactions with any /auth/api*
path?yes, in any case. this should be adressed
hi @Ping , so this rate limit is work if user already loggedin / have a session?
It's based on ip