CORS Access-Control Header Validator
Inspect, debug, and simulate browser preflight OPTIONS requests and Access-Control-* CORS headers. Detect credential mismatches and generate production server configs.
CORS Request & Response Inspector
1. Simulated Client Request
2. Server Response Headers (Target Configuration)
PREFLIGHT FAILED
W3C Specification & Browser Audit Findings:
Browsers explicitly block requests when 'Access-Control-Allow-Credentials: true' is paired with 'Access-Control-Allow-Origin: *'. The response will be rejected by client browsers immediately.
Action: Reflect the verified request Origin header dynamically or whitelist explicit allowed domain strings instead of using '*'.
Headers [x-requested-with] were sent in the request but omitted from 'Access-Control-Allow-Headers'.
Action: Include 'x-requested-with' in the Access-Control-Allow-Headers server directive.
Browsers will cache the preflight response without re-triggering OPTIONS checks for up to 1440 minutes.
Frontend code can inspect: X-Custom-Header, Content-Length.
>>> CLIENT PREFLIGHT REQUEST: OPTIONS /api/v1/resource HTTP/1.1 Host: api.targetdomain.com Origin: https://app.clientdomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type, Authorization, X-Requested-With User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) <<< SERVER PREFLIGHT RESPONSE (HTTP/1.1 204 No Content): Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 86400 Access-Control-Expose-Headers: X-Custom-Header, Content-Length Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
# NGINX Reverse Proxy / Server Block Configuration
location /api/ {
# Preflight OPTIONS Handler
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Max-Age' 86400 always;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
# Main Request Response Headers
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Expose-Headers' 'X-Custom-Header, Content-Length' always;
proxy_pass http://backend_upstream;
}100% Client-Side In-Memory Execution: Header validation algorithms, W3C specification checks, and server config templates run locally within your web browser. No proprietary API endpoints, intranet URLs, or session credentials are ever transmitted to or logged on remote servers.
Understanding Cross-Origin Resource Sharing (CORS) & Browser Security
Cross-Origin Resource Sharing (CORS) is an HTTP-header based security protocol enforced by client web browsers. Under the foundational Same-Origin Policy (SOP), browsers restrict scripts running on one origin from reading HTTP response data from a different origin unless authorized. To analyze headers currently deployed on a live server, inspect them using our live HTTP headers inspector, or pair your cross-origin rules with a hardened policy created in the Content Security Policy generator to safely permit external API origins.
Simple Requests
GET, HEAD, and standard POST requests with default form content types execute directly. Browsers only inspect the returned Access-Control-Allow-Origin header before passing data to JavaScript.
Preflight (OPTIONS)
Requests with non-simple methods (PUT, DELETE, PATCH) or custom headers (Authorization, application/json) trigger an automatic preliminary HTTP OPTIONS handshake before dispatching the real payload.
Client Enforcement
CORS does not stop unauthorized non-browser clients (such as curl, Postman, or scrapers). It functions exclusively inside the browser runtime to safeguard user sessions and cookies against cross-site exploitation.
Anatomy of Access-Control HTTP Response Headers
| HTTP Header Directive | Syntax Example | Specification Role | Common Failure Mode |
|---|---|---|---|
| Access-Control-Allow-Origin | https://client.com | Specifies authorized requesting domains or wildcard (*) | Using wildcard (*) when credentials are true |
| Access-Control-Allow-Credentials | true | Authorizes browsers to expose response when cookies/auth tokens are present | Omitted when frontend uses withCredentials: true |
| Access-Control-Allow-Methods | GET, POST, PUT, DELETE | Enumerates allowed HTTP verbs during preflight OPTIONS check | Missing PUT or DELETE causing preflight 405 error |
| Access-Control-Allow-Headers | Authorization, Content-Type | Authorizes custom headers submitted in client request | Missing Authorization token header |
| Access-Control-Expose-Headers | X-Total-Count, Content-Range | Allows frontend JavaScript to read custom response headers | Pagination headers hidden from Axios/Fetch client |
| Access-Control-Max-Age | 7200 | Caches the preflight response in browser memory | Values > 7200s silently capped by Chromium engines |
CORS Security Pitfalls: Production Hardening Guidelines
Recommended Architecture Patterns
- • Always Send Vary: Origin: When dynamically echoing the incoming request origin, servers must return
Vary: Originso intermediate CDN caches do not serve origin A's permissions to origin B. - • Strict Origin Whitelisting: Validate incoming origins against an explicit array of authorized domains (e.g., in Node.js or Nginx map blocks) before reflecting headers.
- • Tune Max-Age for Production APIs: Set preflight caching between 1,800 and 7,200 seconds to minimize unnecessary preflight latency without exceeding browser caps.
Critical Security Anti-Patterns
- • Blind Origin Reflection: Never echo arbitrary incoming origins unconditionally alongside credentials. This exposes your API to Cross-Site Request Forgery (CSRF) and credential leakage.
- • Regex Prefix Flaws: Avoid regexes like
origin.match(/^https:\/\/api\.mysite\.com/)because an attacker can registerhttps://api.mysite.com.attacker.orgto bypass validation. - • Null Origin Whitelisting: Never allow
Origin: null. Sandboxed iframes and local file protocols generate null origins that can be weaponized in phishing attacks.
Frequently Asked Questions (FAQ)
Why does Access-Control-Allow-Origin: * fail when credentials are true?
The W3C Fetch specification strictly prohibits wildcard origins (*) when Access-Control-Allow-Credentials is set to true. This security restriction prevents arbitrary third-party websites from reading sensitive authenticated responses (such as cookies, HTTP authentication, or TLS client certificates) in browser sessions. When credentials are included, servers must explicitly reflect the requesting origin in the Access-Control-Allow-Origin response header.
What triggers an HTTP preflight OPTIONS request in modern browsers?
A preflight request is triggered whenever a cross-origin HTTP request uses methods other than GET, HEAD, or POST; sets custom request headers beyond CORS-safelisted ones (such as Authorization or custom X-* headers); or sets a Content-Type other than text/plain, multipart/form-data, or application/x-www-form-urlencoded.
What is the maximum allowed duration for Access-Control-Max-Age?
While the HTTP specification allows arbitrary integer seconds, browser implementations enforce strict internal upper bounds. Chromium-based browsers (Google Chrome, Microsoft Edge, Brave, Opera) cap Access-Control-Max-Age at 7,200 seconds (2 hours). Firefox caps it at 86,400 seconds (24 hours). Setting values higher than 7,200 seconds will be truncated silently by Chromium browsers.
Why is the Vary: Origin response header critical when serving dynamic CORS headers?
When your server reflects the requesting Origin rather than returning a static wildcard (*), intermediate CDNs, reverse proxies, and browser caches may serve the cached CORS response to a different client origin. Adding 'Vary: Origin' ensures that caching layers key responses by the Origin header, avoiding erroneous cross-origin blocks for other authorized origins.
What is the difference between simple CORS requests and preflighted CORS requests?
Simple CORS requests do not trigger an initial HTTP OPTIONS preflight round-trip and proceed directly using standard GET, HEAD, or POST methods without custom headers. Preflighted requests send an automated OPTIONS probe to verify server permissions beforehand whenever non-simple methods (PUT, DELETE, PATCH) or custom headers (Authorization, application/json) are present.
Are CORS headers processed server-side or enforced by client web browsers?
CORS is exclusively a client-side security mechanism enforced by web browsers. Backend APIs and command-line tools like cURL or Postman do not enforce CORS restrictions. Browsers inspect Access-Control-* response headers before exposing response payloads to frontend JavaScript code.
Related & Complementary Utilities
Explore more privacy-first client-side web tools.
DKIM Selector Public Key Record Inspector & Generator
Inspect, generate, and validate RFC 6376 DKIM DNS TXT records with 2048-bit RSA key health diagnostics.
URL Punycode & Internationalized Domain (IDN) Converter
Convert Unicode internationalized domain names (IDNs) and URLs into ASCII Punycode (xn--) and vice-versa in real-time according to RFC 3492 and RFC 5891.
SPF Record Generator & Permissive Syntax Validator
Generate, test, and audit RFC 7208 SPF records. Detect the 10 DNS lookup limit, avoid Permerrors, and prevent unauthorized email spoofing.
WHOIS Domain Age Checker & Expiration Auditor
Query live WHOIS registries to inspect domain creation dates, total active age, registrar information, expiration milestones, and trust metrics.