kratos icon indicating copy to clipboard operation
kratos copied to clipboard

feat: prevent account enumeration during registration

Open camero2734 opened this issue 3 months ago • 1 comments

BREAKING CHANGES: This patch changes the behavior of configuration item `security.account_enumeration.mitigate` to also prevent account enumeration during the registration flow, as well as throwing an error if a `session` hook is issued after registration.

Related issue(s)

Would partially resolve #133

Checklist

  • [x] I have read the contributing guidelines.
  • [ ] I have referenced an issue containing the design document if my change introduces a new feature.
  • [x] I am following the contributing code guidelines.
  • [x] I have read the security policy.
  • [x] I confirm that this pull request does not address a security vulnerability. If this pull request addresses a security vulnerability, I confirm that I got the approval (please contact [email protected]) from the maintainers to push the changes.
  • [x] I have added tests that prove my fix is effective or that my feature works.
  • [ ] I have added or changed the documentation.

Further Comments

Currently, it is not possible to avoid account enumeration during the registration flow in Ory Kratos. This means users can attempt to register with an email and if they receive the "An account with the same identifier exists already" error message, they now know the account existed.

For some projects (including the one I'm working on), avoiding account enumeration is a product requirement, and so I've gone ahead and added this functionality into Ory Kratos.

Importantly, this is only enabled if security.account_enumeration.mitigate is set, otherwise the behavior is the same as before.

What changed? (if mitigation is enabled)

  • The registration flow no longer returns the duplicate identifier error
    • Instead, it sends a new mailer (RegistrationDuplicate) to the user to inform them that their account already exists, and they can sign in
    • It returns the exact same response as it would if they identifier hadn't already been taken
  • The identity is no longer returned
    • Maybe this is possible to keep? I'm not sure if there's potential inconsistencies here depending on whether the account existed before or not
  • Session hook is no longer allowed after registration (since issuing a session would expose whether the account existed or not)
  • The verification hook will run after a duplicate registration, but won't send an email or generate a valid code. But it is a valid verification flow, so the behavior on the frontend should be the same.
  • Post persist webhooks will not run unless the identity was actually created
    • i.e. the ONLY post-persist hook that always runs is the verification hook, so that the behavior is the same on the client.
  • Allow session hook after verification. To avoid requiring the user that just signed up to sign in again, you can now put a session hook after verification flows. This way the user is still signed in, but only after verification (preventing enumeration).

I know this is a big change, so happy to discuss the changes.

camero2734 avatar Oct 15 '25 12:10 camero2734

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Oct 15 '25 12:10 CLAassistant