Documentation
How to use this tool, practical use cases, and technical notes.
The CORS Policy Tester is organized into two panels: the Simulated Request (what the browser would send) and the Server CORS Policy (what your server is configured to allow). The live evaluation panel updates in real time as you change any setting.
Step 1 — Configure the Simulated Request
The left panel represents the cross-origin HTTP request being made from a browser. Configure:
Request Origin
Enter the origin from which the request is being made — the scheme, hostname, and port of the page making the request. Examples:
Scenario | Request Origin to Enter |
|---|---|
Production frontend app |
|
Admin dashboard |
|
Local development (HTTPS) |
|
Local development (HTTP) |
|
Sandboxed iframe or file:// |
|
Attacker site (for testing) |
|
HTTP Method
Select the HTTP method the request will use: GET, POST, PUT, PATCH, DELETE, or HEAD.
Method | Preflight Required? | Notes |
|---|---|---|
GET | ❌ No (if no custom headers) | Simple request |
POST with simple Content-Type | ❌ No | Only |
POST with | ✅ Yes | Non-simple Content-Type triggers preflight |
PUT | ✅ Yes | Always non-simple |
PATCH | ✅ Yes | Always non-simple |
DELETE | ✅ Yes | Always non-simple |
HEAD | ❌ No | Simple method |
Request Headers
Toggle the headers your request will include. Any header beyond the CORS-safe list triggers a preflight:
Header | Triggers Preflight? | Common Use |
|---|---|---|
| ✅ Yes | REST API JSON bodies |
| ✅ Yes | Bearer tokens, Basic auth |
| ✅ Yes | AJAX identification |
| ❌ No | CORS-safe header |
| ✅ Yes | CSRF protection tokens |
| ✅ Yes | API key authentication |
Step 2 — Configure the Server CORS Policy
The right panel represents your server's CORS response headers. This is the policy you are designing or testing.
Allowed Origins
Add the exact origins your server will permit. The tool supports four origin modes:
Mode | Configuration | When to Use |
|---|---|---|
Explicit list |
| Production APIs with known frontends (recommended) |
Wildcard ( | Select | Public read-only APIs with no authentication |
Localhost variants |
| Local development environments |
Null | Select | Sandboxed iframe testing only; never production |
Allowed Methods
Toggle which HTTP methods your server permits for cross-origin requests. As a rule:
List only the methods your API actually uses
Always include
OPTIONSif you handle preflight manually (most frameworks handle this automatically)Avoid listing
DELETEorPUTon public APIs unless required
Allowed Headers
Toggle which request headers the server will accept from cross-origin requests. Only headers listed here will be permitted in preflight and actual requests.
Preflight Cache (Max-Age)
Set how long browsers will cache the preflight response, avoiding repeated OPTIONS calls:
Max-Age Value | Seconds | Browser Behavior |
|---|---|---|
Not set | 0 | Preflight sent on every request |
1 hour | 3,600 | Cached for 1 hour per browser tab |
24 hours | 86,400 | Cached for 1 day — good production default |
7 days | 604,800 | Maximum practical cache; use only for stable APIs |
Note: Chrome caps preflight caching at 2 hours (7,200 seconds) regardless of the Max-Age value. Firefox respects longer values up to 86,400 seconds.
Expose Headers
Headers listed here are made available to JavaScript via response.headers.get(). Without being listed here, response headers are hidden from frontend code even if the request succeeds:
Header | Why Expose It |
|---|---|
| Frontend logging and distributed tracing |
| Pagination — total record count for list endpoints |
| File download — filename from server |
| Pagination links (GitHub API pattern) |
Allow Credentials
Toggle whether the server sends Access-Control-Allow-Credentials: true. This controls whether the browser includes cookies, HTTP authentication, or TLS client certificates in the request.
⚠️ Critical constraint: When credentials are enabled, Access-Control-Allow-Origin must be a specific origin, not *. This is enforced by all modern browsers. The tool flags this as an invalid configuration if you attempt to combine both.
Step 3 — Read the Live Evaluation
The evaluation panel shows the outcome of your configuration in real time:
Result | Meaning |
|---|---|
✅ Request allowed | The cross-origin request would succeed |
✅ Preflight would succeed | The OPTIONS preflight passes, and the actual request would be allowed |
⚠️ Preflight required | A preflight OPTIONS call will be sent before the actual request |
❌ Request blocked | The browser would block this request based on the current policy |
❌ Invalid configuration | The policy contains a combination that browsers will reject (e.g., |
The panel also shows the exact values that would appear in each CORS response header, so you can verify the output before deploying.
Step 4 — Use the Pre-Built Scenarios
The "Try a scenario" section at the bottom of the tool loads common CORS configurations with a single click:
Scenario | What It Demonstrates |
|---|---|
Allowed API call | A correctly configured policy that permits a specific authenticated origin |
Blocked origin | A request from an untrusted origin that the policy correctly blocks |
Public wildcard | A wildcard |
Invalid: * + credentials | The dangerous combination of wildcard origin with credentials enabled |
Use the "Invalid: * + credentials" scenario to understand exactly why this combination is rejected by browsers and why some backends that return both headers are still vulnerable.
Step 5 — Copy the Server Configuration Snippet
Once your policy is correctly configured and the evaluation shows your desired result, navigate to the "Web server configuration" tabs and copy the generated snippet for your server platform:
Platform | What Gets Generated |
|---|---|
HTTP headers | Raw header values only (for any platform) |
Nginx |
|
Apache |
|
Caddy | Caddyfile |
Express.js | Node.js middleware using the |
Cloudflare Worker | JavaScript Worker script handling CORS at the edge |
Click "Copy snippet" and paste directly into your configuration file. The generated code includes inline comments explaining each directive.
Step 6 — Reset and Test New Scenarios
Click "Reset" to return to the default configuration and start a new test. This is useful when testing multiple API endpoints with different CORS requirements, or when walking through attack scenarios to understand the impact of misconfigurations.
The CORS Policy Tester is organized into two panels: the Simulated Request (what the browser would send) and the Server CORS Policy (what your server is configured to allow). The live evaluation panel updates in real time as you change any setting.
Step 1 — Configure the Simulated Request
The left panel represents the cross-origin HTTP request being made from a browser. Configure:
Request Origin
Enter the origin from which the request is being made — the scheme, hostname, and port of the page making the request. Examples:
Scenario | Request Origin to Enter |
|---|---|
Production frontend app |
|
Admin dashboard |
|
Local development (HTTPS) |
|
Local development (HTTP) |
|
Sandboxed iframe or file:// |
|
Attacker site (for testing) |
|
HTTP Method
Select the HTTP method the request will use: GET, POST, PUT, PATCH, DELETE, or HEAD.
Method | Preflight Required? | Notes |
|---|---|---|
GET | ❌ No (if no custom headers) | Simple request |
POST with simple Content-Type | ❌ No | Only |
POST with | ✅ Yes | Non-simple Content-Type triggers preflight |
PUT | ✅ Yes | Always non-simple |
PATCH | ✅ Yes | Always non-simple |
DELETE | ✅ Yes | Always non-simple |
HEAD | ❌ No | Simple method |
Request Headers
Toggle the headers your request will include. Any header beyond the CORS-safe list triggers a preflight:
Header | Triggers Preflight? | Common Use |
|---|---|---|
| ✅ Yes | REST API JSON bodies |
| ✅ Yes | Bearer tokens, Basic auth |
| ✅ Yes | AJAX identification |
| ❌ No | CORS-safe header |
| ✅ Yes | CSRF protection tokens |
| ✅ Yes | API key authentication |
Step 2 — Configure the Server CORS Policy
The right panel represents your server's CORS response headers. This is the policy you are designing or testing.
Allowed Origins
Add the exact origins your server will permit. The tool supports four origin modes:
Mode | Configuration | When to Use |
|---|---|---|
Explicit list |
| Production APIs with known frontends (recommended) |
Wildcard ( | Select | Public read-only APIs with no authentication |
Localhost variants |
| Local development environments |
Null | Select | Sandboxed iframe testing only; never production |
Allowed Methods
Toggle which HTTP methods your server permits for cross-origin requests. As a rule:
List only the methods your API actually uses
Always include
OPTIONSif you handle preflight manually (most frameworks handle this automatically)Avoid listing
DELETEorPUTon public APIs unless required
Allowed Headers
Toggle which request headers the server will accept from cross-origin requests. Only headers listed here will be permitted in preflight and actual requests.
Preflight Cache (Max-Age)
Set how long browsers will cache the preflight response, avoiding repeated OPTIONS calls:
Max-Age Value | Seconds | Browser Behavior |
|---|---|---|
Not set | 0 | Preflight sent on every request |
1 hour | 3,600 | Cached for 1 hour per browser tab |
24 hours | 86,400 | Cached for 1 day — good production default |
7 days | 604,800 | Maximum practical cache; use only for stable APIs |
Note: Chrome caps preflight caching at 2 hours (7,200 seconds) regardless of the Max-Age value. Firefox respects longer values up to 86,400 seconds.
Expose Headers
Headers listed here are made available to JavaScript via response.headers.get(). Without being listed here, response headers are hidden from frontend code even if the request succeeds:
Header | Why Expose It |
|---|---|
| Frontend logging and distributed tracing |
| Pagination — total record count for list endpoints |
| File download — filename from server |
| Pagination links (GitHub API pattern) |
Allow Credentials
Toggle whether the server sends Access-Control-Allow-Credentials: true. This controls whether the browser includes cookies, HTTP authentication, or TLS client certificates in the request.
⚠️ Critical constraint: When credentials are enabled, Access-Control-Allow-Origin must be a specific origin, not *. This is enforced by all modern browsers. The tool flags this as an invalid configuration if you attempt to combine both.
Step 3 — Read the Live Evaluation
The evaluation panel shows the outcome of your configuration in real time:
Result | Meaning |
|---|---|
✅ Request allowed | The cross-origin request would succeed |
✅ Preflight would succeed | The OPTIONS preflight passes, and the actual request would be allowed |
⚠️ Preflight required | A preflight OPTIONS call will be sent before the actual request |
❌ Request blocked | The browser would block this request based on the current policy |
❌ Invalid configuration | The policy contains a combination that browsers will reject (e.g., |
The panel also shows the exact values that would appear in each CORS response header, so you can verify the output before deploying.
Step 4 — Use the Pre-Built Scenarios
The "Try a scenario" section at the bottom of the tool loads common CORS configurations with a single click:
Scenario | What It Demonstrates |
|---|---|
Allowed API call | A correctly configured policy that permits a specific authenticated origin |
Blocked origin | A request from an untrusted origin that the policy correctly blocks |
Public wildcard | A wildcard |
Invalid: * + credentials | The dangerous combination of wildcard origin with credentials enabled |
Use the "Invalid: * + credentials" scenario to understand exactly why this combination is rejected by browsers and why some backends that return both headers are still vulnerable.
Step 5 — Copy the Server Configuration Snippet
Once your policy is correctly configured and the evaluation shows your desired result, navigate to the "Web server configuration" tabs and copy the generated snippet for your server platform:
Platform | What Gets Generated |
|---|---|
HTTP headers | Raw header values only (for any platform) |
Nginx |
|
Apache |
|
Caddy | Caddyfile |
Express.js | Node.js middleware using the |
Cloudflare Worker | JavaScript Worker script handling CORS at the edge |
Click "Copy snippet" and paste directly into your configuration file. The generated code includes inline comments explaining each directive.
Step 6 — Reset and Test New Scenarios
Click "Reset" to return to the default configuration and start a new test. This is useful when testing multiple API endpoints with different CORS requirements, or when walking through attack scenarios to understand the impact of misconfigurations.