-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rate limiting to two factor attempts. #510
Conversation
…the two-factor prompt.
…mpts, capping at 1 hour.
On the topic of atomic operations... Due to the implementation of this using meta keys, it would be possible for an attacker to throw 100 requests at the 2FA page at once, and potentially only count as one failed login attempt, this is because there's no way (without using a custom DB query) to atomically ensure that the user_meta (or transient, etc) is not being updated from another PHP thread. This is deemed acceptable, as PHP worker exhaustion would likely occur first, causing the majority of the requests to be processed after the initial database row set, which would cause them to hit the maximum tries block. (Let's assume the first 10 requests would run in parallel, with the further 90 being queued waiting for those initial to process) Using atomic operations, such as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally still prefer the reset approach, or a hybrid. I don't have any big objection to this as a stand-alone, either, though.
Left some minor feedback inline, but nothing blocking.
Co-authored-by: Ian Dunn <[email protected]>
…ain why it's limiting the user. Co-authored-by: Ian Dunn <[email protected]>
This is intended as an alternative to #482 for #477, as a way of limiting exposure to brute force attacks while at the same time preserving the account password and ability for the end-user to login.
This is a draft, and is intended on offering what I feel is a potentially better UX than forced password reset, which may simply further aggravate a legitimate user who has simply used the wrong tokens.
This is implemented through two user_meta keys that store:
Combined with a minimum time delay between 2FA attempts (Set at 5s) and incremental back-off of that delay (ie. 2nd failed attempt is 10s delay, 3rd failure is 20s delay, etc, a maximum of 1hr delay is included) prevents access to the account, but, allows the account owner to still login if they're simply using the wrong 2FA key or other similar issues.
While I set the delay at 5s, this could be as low as 1s, resulting in a time delay of 1s, 2s, 4s, 8s, 16s, 32s, 64s, etc.. While this would allow more initial guesses, it's also enough to prevent brute-force attacks being worthwhile. 5 seconds felt like a small enough yet high enough number to start with here.
The maximum time is set to 1hr, but could also be reduced to something smaller such as 15 minutes without drastically impacting upon security. As even at 15 minutes, 4 guesses per hour is unlikely to succeed.
Filters are included that another plugin could alter the rate limit, use atomic cache operations (such as
wp_cache_incr()
), or use a service that includes per-IP or request-matching to limit two factor attempts.login-backoff.mp4