policies/reputation: reset negative score to 0 on successful login - #25571
policies/reputation: reset negative score to 0 on successful login#25571manantlerio wants to merge 2 commits into
Conversation
✅ Deploy Preview for authentik-integrations ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for authentik-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
A successful login now resets a negative reputation score back to 0 for the matching (identifier, IP) pair, instead of incrementing it by 1. Scores of 0 or above are left untouched, and no entry is created if none exists yet. refs goauthentik#20148 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3b3eeda to
61f2224
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #25571 +/- ##
==========================================
- Coverage 91.69% 91.66% -0.04%
==========================================
Files 1152 1152
Lines 73503 73548 +45
Branches 4054 4054
==========================================
+ Hits 67402 67419 +17
- Misses 6059 6087 +28
Partials 42 42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
gergosimonyi
left a comment
There was a problem hiding this comment.
This doesn't look quite right. The intention is for a successful login to (with a single SQL query)
- reset the reputation to 0 if it was negative
- increase the reputation by 1 if it was non-negative
The second part is removed here.
Addresses review feedback: a successful login now resets a negative score to 0 and raises any other score by 1, both in the same statement via a conditional CASE expression on the existing upsert. A login with no existing entry still creates one at 1, matching the previous behaviour. refs goauthentik#20148 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Good catch - I dropped the increment instead of making it conditional. Fixed in b763202: both branches now in one statement ( |
Details
What does this PR change?
On a successful login, the reputation entry for the matching
(identifier, IP)pair is now updated as follows, instead of being unconditionally incremented by 1:Both branches are a single
CASEexpression inside the existingINSERT ... ON CONFLICT DO UPDATE, so it stays one statement and there is no read-then-write race between concurrent logins.(identifier, IP)pair is touched. Other usernames behind the same IP, and the same username from other IPs, are unaffected.reputation_lower_limit/reputation_upper_limitclamping is unchanged.update_score.No model, migration, API or settings change, so nothing needs configuring on upgrade.
Why is this change needed?
Per the discussion on #20175: unconditionally incrementing means an attacker who shares an IP with a legitimate user earns extra retries per successful login. @gergosimonyi asked whether this should just be the new default rather than another flag, and @dewi-tik confirmed after speaking with @BeryJu that changing the default is preferred over adding a tenant setting.
The behaviour implemented here is the one confirmed in #20148 (comment), corrected per @gergosimonyi's review on this PR to keep the increment for non-negative scores.
How was this tested?
Eight tests in
authentik/policies/reputation/tests.pycovering both branches and the surrounding semantics: negative resets to 0, zero increments to 1, positive increments by 1, no existing entry creates one at 1, the upper limit still bounds the increment, another identifier on the same IP is unaffected, the same identifier on another IP is unaffected, and a failed-then-successful login ends at 0.ruff checkandruff formatare clean. I do not have PostgreSQL/Redis available locally, so I have not run the Django suite myself - the previous revision passedtest-unittestin CI, and I am relying on CI again for this revision.Linked issues
Closes #20148
AI usage disclosure
Per AI_POLICY.md: I used Claude Code to navigate the codebase, draft this change, and draft this description. I reviewed and edited all of it, and I understand and take responsibility for what is submitted here. Happy to answer review questions directly.
Checklist
make all) -ruffclean locally; I cannot run the Django suite on this machine, so I am relying on CImake docs)