CORS Policy Generator
Build a secure CORS policy and copy ready config for Nginx, Apache, Express, FastAPI, Django and 10 more stacks, with a live security review.
This CORS policy generator writes the Cross-Origin Resource Sharing headers you need and the matching config for whatever you actually run, all in your browser, so your origins never leave the page. Tell it which origins you trust, which methods you allow, whether requests carry cookies, and a Max-Age, then read back the raw headers plus ready snippets for Nginx, Apache, Express, Node, FastAPI, Flask, Django, ASP.NET Core, Spring, Caddy, Traefik, HAProxy, IIS and Cloudflare Workers. Start from a preset for a public read-only API, a credentialed SPA, a token API or a locked-down policy. A live security review flags the dangerous combinations in plain English, the wildcard-with-credentials hole most of all, before you ship.
100% in your browser. Nothing you type ever leaves this page.
CORS policy generator, headers + 14 server and framework configs
CORS has woken me up at 2 a.m. A deploy ships. The console floods red, and not one request reaches the API. So I built this. Tell it which origins you trust, which methods you allow, whether you send cookies, and it hands back the config for whatever you actually run: Nginx, Apache, Express, FastAPI, Flask, Django, ASP.NET Core, Spring, Caddy, Traefik, HAProxy, IIS, Cloudflare Workers, fourteen stacks, plus the raw headers. Start from a preset if you like. Then keep half an eye on the live security review. The wildcard-with-credentials hole has bitten me, and honestly, it will probably bite you too if you let it slip through. Runs entirely in your browser. I never see your origins, nothing leaves the page.
https://app.example.com X-Request-Id, X-RateLimit-Remaining How this CORS generator works
Here is the mental model that finally made CORS click for me. It is a handful of response headers telling the browser which other sites are allowed to read what your server sends back. The browser enforces. Your server just declares the rules and hopes it got them right. So pick a preset, or set your origins and methods by hand, tell it whether requests carry cookies, and out comes the exact headers plus the config for fourteen common stacks. It updates as you type. The security review flags anything sketchy in plain English, before you ship.
The CORS response headers explained
| Header | What it does |
|---|---|
Access-Control-Allow-Origin | The single origin allowed to read the response, or * for any. With credentials it must be an exact origin, never *. |
Access-Control-Allow-Methods | HTTP methods permitted in the actual request, returned on the preflight. |
Access-Control-Allow-Headers | Request headers the client may send (for example Authorization, Content-Type). |
Access-Control-Allow-Credentials | Set to true to allow cookies and the Authorization header. Forces an exact origin. |
Access-Control-Expose-Headers | Response headers JavaScript is allowed to read beyond the default safelist. |
Access-Control-Max-Age | How long (seconds) the browser caches the preflight result. Browsers cap it (Chromium 7200, Firefox 86400). |
Vary: Origin | Required when you reflect the origin, so caches do not serve one origin's response to another. |
The wildcard-with-credentials trap
The one CORS mistake I run into most? Turning credentials on while reflecting any origin. The spec will not let you pair Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true, so people get clever and echo back whatever Origin the browser happened to send. Please do not. That hands every site on the internet the power to make authenticated calls with your user's cookies and read the reply. You have quietly switched cross-origin protection off while leaving the green light on. Need credentials for real? Check the incoming origin against an actual allowlist. You get that here the moment you list specific origins instead of the wildcard.
Preflight requests
Anything that is not a "simple" request makes the browser fire off an OPTIONS preflight first, asking permission. A custom header does it. So does a JSON body, or any method past GET, POST or HEAD. Your server has to answer that preflight with the CORS headers and a 2xx before the real request is allowed through. Forget it and the whole thing fails, usually in silence, which is a fun afternoon. The Nginx, Node, Caddy and HAProxy configs here already bake in the little short-circuit that answers OPTIONS with a 204. One less thing to remember.
Frequently asked questions
Why is my CORS policy not working even though I set the header?
In my experience it is almost always one of a few things. The preflight OPTIONS never gets a 2xx carrying the headers. Or you have paired Access-Control-Allow-Origin: * with credentials, which the browser flat-out refuses. Maybe a proxy or CDN is quietly stripping the headers on the way out, that one is sneaky. Open the raw-headers tab to see what should go out. Then line it up against the real response in your browser network panel. The gap usually jumps out once you actually look.
Can I use a wildcard origin with cookies or Authorization?
No. And you cannot sneak it past the browser either. The second Access-Control-Allow-Credentials turns true, the wildcard gets rejected for the origin (and for Allow-Headers and Expose-Headers, while we are at it). You have to send back the exact origin that asked, checked against an allowlist, plus Vary: Origin. List your specific origins, tick credentials, and the tool wires all of that up for you.
What is a preflight request and when does it happen?
It is the automatic OPTIONS request the browser sends before a non-simple cross-origin call. Basically it asks whether it is allowed to do this. You set it off with any method past GET, POST or HEAD. A Content-Type like application/json triggers it too, or any custom request headers. Your server replies with the Allow-Methods and Allow-Headers and a 2xx. Then the real request runs.
Does CORS protect my server?
No. This one trips up a lot of people. CORS lives in the browser, and it protects your users, not your server. All it controls is whether JavaScript on some other site can read your responses. It is not auth. It is not a firewall. Anyone can still hit your API straight from curl and get everything back. Postman too. Keep your real authorization and your rate limiting on the server, where they actually do something.