Same Origin Policy (SOP)
Policy that instructs how web browsers interact between web pages.
The image below shows what a URL looks like with all its features (it does not use all features in every request).
SOP Decision Process
CORS
Cross-Origin Resource Sharing (CORS) is a mechanism defined by HTTP headers that allows servers to specify how resources can be requested from different origins.
While the Same-Origin Policy (SOP) restricts web pages by default to making requests to the same domain, CORS enables servers to declare exceptions to this policy, allowing web pages to request resources from other domains under controlled conditions.
It's important to note that the server does not block or allow a request based on CORS; instead, it processes the request and includes CORS headers in the response. The browser then interprets these headers and enforces the CORS policy by granting or denying the web page's JavaScript access to the response based on the specified rules.
Different HTTP Headers Involved in CORS
- Access-Control-Allow-Origin: This header specifies which domains are allowed to access the resources. For example,
Access-Control-Allow-Origin: example.com
allows only requests fromexample.com
. - Access-Control-Allow-Methods: Specifies the HTTP methods (GET, POST, etc.) that can be used during the request.
- Access-Control-Allow-Headers: Indicates which HTTP headers can be used during the actual request.
- Access-Control-Max-Age: Defines how long the results of a preflight request can be cached.
- Access-Control-Allow-Credentials: This header instructs the browser whether to expose the response to the frontend JavaScript code when credentials like cookies, HTTP authentication, or client-side SSL certificates are sent with the request. If Access-Control-Allow-Credentials is set to true, it allows the browser to access the response from the server when credentials are included in the request. It's important to note that when this header is used, Access-Control-Allow-Origin cannot be set to
*
and must specify an explicit domain to maintain security.
Requests: Simple VS Preflight
Simple:
- uses the GET, HEAD, or POST method, and the POST request's
Content-Type
header is one ofapplication/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
. - the request should not include custom headers that aren't CORS-safe listed
- cookies and HTTP authentication data are included in simple requests if the site has previously set such credentials, even without the
Access-Control-Allow-Credentials
header being true.
Preflight:
- OPTIONS request
- using HTTP methods other than GET, HEAD, or POST, or when POST requests are made with another Content-Type other than the allowed values for simple requests, or when custom headers are included
- OPTIONS request includes headers like
Access-Control-Request-Method
andAccess-Control-Request-Headers
, indicating custom headers - server response must include headers:
Access-Control-Allow-Methods
,Access-Control-Allow-Headers
, andAccess-Control-Allow-Origin
to indicate request permitted - If the preflight succeeds, the browser will send the actual request with credentials included if
Access-Control-Allow-Credentials
is set to true.
Process of a CORS Request
Edit 🖊️
- The browser first sends an HTTP request to the server.
- The server then checks the Origin header against its list of allowed origins.
- If the origin is allowed, the server responds with the appropriate
Access-Control-Allow-Origin
header. - The browser will block the cross-origin request if the origin is not allowed.
Access-Control-Allow-Origin Header
If the origin is permitted, the server includes the Access-Control-Allow-Origin
header in the response, specifying either the allowed origin or a wildcard (*), which means any origin is allowed
ACAO Configurations
- Single Origin:
- Configuration:
Access-Control-Allow-Origin: https://example.com
- Implication: Only requests originating from
https://example.com
are allowed. This is a secure configuration, as it restricts access to a known, trusted origin.
- Configuration:
- Multiple Origins:
- Configuration: Dynamically set based on a list of allowed origins.
- Implication: Allows requests from a specific set of origins. While this is more flexible than a single origin, it requires careful management to ensure that only trusted origins are included.
- Wildcard Origin:
- Configuration:
Access-Control-Allow-Origin: *
- Implication: Permits requests from any origin. This is the least secure configuration and should be used cautiously. It's appropriate for publicly accessible resources that don't contain sensitive information.
- Configuration:
- With Credentials:
- Configuration:
Access-Control-Allow-Origin
set to a specific origin (wildcards not allowed), along withAccess-Control-Allow-Credentials: true
- Implication: Allows sending of credentials, such as cookies and HTTP authentication data, to be included in cross-origin requests. However, it's important to note that browsers will send cookies and authentication data without the Access-Control-Allow-Credentials header for simple requests like some GET and POST requests. For preflight requests that use methods other than GET/POST or custom headers, the Access-Control-Allow-Credentials header must be true for the browser to send credentials.
- Configuration:
ACAO Flow
Common CORS Misconfigurations
-
Null Origin Misconfiguration: This occurs when a server accepts requests from the "null" origin. This can happen in scenarios where the origin of the request is not a standard browser environment, like from a file (
file://
) or a data URL. An attacker could craft a phishing email with a link to a malicious HTML file. When the victim opens the file, it can send requests to the vulnerable server, which incorrectly accepts these as coming from a 'null' origin. Servers should be configured to explicitly validate and not trust the 'null' origin unless necessary and understood. -
Bad Regex in Origin Checking: Improperly configured regular expressions in origin checking can lead to accepting requests from unintended origins. For example, a regex like
/example.com$/
would mistakenly allowbadexample.com
. An attacker could register a domain that matches the flawed regex and create a malicious site to send requests to the target server. Another example of lousy regex could be related to subdomains. For example, if domains starting withexample.com
is allowed, an attacker could useexample.com.attacker123.com
. The application should ensure that regex patterns used for validating origins are thoroughly tested and specific enough to exclude unintended matches. -
Trusting Arbitrary Supplied Origin: Some servers are configured to echo back the
Origin
header value in theAccess-Control-Allow-Origin
response header, effectively allowing any origin. An attacker can craft a custom HTTP request with a controlled origin. Since the server echoes this origin, the attacker's site can bypass the SOP restrictions. Instead of echoing back origins, maintain an allowlist of allowed origins and validate against it.