Skip to content

Security

How SlaySlop checks Cors Misconfiguration

SlaySlop's CORS misconfiguration check looks at whether cross-origin sharing on the public surface allows untrusted sites to read responses, then attaches evidence to the affected resource.

· by Maya Okonkwo

How SlaySlop checks Cors Misconfiguration

What an attacker sees on the public surface includes HTTP response headers that grant cross-origin reads. Fancy architecture diagrams do not travel with those headers. The browser only sees what the live endpoint returns when an Origin is present.

SlaySlop publishes one sentence for CORS misconfiguration: it "Checks whether cross-origin resource sharing allows untrusted sites to read responses." I treat that as a public-surface observation with evidence, not as a promise that every internal service was fuzzed.

Outcome the check is for

You get a Security finding when observed responses appear to allow untrusted sites to read them via CORS. The outcome is a route- or resource-linked finding, ranked by impact among other verified findings—not a certificate that your SPA "works in Chrome."

In the catalog this check lives under Security, beside Content Security Policy, Frame protection, TLS, and related public-surface controls. The Security and secrets product describes the wider pass as headers, TLS, known vulnerabilities, client-bundle secrets, and public threat signals. Keep CORS in the headers/browser-controls bucket when you triage.

Boundaries

Read-only. Public surface. Permission required. SlaySlop does not edit code, content, settings, or data on the target. Scanning a site you do not own, manage, or have permission to test violates Acceptable Use. This is hygiene on a public attack surface, not a pentest, not an exploit walkthrough, and not permission to hammer someone else's API.

The check is also not a claim about every CDN edge, every microservice, or every preflight combination under the sun. Product language is whether CORS allows untrusted sites to read responses. I read that as dangerous sharing grants on observed public responses—especially patterns that reflect arbitrary Origins or mix wildcard sharing with credentials—rather than as "any missing ACAO header anywhere."

Loading diagram.

Happy path: how the signal is observed

Published scanner workflow, adapted to this check:

  1. Open or request the public URL in the crawl context (real browser crawl for the site map; header inspection on relevant responses).
  2. Observe cross-origin resource sharing behavior on public responses the scan can see.
  3. Flag patterns that indicate untrusted sites may read responses.
  4. Attach findings with the evidence that triggered them.
  5. Rank by impact so a sensitive API grant does not hide under a static asset curiosity.

When I reproduce locally on a host I am allowed to test, I mirror the same idea with an explicit Origin:

bash
API="https://api.example.com/v1/profile"
curl -sI \
  -H "Origin: https://untrusted.example" \
  -H "Access-Control-Request-Method: GET" \
  "$API" | awk 'BEGIN{IGNORECASE=1} /^HTTP|^access-control-|^vary:/{print}'
http
HTTP/2 200
access-control-allow-origin: https://untrusted.example
access-control-allow-credentials: true

That pair is the concrete shape I care about. A tight allowlist that only echoes your real front-end origins is a different shape. Absence of CORS headers on a public blog HTML document is often unremarkable. Read the finding's evidence before you rewrite your entire gateway.

Pitfalls when reading the row

"Works from my front end" is not the same as "safe from an untrusted origin." Your front end is trusted by design. The check asks about untrusted sites.

Console CORS errors on a broken staging URL also mislead. A browser blocking your own mistaken Origin does not prove the API refuses everyone else's. Look at the response headers, not only at the red text in DevTools.

Do not collapse CORS into CSP. CSP "Checks whether browser content sources are restricted by a CSP header." Frame protection "Looks for controls that prevent unwanted framing and clickjacking." Three different browser controls. One Security category.

What I write in the triage note

I copy the ACAO value, the credentials flag if present, and the resource URL into the ticket. Then I ask one question: is this resource supposed to be readable by a browser script on another site? If the answer is no, the allowlist shrinks. If the answer is yes for a public non-credentialed feed, I document that intent so the next reviewer does not "fix" a deliberate grant.

That note also prevents mixing CORS work with unrelated Security rows. Exposed admin panels and open redirects are different findings with different owners. Keep the queues separate even when they arrive in one report.

Related next step

Triage CORS misconfiguration with the rest of the Security pass on the same host. Soft next read: CORS misconfiguration and Security and secrets.