Security
Cors Misconfiguration: what to verify before client handoff
Before handoff, verify that public API and app responses do not grant untrusted origins a read on sensitive bodies—and keep CSP and frame protection in the same Security triage.
· by Jonas Reed

Handoff decks show the marketing site. Clients later wire a dashboard to api.client.com and discover Access-Control-Allow-Origin reflecting whatever Origin the browser sent. That discovery happens on a call you wanted to keep short. Lab notes should have caught it.
SlaySlop's CORS misconfiguration check "Checks whether cross-origin resource sharing allows untrusted sites to read responses." Before portal access goes out, that sentence is the Security bar I use for the CORS row.
Outcome you want at handoff
On the public APIs and app origins in scope, CORS grants match the front ends you intentionally allow. Untrusted origins do not get a casual read on responses that matter. You can show evidence: Origin sent, ACAO returned, credentials flag, route. Mechanisms on paper beat "we enabled CORS so the SPA would load."
Boundaries to state on the call
Read-only public scan. Permission required. Not a pentest. SlaySlop does not patch the gateway for you. A clean CORS row is not a full Security sign-off.
Keep siblings visible so nobody treats one green cell as the browser-controls story:
- Content Security Policy: checks whether browser content sources are restricted by a CSP header
- Frame protection: looks for controls that prevent unwanted framing and clickjacking
Those definitions are from the checks catalog. The Acceptable Use Policy still applies: only assets you own or are explicitly authorized to assess.
Happy path checklist before you send the portal
List the public hosts in the SOW: marketing site, app origin, API origin. Scan each with permission. Prefer routes that return user-specific or authenticated-shaped JSON over pure static assets when you spot-check manually.
Loading diagram.
# Permissioned Origin probes against your API
for origin in \
"https://app.example.com" \
"https://untrusted.example"
do
echo "=== Origin: $origin"
curl -sI -H "Origin: $origin" "https://api.example.com/v1/me" \
| awk 'BEGIN{IGNORECASE=1} /^HTTP|^access-control-|^vary:/{print}'
doneThen in the SlaySlop report:
- Open CORS misconfiguration findings and read the evidence.
- Confirm whether reflected Origins or credentialed wildcards appear on in-scope APIs.
- Check CSP and frame protection on the same hosts.
- Write portal notes with host, route, and expected allowlist.
- Schedule a rescan after any gateway change.
SlaySlop crawls the public site in a real browser, ranks verified findings by impact, and includes the evidence that triggered each finding. Put the API host in the notes even if the pretty screenshot was only the marketing homepage.
Pitfalls that embarrass you on the call
"CORS works" meaning the first-party SPA can call the API. That was never the question. The question was untrusted sites reading responses.
Another classic: allowlist updated in staging only. Production API still reflects. Your internal Postman collection used a hard-coded Origin that happens to be allowed. The client's random preview deploy is not on the list—or worse, everything is reflected so nothing fails in demos.
Null Origin tests from local HTML files also create confusing lab results that never match the public host. Prefer the public URL evidence in the portal.
Portal language that survives the call
I avoid "CORS secured." I write "API allowlist includes https://app.example.com only on /v1/*; untrusted Origin probe returned no ACAO; SlaySlop CORS misconfiguration clean on api.example.com as of DATE." Clients can forward that sentence to their security contact without translation.
If something is still open, I say what is open. "Temporary partner Origin https://partner.example expires DATE" is an honest handoff. Hidden temporary grants are how false confidence returns after you leave the project.
How I split marketing vs API hosts
Marketing pages often need little or no CORS. APIs need an explicit story. I keep two mini-checklists in the portal:
Marketing host: CORS usually quiet; still skim Security siblings; do not pretend this covers api..
API host: Origin probes, allowlist text, CORS misconfiguration evidence, auth reminder that CORS is not login.
Mixing those checklists into one "website Security" blur is how glances sneak back in. Clients understand the split when you show two hostnames on the slide instead of one homepage screenshot.
If the client only paid for a marketing-site scan, say that limit in the portal instead of implying the API was reviewed. Scope honesty prevents false confidence better than another screenshot.
What to put in the portal notes
Host, route, intended allowlist, observed ACAO behavior, ticket id for any tighten-up, and the Security siblings you also checked. Soft next step: keep scanning after launch so a "temporary" * does not rot into permanence. Glossary: CORS misconfiguration.