Security Tip: Don't Forget to Regenerate 2FA Secret Keys!

[Tip #84] It's not just passwords you need to worry about when it comes to authentication and stolen credentials: your 2FA secret keys may also be at risk!

Security Tip: Don't Forget to Regenerate 2FA Secret Keys!

A common mistake when implementing Time-based One-Time Password (TOTP) Two-Factor Authentication (2FA) is to generate the user's secret key once, and then reuse the same secret key even when TOTP is disabled and enabled, providing the user with no mechanism to reset their key.

This opens up a similar risk to password reuse: if an attacker can obtain the user's secret key, and the user has no way to reset it, then the attacker just needs the user's password to successfully log in! (As they will always have a valid TOTP!) 😱

But, why is this an issue, and how can an attacker obtain the user's secret key?

While it is unlikely, it's not unheard of for 2FA secret keys to be leaked in some way - such as with the Spoutible data breach, but also consider if the user's device is compromised: an attacker could access the user's authenticator app and steal their secret keys - the user would need to reset their passwords and TOTP keys ASAP!

The solution is simple: wipe the secret key when TOTP is disabled, and generate a fresh key when TOTP is enabled.

This will ensure a fresh key any time TOTP is toggled, and provide a logical reset method if the user needs to reset their key.

Laravel Fortify (the backend for Jetstream) does this with it's EnableTwoFactorAuthentication and DisableTwoFactorAuthentication actions.

P.s. I'd also suggest encrypting your 2FA secret key in the database, for added security in case of a data breach!

🤓
2FA - Two-Factor Authentication
MFA - Multi-Factor Authentication
2SV - Two-Step Verification

These are all similar terms with subtle differences that relate to authenticating users with multiple authentication factors: something you know (passwords), something you have (physical device), something you are (biometrics).

TOTP - Time-based One-Time Password

A cryptographically secure method of generating a unique code every 30 seconds, to provide something you have, in the form of a physical device - i.e. your phone.

If you found this security tip useful? 👍
Subscribe now to get weekly Security Tips straight to your inbox, filled with practical, actionable advice to help you build safer apps.

Want to learn more? 🤓
Upgrade to a Premium Subscription for exclusive monthly In Depth articles, or support my work with a one-off tip! Your support directly funds my security work in the Laravel community. 🥰

Need a second set of eyes on your code?
Book in a
Laravel Security Audit and Penetration Test today! I also offer budget-friendly Security Reviews too.

Finally, connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.