🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Untitled Lesson

Total XP: 0|💻 backend XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Storing a user's TOTP secret in plaintext in the database

// Wrong: plaintext secret, fully exposed if the database leaks await db.users.update(userId, { mfaSecret: secret }); // Correct: encrypted at rest const encryptedSecret = encrypt(secret, ENCRYPTION_KEY); await db.users.update(userId, { mfaSecret: encryptedSecret });

The Solution //

The TOTP secret is functionally equivalent to a permanent second password — if the database is ever compromised or leaked, an attacker with the plaintext secret can generate valid MFA codes indefinitely, completely defeating the purpose of the second factor. Encrypt the secret at rest, with the encryption key managed and stored separately.

The Error //

Having no rate limiting on the MFA code verification endpoint

// Wrong: unlimited verification attempts, brute-forceable app.post("/auth/mfa/verify", verifyMfaHandler); // Correct: strict rate limiting closes the brute-force gap app.post("/auth/mfa/verify", rateLimit({ windowMs: 900000, max: 5 }), verifyMfaHandler);

The Solution //

A 6-digit TOTP code has only 1,000,000 possible values — without rate limiting on verification attempts, an attacker who already has a valid stolen password could feasibly brute-force the correct MFA code through repeated attempts, defeating MFA's protective purpose entirely.

Continue Learning