Add ambiguous error messages option to Accounts config #8520
User account enumeration is a security concern for some people. In our bug bounty program @LegalRobot, we've had 17 different reports on user enumeration. It got annoying, so we started using this code in local forks of accounts-core and accounts-password but are now happy to share this with the community. This PR addresses some of the simpler attack vectors: different error messages returned from the server upon various login failures or pw reset failures.
By default, we leave the existing behavior alone but provide a simple mechanism to enable this by setting the
Enabling this option sends the same, rather ambiguous, error message to the client upon various login and reset failures. The specific text isn't really important, just that it can be identical across different failures. Perhaps as an extension of this, we could allow people to configure the message?
As @glasser and @lorensr discussed a few years ago in #2139, user enumeration is still possible via inference upon registration failure - the only way to prevent this is allowing duplicate accounts for the same email, but that opens up a whole mess of UX issues; and that can still be mitigated through rate limiting on those methods. So, this PR does not tackle the whole user enumeration problem, but at least we’re not being as explicit about every failure.
Unfortunately, we're not really able to write tests for this change since it seems that server-side testing is not isolated (PR anyone?). We can either run the tests with this new option disabled (which is more common and the default) or enabled, but not both.
Looping in @guide for documentation changes, and @DaTa since we're messing with some pretty important stuff in Meteor accounts.
Add boolean option 'ambiguousErrorMessages' to Accounts config that sends ambiguous error messages to the client in order to mitigate user enumeration. User enumeration still possible via inference upon registration failure, but at least we’re not being as explicit about the failures.
hwillson left a comment
Hi @dhrubins - thanks for taking the time to submit this PR! At a quick glance, I think these changes make sense, but I'll let others comment as well to confirm. Normally we recommend first creating an issue to track feature requests like this, to promote discussion and help hash out of the best design approach (see Proposing your change in the Contributing guide). That being said, I've done a quick review of your code, and have a few suggestions, but I'm sure others will chime in with more comments. Thanks!
This file leaves a lot to be desired, but strong preference to not remove existing curly-braces on if-statements. Also removed trailing whitespaces and slight indentation changes following the changes in #8520.
I appreciate the work put into making this feature a reality in Meteor 1.5. However, I think it may be worth noting that it does not really prevent username enumeration.
When an non-existent email address is entered in the "forgot password" form, a websocket error still indicates that the password reset failed with the error:
To be completely sure that username enumeration cannot happen, the error must not be returned to the client.
@runlevelsix Thanks for bringing this up. You're right that the fix applied here does not truly avoid user enumeration (and that's stated in the OPs post). Though, I think it's worth pointing out that even Google and Facebook tell you immediately if an account exists via "Forgot Password" or not. There's a user experience issue to blocking it entirely, though it would be nice if it were fully configurable though. Would you be willing to expand upon this PR?