forked from kevadesu/forgejo
Rate limit pre-activation email change separately
Changing the email address before any email address is activated should be subject to a different rate limit than the normal activation email resending. If there's only one rate limit for both, then if a newly signed up quickly discovers they gave a wrong email address, they'd have to wait three minutes to change it. With the two separate limits, they don't - but they'll have to wait three minutes before they can change the email address again. The downside of this setup is that a malicious actor can alternate between resending and changing the email address (to something like `user+$idx@domain`, delivered to the same inbox) to effectively halving the rate limit. I do not think there's a better solution, and this feels like such a small attack surface that I'd deem it acceptable. The way the code works after this change is that `ActivatePost` will now check the `MailChangeLimit_user` key rather than `MailResendLimit_user`, and if we're within the limit, it will set `MailChangedJustNow_user`. The `Activate` method - which sends the activation email, whether it is a normal resend, or one following an email change - will check `MailChangedJustNow_user`, and if it is set, it will check the rate limit against `MailChangedLimit_user`, otherwise against `MailResendLimit_user`, and then will delete the `MailChangedJustNow_user` key from the cache. Fixes #2040. Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
This commit is contained in:
parent
43ded8ee30
commit
e35d2af2e5
2 changed files with 28 additions and 3 deletions
|
@ -124,6 +124,15 @@ func TestSignupEmailChangeForInactiveUser(t *testing.T) {
|
|||
// Verify that the email was updated
|
||||
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "exampleUserX"})
|
||||
assert.Equal(t, "fine-email@example.com", user.Email)
|
||||
|
||||
// Try to change the email again
|
||||
req = NewRequestWithValues(t, "POST", "/user/activate", map[string]string{
|
||||
"email": "wrong-again@example.com",
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
// Verify that the email was NOT updated
|
||||
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "exampleUserX"})
|
||||
assert.Equal(t, "fine-email@example.com", user.Email)
|
||||
}
|
||||
|
||||
func TestSignupEmailChangeForActiveUser(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue