CWE Glossary
- CWE-22: Path Traversal
- CWE-78: OS Command Injection
- CWE-79: Cross-Site Scripting
- CWE-89: SQL Injection
- CWE-90: LDAP Injection
- CWE-91: XML Injection
- CWE-94: Code Injection
- CWE-98: PHP File Inclusion
- CWE-113: HTTP Response Splitting
- CWE-119: Buffer Errors
- CWE-130: Improper Handling of Length Parameter Inconsistency
- CWE-193: Off-by-one Error
- CWE-200: Information Exposure
- CWE-211: Information Exposure Through Externally-Generated Error Message
- CWE-236: Improper Handling of Undefined Parameters
- CWE-276: Incorrect Default Permissions
- CWE-284: Improper Access Control
- CWE-285: Improper Authorization
- CWE-287: Improper Authentication
- CWE-297: Improper Validation of Certificate with Host Mismatch
- CWE-306: Missing Authentication for Critical Function
- CWE-312: Cleartext Storage of Sensitive Information
- CWE-345: Insufficient Verification of Data Authenticity
- CWE-352: Cross-Site Request Forgery
- CWE-384: Session Fixation
- CWE-427: Uncontrolled Search Path Element
- CWE-434: Unrestricted Upload of File with Dangerous Type
- CWE-476: NULL Pointer Dereference
- CWE-521: Weak Password Requirements
- CWE-601: Open Redirect
- CWE-611: Improper Restriction of XML External Entity Reference ('XXE')
- CWE-613: Insufficient Session Expiration
- CWE-618: Exposed Unsafe ActiveX Method
- CWE-671: Lack of Administrator Control over Security
- CWE-798: Use of Hard-coded Credentials
- CWE-799: Improper Control of Interaction Frequency
- CWE-822: Untrusted Pointer Dereference
- CWE-835: Infinite Loop
- CWE-918: Server-Side Request Forgery (SSRF)
- CWE-942: Overly Permissive Cross-domain Whitelist
CWE is a trademark of the MITRE Corporation.
Overly Permissive Cross-domain Whitelist [CWE-942]
Overly Permissive Cross-domain Whitelist weakness describes a case where software uses cross-domain policy, which includes domains that should not be trusted.
Created: June 11, 2018
Latest Update: December 28, 2020
Table of Content
- Description
- Potential impact
- Attack patterns
- Affected software
- Severity and CVSS Scoring
- Mitigations
- Vulnerability Remediation Techniques and Examples
- Common Fix Errors and Bypasses
- References
Want to have an in-depth understanding of all modern aspects of Overly Permissive Cross-domain Whitelist [CWE-942]? Read carefully this article and bookmark it to get back later, we regularly update this page.
1. Description
A cross-domain policy is defined via HTTP headers sent to the client's browser.
There are two headers that are important to cross-origin resource sharing process:
Access-Control-Allow-Origin – defines domain names that are allowed to communicate with the application.
Access-Control-Allow-Credentials – defines if the response from the request is allowed to be exposed on the page.
The vulnerability occurs when the "Access-Control-Allow-Origin" header lists a domain that is under attacker's control (e.g. the application accepts any domain from HTTP request and mirrors it back to the browser or just responds with an asterisk) and if "Access-Control-Allow-Origin" is set to "true". The attacker is able then to inject arbitrary content from the domain name under his/her control and display that content in victim's browser.
The vulnerability occurs when the "Access-Control-Allow-Origin" header lists a domain that is under an attacker's control (e.g. the application accepts any domain from the HTTP request via user input and mirrors it back to the browser) and if "Access-Control-Allow-Credentials" is set to "true".
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json; charset=utf
Access-Control-Allow-Origin: https://htbridge.com
Access-Control-Allow-Credentials: true
The attacker is then able to issue a cross-domain request (via tricking a victim user of the vulnerable website into opening a crafted web page that contains the relevant cross-domain exploit) and return the contents of the exposed endpoint, this could contain potentially sensitive content corresponding to the victim.
If the domain responds with "Access-Control-Allow-Origin: *", and with credentials permitted, it is important to note that the web browser implements a security mechanism that checks the combination of these two and will prevent credentials from being transmitted. However, later in the article will be example of why this still can be dangerous under the right circumstances.
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
If the domain responds with "Access-Control-Allow Origin: null" with credentials allowed, then it is possible to cause the same impact as with an arbitrary domain generated from user input, with credentials allowed.
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
If the domain responds with Access-Control-Allow-Origin: *, but without credentials, then under certain circumstances the victims browser may be leveraged to bypass IP based restrictions, allowing an attacker to proxy to internal resources.
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
2. Potential impact
The vulnerability may allow an attacker to inject arbitrary JavaScript code from a remote server and execute it in victim's browser.
3. Attack patterns
The following attack patterns are related to this weakness:
- CAPEC-63: Cross-Site Scripting (XSS)
- CAPEC-588: DOM-Based XSS
4. Affected software
Software that relies on cross-domain browser policy is affected by this vulnerability.
5. Severity and CVSS Scoring
This vulnerability allows the same impact as cross-site scripting and therefore should be scored as such:
4.7 [CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N] - Medium
5. Mitigations
The only possible mitigation technique is to replace HTTP header values on the server side to prevent exploitation of this vulnerability.
6. Vulnerability Remediation Techniques and Examples
When developing an application, never rely on user-supplied input when setting values for HTTP headers. Always use predefined value for "Access-Control-Allow-Origin" that does not contain "*" character and cannot be influenced by the incoming HTTP request. Also, where possible set "Access-Control-Allow-Credentials" to "false" by default.
Below are examples of a whitelist approach for controlling allowed domains, with credentials. Please note that there are numerous possible ways to implement a whitelist approach, depending on the needs of the domain publishing the policy.
Apache HTTP Server
via /etc/apache2/sites-enabled :
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO
SetEnvIf Origin "http(s)?://(www\.)?(domain1.com|domain2.com|domain3.com)$"AccessControlAllowOrigin=$0$1
Header set Access-Control-Allow-Credentials true
</IfModule>
PHP
$whitelist = array( '(http(s)://)?(www\.)?my\-domain\.com');
if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] != '') {
foreach ($whitelist as $allowed_origin) {
if (preg_match('#' . $allowed_origin . '#', $_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: 'true');
break;
}
}
}
Microsoft IIS
Via the web applications "web.config" file:
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="*" />
<add origin=https://*htbridge.com
allowCredentials="true"
maxAge="120">
….
C#
internal static class Example {
private static void Main() {
using(ServerManager serverManager = new ServerManager()) {
Configuration config = serverManager.GetWebConfiguration("ExampleSite");
ConfigurationSection corsSection=config.GetSection("system.webServer/cors");
corsSection["enabled"] = true;
corsSection["failUnlistedOrigins"] = true; ConfigurationElementCollection corsCollection = corsSection.GetCollection();
ConfigurationElement addElement = corsCollection.CreateElement("add");
addElement["origin"] = @"*";
corsCollection.Add(addElement);
ConfigurationElement addElement1 = corsCollection.CreateElement("add");
addElement1["origin"] = @"https://*.htbridge.com";
addElement1["allowCredentials"] = true;
addElement1["maxAge"] = 120;
….
….
NodeJS
Via the "cors" npm module:
var express = require('express')
var cors = require('cors')
var app = express()
var whitelist = ['http://domain1.com', 'http://domain2.com']
var corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
7. Common Fix Errors and Bypasses
Numerous bypasses exist for poorly implemented CORS configurations that may still be present from development. A subset of basic examples is listed below:
Partial Domain Name Validation
e.g. htbridge.com
Access-Control-Allow-Origin: htbridge.com
The above example allows all requests to share its contents with any domain that ends with htbridge.com. An attacker can register a domain such as attackerhtbridge.com and carry out the same attack technique as above.
The same problems exists if the policy permits any origin starting with a pre-defined value, such as https://htbridge.com, an attacker can register a domain such as https://htbridge.com.domain.com and proceed with exploitation.
The above example also opens the possibility of exploitation via cross-site scripting. If a domain is whitelisted, e.g *.htbridge.com, then any XSS vulnerability on any subdomain can be leveraged to make cross-origin requests to the domain publishing the policy.
Intentionally whitelisting all subdomains
An average sized company may have numerous subdomains, trusting all of these in a whitelist implies that all of them are free of any XSS vulnerabilities. As above, any XSS vulnerability on any subdomain can be leveraged to make cross-origin requests to the domain publishing the policy.
Allowing all Origins "*", but without credentials.
Some may assume that permitting interaction from all domains on public content but not allowing credentialed requests is safe, this is often the case, but if the user's browser is used in IP address authentication in order to access internal resources, then this could open a security hole, allowing attackers to pivot to restricted resources.
Permitting HTTP
If the domain publishing the policy allows the use of domains to use "HTTP" for interaction, while the domain used HTTPS, an attacker may use classic MITM techniques to intercept the resulting HTTP traffic.
8. References
- CWE-942: Overly Permissive Cross-domain Whitelist [cwe.mitre.org]
- Cross-Origin Resource Sharing (CORS) [developer.mozilla.org]
- Access-Control-Allow-Credentials [developer.mozilla.org]
Copyright Disclaimer: Any above-mentioned content can be copied and used for non-commercial purposes only if proper credit to ImmuniWeb is given.
↑ Back to Top