From 291b35c3dbafa299e8b67d7b7fdcd7eb8f11e2a0 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Tue, 13 Jan 2026 18:05:47 +0100 Subject: [PATCH] stages/authenticator_validate: decrease reputation on failed MFA attempt (#19378) Signed-off-by: Jens Langhammer --- authentik/stages/authenticator_validate/stage.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/authentik/stages/authenticator_validate/stage.py b/authentik/stages/authenticator_validate/stage.py index 598204ad21..8fb4ad2a38 100644 --- a/authentik/stages/authenticator_validate/stage.py +++ b/authentik/stages/authenticator_validate/stage.py @@ -21,6 +21,7 @@ from authentik.flows.models import FlowDesignation, NotConfiguredAction, Stage from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.stage import ChallengeStageView from authentik.lib.utils.time import timedelta_from_string +from authentik.policies.reputation.signals import update_score from authentik.stages.authenticator import devices_for_user from authentik.stages.authenticator.models import Device from authentik.stages.authenticator_email.models import EmailDevice @@ -418,6 +419,10 @@ class AuthenticatorValidateStageView(ChallengeStageView): ) return response + def challenge_invalid(self, response: AuthenticatorValidationChallengeResponse) -> HttpResponse: + update_score(self.request, self.get_pending_user().username, -1) + return super().challenge_invalid(response) + def challenge_valid(self, response: AuthenticatorValidationChallengeResponse) -> HttpResponse: # All validation is done by the serializer user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)