Same-Origin Policy is the browser’s default isolation rule for cross-origin interaction. Cross-Origin Resource Sharing is the HTTP-header mechanism that selectively relaxes that rule. Most real-world CORS bugs are not about “the server blocks the request,” but about the browser exposing sensitive responses to hostile origins because the server declared the wrong cross-origin policy. These notes cover how SOP and CORS fit together, the key headers, simple vs preflight requests, and the common misconfigurations that lead to exploitable data exposure.
SOP decides whether one origin may read data from another origin in the browser. An origin is defined by:
All three must match for two pages to be same-origin.
https://test.com:80 can interact with https://test.com:80/about.https://test.com:80 is cross-origin to https://test.com:8080 because the port differs.http://test.com is cross-origin to https://test.com because the protocol differs.The common mistake is assuming “same domain” means “same origin.” It does not.
CORS lets the server tell the browser which foreign origins may read a response. The important detail is that the server usually still processes the request either way. The browser is the component that decides whether frontend JavaScript may see the response.
So when reviewing CORS, the core question is not “was the request sent?” but “did the browser expose the sensitive response to untrusted JavaScript?”
Access-Control-Allow-Origin: which origin may read the response.Access-Control-Allow-Methods: which HTTP methods are allowed.Access-Control-Allow-Headers: which request headers are allowed.Access-Control-Max-Age: how long preflight results may be cached.Access-Control-Allow-Credentials: whether the browser may expose the response when credentials are included.Important: if Access-Control-Allow-Credentials: true is used, the origin must be explicit. It cannot safely be paired with a wildcard origin for browser exposure.
Requests using GET, HEAD, or a limited subset of POST behavior are sent directly with the Origin header. The browser then checks the response headers to decide whether JavaScript may access it.
When the request uses methods, headers, or content types outside the simple-request rules, the browser first sends an OPTIONS request to ask whether the actual request is allowed.
This means some vulnerabilities are only visible when you understand whether the target interaction is simple or preflighted.
One of the highest-risk CORS cases is when the victim’s browser sends cookies or other credentials and the browser is also told to expose the response to a hostile origin.
That combination turns the victim’s authenticated browser into a cross-origin data exfiltration channel.
https://example.com.*: only appropriate for public resources with no sensitive data and no credentialed access.A common bug is reflecting whatever Origin header the client supplies straight back into Access-Control-Allow-Origin.
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']."");
header('Access-Control-Allow-Credentials: true');
}
If the application does this while exposing sensitive data, an attacker can host JavaScript on their own origin and have the victim’s browser read authenticated responses from the target site.
Another common mistake is weak regex-based origin validation.
if (isset($_SERVER['HTTP_ORIGIN']) && preg_match('#corssop.thm#', $_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']."");
header('Access-Control-Allow-Credentials: true');
}
This accepts origins that merely contain the trusted string, such as corssop.thm.evilcors.thm. That is not an allowlist. It is just a substring test pretending to be one.
Some applications explicitly trust the null origin:
header('Access-Control-Allow-Origin: null');
header('Access-Control-Allow-Credentials: true');
The null origin can appear in contexts such as local files, sandboxed iframes, or data URL contexts. If the application treats it as trusted, an attacker may be able to craft a browser context that reads authenticated responses unexpectedly.
CORS issues become even worse when chained with XSS. If the attacker already has script execution in the vulnerable origin, they can often make authenticated requests directly. But even without same-origin script execution, a weak CORS policy may expose protected responses to hostile origins.
That is why CORS review and XSS review complement each other.
null origin acceptance,Origin headers and inspect the server’s ACAO behavior.null where relevant.null unless there is a very specific and justified need.