Auditing CORS Configuration with AI Before It Leaks Your API
A wildcard origin with credentials is an open door. Here's how I use AI to audit CORS policies for reflected origins, credential leaks, and over-broad allowlists.
- #security
- #hardening
- #cors
- #api
- #ai
CORS is one of those settings every developer touches in a hurry and almost nobody revisits. A frontend can’t reach the API, somebody adds a header to make the error go away, the feature ships, and the temporary fix becomes permanent. I have lost count of the production configs I’ve found that reflect any origin back and set Access-Control-Allow-Credentials: true at the same time, which is the browser-security equivalent of leaving the keys in the door because the lock was annoying.
CORS reviews are tedious and pattern-heavy, which makes them ideal for AI assistance. I use the model as a fast junior engineer that reads the config, explains what each directive actually permits, and flags the dangerous combinations. I verify every finding against the real code and the spec before changing anything, and I keep it strictly defensive. No live credentials or tokens go into the prompt.
Understand what CORS actually protects
Half of CORS mistakes come from misunderstanding what it does. CORS does not protect your server; it instructs the browser about which cross-origin pages may read responses. It is a relaxation mechanism layered on the same-origin policy. So a too-permissive CORS policy doesn’t open a hole in your server’s firewall, it tells victims’ browsers to hand attacker-controlled pages the responses to authenticated requests.
I keep that framing in front of the AI so its analysis stays grounded:
Treat this CORS config as instructions to the browser about which origins may read authenticated responses. For each rule, tell me which origins gain read access and whether credentials are included. Defensive review only.
Hunt the wildcard-plus-credentials combination first
The single most dangerous CORS mistake is allowing credentials with a permissive origin. The spec forbids Access-Control-Allow-Origin: * together with Access-Control-Allow-Credentials: true, so frameworks work around it by reflecting the request’s Origin header back. That reflection is effectively a wildcard that also carries cookies, which is far worse than a literal *.
I have the AI scan for reflection patterns in code:
Find any place where the response
Access-Control-Allow-Originis set from the incoming request’s Origin header without validating it against an allowlist. Flag every one where credentials are also allowed.
Then I confirm with a quick probe against a staging endpoint, never production secrets:
curl -s -I -H "Origin: https://evil.example" https://staging.api.internal/me \
| grep -i 'access-control-allow-'
If the response echoes https://evil.example and includes Allow-Credentials: true, that’s the finding. The AI tells me where in the code it happens; the curl proves it.
Pro Tip: an origin allowlist that uses a loose prefix or substring match is its own bug. startsWith("https://app.example.com") happily matches https://app.example.com.evil.net. Ask the AI to flag any origin check that isn’t an exact, full-string equality match.
Check the methods and headers you actually expose
CORS isn’t just about origins. Access-Control-Allow-Methods and Access-Control-Allow-Headers define what a cross-origin page can invoke. I’ve seen configs that reflexively allow every method and * headers because copying from a tutorial was easier than enumerating what the frontend needs.
I ask the model to reconcile the allowed methods against the routes that actually exist:
Compare the CORS allowed methods and headers against the API routes I’m pasting (sanitized). Flag any method or header allowed cross-origin that no legitimate route needs.
Least privilege applies here exactly like it does to firewall rules: allow what the frontend genuinely uses, deny the rest.
Don’t forget the preflight cache and null origin
Two subtler items the AI is good at catching. First, Access-Control-Max-Age set absurdly high caches a permissive preflight in browsers for hours, so a bad policy lingers even after you fix the server. Second, allowing the literal Origin: null value is dangerous, because sandboxed iframes, data: URLs, and some redirects produce a null origin, and attackers can engineer one. I have the model explicitly check whether null is in any allowlist and whether the preflight cache is set to something sane.
Make it a gate on the gateway, not a per-service guess
In a microservice estate, CORS often lives in two places at once: a shared API gateway and individual services that also set their own headers. When both set CORS headers, browsers see duplicates or conflicts, and the effective policy is whatever survives last. I ask the AI to map where CORS is configured across the gateway config and the service code, and to tell me where the two disagree. Centralizing CORS at the gateway, with services trusting it, is usually the cleaner defensive posture, and the model is good at laying out that consolidation as a reviewable diff.
I route the resulting change through the code review dashboard so the before-and-after is inline and a human approves it rather than the AI applying anything directly.
Verify, then ship
The pattern that holds up: the AI reads the config and explains the effective permissions, I prove the dangerous cases with a harmless curl against staging, and a human approves the tightened policy. The model never gets a real session cookie or token, and it never applies a change on its own.
I keep the CORS and API-hardening prompts in our prompts library, with the security set bundled in the DevOps security prompt pack. For the review itself I’ve used both Claude and ChatGPT to good effect, since this is mostly read-and-explain work over config text.
The takeaway
CORS misconfigurations are quiet, common, and genuinely dangerous when credentials are in play. An AI reviewer turns a tedious header-by-header audit into a fast, repeatable pass, as long as you treat it as the junior engineer that flags and explains while you verify each finding and own the change. Keep it defensive, keep real credentials out of the prompt, and prove the scary cases with a curl before you trust the verdict. The rest of the security hardening category covers the headers, gateways, and auth flows this sits next to.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.