Unrestricted Access to Sensitive Business Flows
The security patch is active. CAPTCHA is invalidated after use and rate limiting is enforced. Go back to the Proxy page and try the replay attack again — it will be blocked.
// 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.