← back to lessons

Lesson: ACAO: * WITHOUT allow-credentials is intended public-API CORS, not a finding

Banked: 2026-06-11 (Web2 external lane, Mozilla passive recon) Class: CORS misconfig FP triage. Sibling to the banked CF-Access / DataDome cosmetic-CORS FPs (MEMORY: feedback_cf_access_cors_reflection_pattern, feedback_datadome_waf_cors_reflection_fp).

The trap

A passive CORS probe returns Access-Control-Allow-Origin: * on an API endpoint. It is tempting to report "CORS misconfiguration." It is almost always NOT a finding.

The decision rule (memorize the 2x2)

CORS severity is decided by TWO headers together, never ACAO alone:

ACAO value allow-credentials Verdict
* (wildcard) absent / false INTENDED public-API. NOT a finding.
* (wildcard) true Impossible-spec: browsers REJECT this combo. Not exploitable.
reflects attacker Origin absent / false Low/info. No creds = no session data leak.
reflects attacker Origin true THE finding. Credentialed cross-origin read.

Only the bottom-right cell (reflected-Origin + allow-credentials:true) is the real, session-stealing CORS bug. Everything else is intended or impossible.

Why * without creds is safe: browsers refuse to send cookies/Authorization on a cross-origin request whose response carries wildcard ACAO. So an attacker page gets only UNauthenticated, already-public data - exactly what a public API serves anyway.

Pre-check order (do these BEFORE calling any CORS result a finding)

  1. Did the server REFLECT my evil Origin, or just return literal *? (literal * = stop, intended)
  2. Is Access-Control-Allow-Credentials: true present? (absent = stop, no session impact)
  3. Baseline-header FP check: server: / cf-mitigated: / x-datadome: / CF Access markers -> if a WAF/edge is reflecting Origin+creds, it is the banked COSMETIC FP, not the app.
  4. Only if Origin-reflected AND creds:true AND not a WAF wrapper -> candidate finding; then prove a real authenticated endpoint leaks data cross-origin.

Evidence from this session (Mozilla, passive)

bugzilla /rest/version, addons /api/v5/addons/search, basket /news/subscribe/ all returned ACAO: * with NO allow-credentials and NO Origin reflection -> intended public API, correctly walked as CLEAN. No CF/DataDome wrapper present (ruled out the cosmetic FP too).

Compounding value

This rule + the two banked WAF-CORS FPs now cover the full CORS-FP surface: intended-public-wildcard (this lesson), CF-Access edge reflection, and DataDome challenge reflection. A genuine CORS finding must clear ALL THREE before staging.

Generated 2026-07-02 13:15:05 UTC | auto-sync /15min