Discovered during PR #149 review (CodeRabbit, Major).
The /api/checkout/report-failure alert bridge is necessarily reachable by the browser beacon, so it is unauthenticated. Because wcpos.store.sale bypasses the Discord rate limit, a malicious client could POST {"kind":"order_pending"} repeatedly to flood Discord/Sentry.
Done in #149 (cheap mitigations):
- Sanitize the attacker-controlled
reference before logging (strip to WCPOS charset + cap length) — prevents Discord/log injection.
- Reject oversized request bodies (
content-length > 2KB).
Deferred to this issue (needs design):
- Authenticity: mint a short-lived signed token server-side on the checkout page and verify it on the beacon (a browser beacon can't hold a static server secret, so HMAC-with-shared-secret isn't viable client-side).
- Server-side throttle + per-reference dedupe on the sale-critical bypass path so a flood can't drown real alerts.
Low-moderate severity: logs/alerts only, no data exposure and no money path. Pairs with the Phase 4 (Medusa-side webhooks) work.
Discovered during PR #149 review (CodeRabbit, Major).
The
/api/checkout/report-failurealert bridge is necessarily reachable by the browser beacon, so it is unauthenticated. Becausewcpos.store.salebypasses the Discord rate limit, a malicious client could POST{"kind":"order_pending"}repeatedly to flood Discord/Sentry.Done in #149 (cheap mitigations):
referencebefore logging (strip to WCPOS charset + cap length) — prevents Discord/log injection.content-length > 2KB).Deferred to this issue (needs design):
Low-moderate severity: logs/alerts only, no data exposure and no money path. Pairs with the Phase 4 (Medusa-side webhooks) work.