-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
stages/email: implement rate limiting for account verification #15531
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
stages/email: implement rate limiting for account verification #15531
Conversation
✅ Deploy Preview for authentik-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for authentik-integrations ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for authentik-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
c17d035
to
00a7295
Compare
cc: @rissson 👋 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #15531 +/- ##
==========================================
- Coverage 92.76% 92.73% -0.03%
==========================================
Files 833 833
Lines 44731 44868 +137
==========================================
+ Hits 41494 41610 +116
- Misses 3237 3258 +21
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
00a7295
to
ba7e7df
Compare
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.
Couple small things, otherwise lgtm
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse: | ||
return super().challenge_invalid(response) | ||
|
||
def _get_cache_key(self) -> str: |
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.
nit but this might be something to implement as a Throttle in DRF https://www.django-rest-framework.org/api-guide/throttling/#userratethrottle
(this code is fine, thats just a design idea)
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.
💡 That's an interesting idea. We could create a custom throttling class that uses DRF's throttling mechanism (we don't want to return a 429
status code, need to check stage specific settings, etc). This sounds like a viable option➕
ba7e7df
to
525e61c
Compare
Thanks for your feedback @BeryJu 🙏 I've implemented your suggestions and it's ready for another review. |
525e61c
to
fbd027e
Compare
Thanks for your review @melizeche 🙏 I've addressed your feedback and it's ready for another review when you get a chance. |
…on for Account Recovery Settings
…lated translations
…nerate migrations
…che_timeout to EmailStageSerializer
…reference to Email Stage specific values
…and cache timeout
…ing validator. Re-generate migrations.
fbd027e
to
92f94c2
Compare
* main: (32 commits) core: bump goauthentik.io/api/v3 from 3.2025064.6 to 3.2025064.7 (#16024) core, web: update translations (#16021) ci: move images from beryju/* to authentik/* (#15321) core, web: update translations (#15985) core: bump cattrs from 24.1.3 to v25.1.1 (#15981) web: bump API Client version (#16002) ci: bump actions/download-artifact from 4 to 5 (#15995) core: bump certifi from 2025.7.14 to v2025.8.3 (#15982) core: bump anyio from 4.9.0 to v4.10.0 (#15979) core: bump boto3 from 1.40.1 to v1.40.2 (#15980) core: bump astral-sh/uv from 0.8.4 to 0.8.5 (#15998) core: bump goauthentik.io/api/v3 from 3.2025064.5 to 3.2025064.6 (#15997) stages/email: implement rate limiting for account verification (#15531) web: Fix stale application slug, missing error state. (#15941) website/docs: change azure ad to entra id (#15691) website/docs: add tips for image optimization (#15978) web: bump API Client version (#15976) providers/oauth2: backchannel logout (#15401) web: bump API Client version (#15953) translate: Updates for file web/xliff/en.xlf in fr (#15974) ...
* main: (32 commits) core: bump goauthentik.io/api/v3 from 3.2025064.6 to 3.2025064.7 (#16024) core, web: update translations (#16021) ci: move images from beryju/* to authentik/* (#15321) core, web: update translations (#15985) core: bump cattrs from 24.1.3 to v25.1.1 (#15981) web: bump API Client version (#16002) ci: bump actions/download-artifact from 4 to 5 (#15995) core: bump certifi from 2025.7.14 to v2025.8.3 (#15982) core: bump anyio from 4.9.0 to v4.10.0 (#15979) core: bump boto3 from 1.40.1 to v1.40.2 (#15980) core: bump astral-sh/uv from 0.8.4 to 0.8.5 (#15998) core: bump goauthentik.io/api/v3 from 3.2025064.5 to 3.2025064.6 (#15997) stages/email: implement rate limiting for account verification (#15531) web: Fix stale application slug, missing error state. (#15941) website/docs: change azure ad to entra id (#15691) website/docs: add tips for image optimization (#15978) web: bump API Client version (#15976) providers/oauth2: backchannel logout (#15401) web: bump API Client version (#15953) translate: Updates for file web/xliff/en.xlf in fr (#15974) ...
Details
This PR implements a very basic version of rate limiting for account verification emails.
Closes #11149
Context
Currently, it is possible to send an infinite number of account recovery emails. To reproduce this:
Once you send the initial email, you will have the option to "Send email again":
You can currently click this button an unlimited number of times.
Rate Limiting
To prevent the user from being spammed, this PR introduces a rate limiting feature. To configure it, edit an existing Email Stage, where you'll notice two new fields, "Account Recovery Max Attempts" and "Account Recovery Cache Timeout":
Now if you spam the same button, eventually you'll see an error:
The error is
Too many account verification attempts. Please try again after 10 minutes.
. The error keeps track of the actual cache expiry time: if you click the button after a minute, you'll notice the message will ask you to try after 9 minutes.Checklist
ak test authentik/
)make lint-fix
)If an API change has been made
make gen-build
)If changes to the frontend have been made
make web
)If applicable
make website
)