-
Notifications
You must be signed in to change notification settings - Fork 3
Change OTP generation to 4-digit random number #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,7 @@ const router = express.Router(); | |
| */ | ||
|
|
||
| router.post('/otp', (req, res) => { | ||
| const otp = Math.floor(100 + Math.random() * 900); // Generate 3-digit random number | ||
| const otp = Math.floor(100 + Math.random() * 9000); // Generate 4-digit random number | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :large_orange_circle: MEDIUM Issue: The new range does not produce a 4-digit OTP, and the OTP space is small enough to brute-force given there is no rate limiting. Location: Risk: Fix: Use a 6-digit OTP from a CSPRNG (see the Reference: CWE-307 (Improper Restriction of Excessive Authentication Attempts), CWE-330, OWASP API4:2023 Unrestricted Resource Consumption |
||
| return res.json({ otp }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 CRITICAL (pre-existing on this line; this PR keeps it in place) Issue: The generated OTP is returned directly in the HTTP response body, on an unauthenticated endpoint, and is never stored or bound to a user. Location: Risk: Three defects compound here:
Returning the OTP is also what makes the Fix: Persist the OTP server-side as a hash keyed to the authenticated user/session with a short TTL (e.g. 5 min), single-use, with an attempt counter; deliver it out-of-band (SMS/email) and return only Reference: CWE-200 (Exposure of Sensitive Information), CWE-306 (Missing Authentication for Critical Function), CWE-613 (Insufficient Session Expiration), OWASP API2:2023 Broken Authentication |
||
| }); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:large_yellow_circle: HIGH
Issue: OTP is generated with
Math.random(), a non-cryptographic PRNG.Location:
badApi/otp.js:42Risk:
Math.random()in V8 isxorshift128+, seeded once per context and not cryptographically secure. Because this endpoint hands the raw OTP back to the caller (see separate comment), an attacker can request a handful of OTPs, recover the 128-bit internal state by solving for it, and then predict every subsequent OTP the process will emit — including OTPs generated for other users. Widening the range from 3 to 4 digits does not change this: the output is deterministic once the state is known, so the effective entropy is 0 bits after state recovery, regardless of digit count.Fix: Use a CSPRNG.
crypto.randomInt()is available in Node's stdlib and is unbiased:(add
const crypto = require('crypto');alongside the other requires at the top of the file).Reference: CWE-338 (Use of Cryptographically Weak PRNG), CWE-330 (Use of Insufficiently Random Values), OWASP ASVS V2.8.3 / V6.3.1