Testing multi-factor authentication (MFA)
There's not really anything in the WSTG about how to test multi-factor authentication (MFA). Off the top of my head, some of the key areas to look at would be:
- Is it actually MFA (i.e, not security questions)?
- Is MFA enforced?
- Is it enforced on all login methods (web interface vs API, etc)
- Can it be bypassed?
- Do you need to re-authenticate to disable MFA?
- Is the process for resetting MFA strong?
- Are there backup codes, and are they strong?
- OTP issues:
- Do OTP attempts trigger account lockout?
- How long are OTPs valid for?
- Is the keyspace large enough?
- Is there rate limiting on sending OTPs via SMS/email/phone?
- Certificates
- Are digital certificates certificates actually validated, or just issuer/CN?
- Are expired certificates allowed?
- Are only some CAs limited?
- IP filtering (arguable if this is really MFA..)
- Are headers like
X-Forwarded-Fortrusted? - Are public IP ranges (such as AWS/Azure) trusted?
- Are headers like
- Other things I've missed (please add)
Some of these fit into other areas (such as MFA lockout in the existing account lockout section), but others don't really have an obvious home. Should we try and merge this into existing docs, or make it a new document under the authentication section?
Thoughts/comments?
I think this is a good idea. I think adding it as a new auth page would be a good move.
Fully agreed! I've had the knowbe4 blogs in a new tab thinking about this for a while, thanks for bringing it up! I will give it some time and give notes on the presented initial outline, but it's fantastic with the one you have.
Some of those might definitely be tackled in other sections, but that can be tackled as we go through it I'd say.
I don't have much to comment on this. It's art. @rbsec do you wanna take this on? Any help we can provide other than reviewing when it's ready? :)
@ThunderSon I'm happy to, but it'll probably be a little while before I find time for it. But at least leaving it in my issues should stop me forgotten about it...
I have brainstormed a list of MFA attack vectors. I need to clean it up, and I'll share it here, hopefully tomorrow.
- Brute force of MFA codes
- Credential stuffing combined with minimal MFA guessing attempts
- MFA guessing for a single account
- From a single IP
- From multiple IPs
- From a single user-agent
- From multiple user-agents
- Any other metadata mixup configuration
- MFA lockout triggering account reset or “workarounds” that might disable MFA implicitly to allow the user access
- One time code sent to email/SMS (does this override the need for username + password?)
- Abuse of non-MFA-protected endpoints or activity:
- Special endpoints used for certain activities
- Password reset functionality that allows the reset of the password without the usage of MFA, giving access to an attacker by stealing the password reset token
- Weak business logic
- MFA code (or MFA session) is not linked to the account being logged in, allowing a generated code to be used with another user’s session
- Session gets generated without the need for a MFA code, and gets created by simply accessing an “authenticated” page and skipping the MFA page (premature session generation)
- Exceptions and middle-layer bypasses
- Exceptions are created to allow specific people, IPs, or machines to bypass MFA
- Metadata, headers, or any other “special variables” could trigger middle-layers to take over a request over an MFA rule, allowing a different logic to happen, and potentially bypassing the proper MFA logic (e.g. XFF headers)
- Social engineering
- SIM swapping attacks for SMS based MFA
@ThunderSon that list looks good, and there's quite a bit of overlap with what I'd been thinking about - although attacks against SMS are probably a bit outside of the scope of the WSTG.
I'll merge this with what I have and put together as skeleton at some point.
I've pushed an initial draft of this in #971 - any comments and feedback on the content are welcome (I've not done a proper QA, so spelling/grammar/etc can wait).
This has been merged in #971.