Decloak is an AI-powered web security intelligence platform that scans a site's HTTP/TLS posture, JavaScript, and third-party scripts to produce a report anyone can read. This guide is part of Decloak's library of practical, source-backed security guidance.
In this guide
- Key takeaways
- What does the Access-Control-Allow-Origin header do?
- Which header values are safe and which are risky?
- How do credentials affect the header?
- Why is the Vary: Origin header important?
- Common pitfalls and how to avoid them
- How to test your ACAO configuration
- When should you avoid using Access-Control-Allow-Origin altogether?
- Summary
Key takeaways
Access-Control-Allow-Origin(ACAO) is the HTTP response header that controls which origins may read a cross - origin response in JavaScript.- Use a specific origin (e.g.
https://example.com) when credentials are needed;*only works for non - credentialed requests. - Always send
Vary: Originwhen you echo back the request’s origin so caches store separate copies. - Misconfiguring ACAO is a common source of broken functionality and security bugs.
What does the Access-Control-Allow-Origin header do?
The ACAO header tells the browser whether the response may be read by client - side JavaScript that originated from a particular scheme, host, and port. If the header is missing or does not match the request’s Origin, the browser blocks the JavaScript and logs a CORS error.
Which header values are safe and which are risky?
*(wild - card) allows any origin only for requests that do not include credentials (cookies, HTTP auth, client certificates). Using*with credentials causes the request to fail.- A single concrete origin like
https://example.comallows exactly that origin. Servers that support many origins must echo back the incomingOriginvalue. nullis meant for sandboxed iframes orfile:URLs, but it is discouraged because any site can forge a null origin, creating a security risk.
How do credentials affect the header?
When JavaScript sends a request with withCredentials:true (or credentials: 'include' in fetch), the server must:
- Return a specific origin in
Access-Control-Allow-Origin(never*). - Include
Access-Control-Allow-Credentials: true. If either condition is missing, the browser rejects the response even though the request may have succeeded at the network level.
Why is the Vary: Origin header important?
When a server echoes back the request’s origin, caches (CDNs, reverse proxies) could otherwise serve the wrong variant to a different origin. Adding Vary: Origin tells caches to store separate versions per origin, preventing accidental data leakage.
Common pitfalls and how to avoid them
| Pitfall | Why it breaks | Fix |
|---|---|---|
Using * with credentialed requests | Browser rejects the response | Return the exact requesting origin and add Access-Control-Allow-Credentials: true |
Missing Vary: Origin when echoing origins | Cached response may be served to the wrong site | Add Vary: Origin to the response headers |
Setting null as the allowed origin | Any site can spoof a null origin | Use a concrete origin or avoid allowing null altogether |
| Forgetting to send ACAO at all | Browser blocks the JavaScript | Ensure every API endpoint that is called from the browser includes ACAO |
How to test your ACAO configuration
- Open the browser’s developer tools, go to the Network tab, and look for the response headers of the request.
- Verify that
Access-Control-Allow-Originmatches theOriginheader sent by the browser. - If you use credentials, also check for
Access-Control-Allow-Credentials: true. - Use a tool like curl to simulate the request and inspect headers:
curl -I -H "Origin: https://myapp.com" https://api.example.com/data
Confirm the Access-Control-Allow-Origin value in the output.
5. Test both credentialed and non - credentialed scenarios to ensure the header behaves as expected.
When should you avoid using Access-Control-Allow-Origin altogether?
If an API is intended for server - to - server communication only, there is no need to enable CORS. Omitting ACAO ensures browsers block any accidental cross - origin calls, reducing the attack surface.
Summary
Access-Control-Allow-Origin is the gatekeeper for cross - origin JavaScript requests. Use concrete origins for credentialed calls, add Vary: Origin for caching safety, and always verify the header with browser tools. Proper configuration prevents common CORS errors and protects against unintended data exposure.
Related guides
How to Fix a Missing Content - Security - Policy Header
Learn concrete steps to add, test, and harden a Content - Security - Policy header, from server configuration to iterative reporting and verification.
Is HTTP 1.1 a security risk?
HTTP 1.1 is not a direct vulnerability, but its plain - text design and parsing ambiguities can create attack surfaces that need mitigation, especially when not used over TLS.
Is JavaScript a security risk?
JavaScript can be a major attack surface because injected scripts run with the same privileges as the page, but proper sanitization, CSP, and safe frameworks eliminate most risks.