Part 1- Everything You Need to Know About Browser Security Policies — SOP, CORS.

5 months ago 59
BOOK THIS SPACE FOR AD
ARTICLE AD

vikram naidu

Hello everyone, I am excited to launch a series dedicated to various security topics aimed at helping security enthusiasts deepen their understanding of application security. Browser security policies form the backbone of web application security, protecting users from a variety of threats including data theft, session hijacking, and malicious scripting. In today’s blog, we will discuss some of the most critical browser security policies such as the Same-Origin Policy (SOP), and Cross-Origin Resource Sharing (CORS). Refer to part 2 at the end of the blog for Content Security Policy (CSP), HSTS, and cookie attributes.

These policies were chosen for their key roles in defining and safeguarding the interactions between browsers and web content. By understanding these policies, developers and security professionals can better implement secure web applications and protect against common vulnerabilities. Throughout this first installment of our “Application Security 101” series, we will explore how each policy works, provide practical examples, and discuss their limitations and implications in real-world scenarios.

Same-Origin Policy (SOP)

Cross-Origin Resource Sharing (CORS)

The Same-Origin Policy (SOP) is a crucial security mechanism that limits how documents or scripts from one origin can interact with resources from another origin. This policy prevents malicious websites from using JavaScript to access data from other websites, thereby protecting user information. In simple terms, Resource sharing is only permitted if the origin is the same.

What is an Origin?

To simplify, think of an origin as a URL. Two URLs are considered to have the same origin if their scheme, host, and port are identical. Let’s illustrate this with an example.

URL: https://example.com:443

Scheme: httpsHost: example.comPort: 443

Now, let’s compare a few URLs with the above URL to determine if they are considered the same origin or not.

Now that you understand what an origin is, let me explain the Same-Origin Policy (SOP) with an example.When a request is made by https://example.com/account-info to https://example.com, the resource is shared because the request is coming from the same origin. However, when a request is made by https://sub.example.com to https://example.com, the resource is not shared because the request is not from the same origin.

Note: If you want your subdomains to share resources with your main domain, you can set the document.domain value to a common superdomain. For example, if you want http://store.example.com to interact with http://example.com, you can set document.domain = "example.com" on both pages. This allows them to be treated as the same origin. However, be aware that this method is deprecated due to security risks and compatibility issues.

Since the Same-Origin Policy (SOP) is strict and enabled by default in browsers, it can be challenging for developers to share resources with legitimate third-party sites. To work around SOP, a concept called Cross-Origin Resource Sharing (CORS) is used.

So, what is this CORS? Cross-Origin Resource Sharing (CORS) is a mechanism that enables resource sharing between different origins, overcoming the restrictions imposed by the Same-Origin Policy (SOP). This is essential for modern web applications that often need to interact with APIs and services from different domains.

How CORS Works

CORS is an HTTP-based mechanism that involves the use of additional headers to manage cross-origin requests: Below are three key headers relevant to CORS (Cross-Origin Resource Sharing). Let’s explore how each header functions and the potential vulnerabilities that can arise from their misconfiguration.

Origin Header: When a browser makes a cross-origin request, it includes an “Origin” header. This header indicates the origin (scheme, host, and port) of the request. Below is the example request.GET /data HTTP/1.1
Host: api.example.com
Origin: https://client.example.com

2. Access-Control-Allow-Origin Header: The server responds with an “Access-Control-Allow-Origin” header, specifying which origins are permitted to access the resource. If the origin in the request matches the allowed origin in the response, the browser allows the resource sharing.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://client.example.com

Example Scenario: In this scenario, https://client.example.com is allowed to access resources from https://api.example.com because the server explicitly permits it.

The Access-Control-Allow-Origin header can contain 3 Parameters:

*: Allows any origin to access the resource. This is useful for public APIs but can be risky if sensitive data is exposed.Specific Origin: Specifies a single origin that is allowed access (e.g., https://client.example.com). This provides more control and security.null: Used for certain use cases like local files or sandboxed iframes.

Key Points to Note:

CORS itself is not a vulnerability. It is a feature designed to enable resource sharing between trusted origins. However, improper configuration of CORS headers can lead to security vulnerabilities. For example, setting Access-Control-Allow-Origin to * (wildcard) allows any origin to access the resource, which can expose sensitive data.If the * is set to A-C-A-O, then any domain ( attacker’s site evil.com) can also access the information from the example.com which is a security concern depending on what kind of data is shared.

3. Access-Control-Allow-Credentials Header: This Header Indicates whether the browser should include credentials (like cookies or HTTP authentication) with requests.

Parameters:

true: Allows credentials to be included in the request. This should be used with specific origins, not *. Allowing credentials with * can lead to security vulnerabilities, exposing user data to any origin.false: Credentials are not included in the request. Safe for public data.

Example of a Vulnerable CORS Configuration: A server improperly allows access from any origin with credentials. Here malicious.com is attacker attacker-controlled site and vulnerable.com is the target.

Request from https://malicious.comGET /private-data HTTP/1.1
Host: vulnerable.com
Origin: https://malicious.com

2. Response from https://vulnerable.com

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Type: application/json

{
"user": "John Doe",
"email": "john.doe@example.com"
"auth-token: "aldfji34939.afdqwetr344.343455afasf"

}

3. Explanation: The server’s CORS configuration (Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true) allows any origin to access sensitive data, including credentials. This can lead to significant security risks.

Illustration of Vulnerable CORS Request and Response

4. Request from https://malicious.com: Imagine a user visits a malicious website, https://malicious.com. This website contains a script that attempts to fetch sensitive data from another website, https://vulnerable.com. Below is the example script which fetches the private data.

<script>
fetch('https://vulnerable.com/private-data', {
method: 'GET',
credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data));
</script>

5. Response from Vulnerable Website: The server at https://vulnerable.com is improperly configured to allow any origin to access its resources and includes credentials in its response. The below sensitive data will be sent to the attacker domain leaking the user, email, and auth-token information.

{
"user": "John Doe",
"email": "john.doe@example.com"
"auth-token: "aldfji34939.afdqwetr344.343455afasf"
}

CORS Vulnerability Scenarios Table

Mitigations:

Restrict Allowed Origins: Use Access-Control-Allow-Origin to specify trusted domains only, avoiding the wildcard * to prevent unauthorized access. Example: Access-Control-Allow-Origin: https://trusteddomain.com.Control Credential Inclusion: Set Access-Control-Allow-Credentials to true only with specific origins, not *, to protect user credentials. Example: Access-Control-Allow-Credentials: true; Access-Control-Allow-Origin: https://trusteddomain.com.Restrict HTTP Methods: Limit HTTP methods using Access-Control-Allow-Methods to reduce attack vectors. Example: Access-Control-Allow-Methods: GET, POST, PUT.Limit Allowed Headers: Use Access-Control-Allow-Headers to restrict the headers that can be used in requests, ensuring only necessary ones are included. Example: Access-Control-Allow-Headers: Content-Type, Authorization.Control Exposed Headers: Specify which headers can be exposed using Access-Control-Expose-Headers to manage what client-side scripts can access. Example: Access-Control-Expose-Headers: Content-Length, X-Kuma-Revision.Set Preflight Cache Duration Appropriately: Use Access-Control-Max-Age to set a reasonable cache duration for preflight requests to balance performance and security. Example: Access-Control-Max-Age: 600.Validate and Sanitize Origin: Dynamically validate the Origin header to ensure it matches allowed origins and avoid using dynamic origin reflection without proper validation.

click here for part 2

Read Entire Article