Unrestricted Access to Sensitive Business Flows
The application is currently vulnerable. CAPTCHA is not invalidated after use and there is no rate limiting. Click the button to deploy the security patch.
// POST /api/Feedbacks/
async function submitFeedback(req, res) {
const { captchaId, captcha, comment, rating } = req.body;
// Validate CAPTCHA answer
const captchaRecord = await getCaptcha(captchaId);
if (captchaRecord.answer !== captcha) {
return res.status(400).json({ error: "Invalid CAPTCHA" });
}
// ⚠️ VULNERABILITY: CAPTCHA is validated but NEVER invalidated
// The same captchaId + answer can be replayed indefinitely
// No rate limiting applied
const feedback = await createFeedback({ comment, rating });
return res.status(201).json({ success: true, id: feedback.id });
}// POST /api/Feedbacks/async function submitFeedback(req, res) { const { captchaId, captcha, comment, rating } = req.body; // Validate CAPTCHA answer const captchaRecord = await getCaptcha(captchaId); if (captchaRecord.answer !== captcha) { return res.status(400).json({ error: "Invalid CAPTCHA" }); }+ // ✅ FIX 1: Single-use CAPTCHA enforcement+ if (captchaRecord.used) {+ return res.status(403).json({+ error: "CAPTCHA already used. Request a new one."+ });+ }+ await markCaptchaAsUsed(captchaId);+ // ✅ FIX 2: Rate limiting (max 3 requests per minute)+ if (!checkRateLimit(req.sessionId)) {+ return res.status(429).json({+ error: "Rate limit exceeded. Try again later."+ });+ } const feedback = await createFeedback({ comment, rating }); return res.status(201).json({ success: true, id: feedback.id });}Each CAPTCHA is marked as "used" after first validation. Replay attempts get HTTP 403.
Max 3 submissions per minute. Exceeding returns HTTP 429 Too Many Requests.
For high-value banking flows, require OTP or biometric verification before processing.