Weakness reference
CWE-942

Permissive Cross-domain Policy with Untrusted Domains

This weakness occurs when a web application's cross-origin resource sharing CORS policy or similar cross-domain mechanism is configured too broadly, allowing…

01Summary

This weakness occurs when a web application's cross-origin resource sharing (CORS) policy or similar cross-domain mechanism is configured too broadly, allowing any website or untrusted domain to make requests to your application and access sensitive data or perform actions on behalf of users. A misconfigured policy can turn your application into a stepping stone for attackers to compromise user accounts or steal information.

02How It Happens

Modern browsers enforce the Same-Origin Policy to prevent one website from directly accessing data on another. Cross-domain policies like CORS exist to safely relax this restriction when needed — for example, to allow a legitimate partner API to fetch data. However, developers sometimes configure these policies with wildcards (*), null origins, or overly broad domain patterns without understanding the security implications. When a policy allows any origin to make credentialed requests (requests that include cookies or authentication tokens), an attacker can craft a malicious webpage that, when visited by a logged-in user, silently makes requests to your application using that user's credentials.

03Real-World Impact

An attacker can exploit this weakness to read sensitive user data (account details, personal information, financial records), modify or delete data, perform unauthorized actions (transfer funds, change passwords, post content), or escalate privileges. Because the request originates from the user's browser with their active session, the application cannot easily distinguish it from a legitimate user action. The damage is often invisible to the user until they notice unauthorized changes.

04Vulnerable & Fixed Patterns

Vulnerable pattern
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/user-data', methods=['GET'])
def get_user_data():
    # Vulnerable: allows any origin to access this endpoint
    response = jsonify({'user_id': 123, 'email': 'user@example.com'})
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    return response

Why it's vulnerable:
The * wildcard allows any domain to request this endpoint, and Allow-Credentials: true means the browser will include authentication cookies. An attacker's website can fetch this data on behalf of a logged-in user.

Fixed pattern
from flask import Flask, request, jsonify

app = Flask(__name__)
ALLOWED_ORIGINS = ['https://trusted-partner.example.com', 'https://app.example.com']

@app.route('/api/user-data', methods=['GET'])
def get_user_data():
    origin = request.headers.get('Origin')
    if origin in ALLOWED_ORIGINS:
        response = jsonify({'user_id': 123, 'email': 'user@example.com'})
        response.headers['Access-Control-Allow-Origin'] = origin
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        return response
    return jsonify({'error': 'Forbidden'}), 403
Vulnerable pattern
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST');

$user_data = array(
    'user_id' => 123,
    'email' => 'user@example.com'
);
echo json_encode($user_data);
?>

Why it's vulnerable:
The wildcard origin combined with credential support allows any website to request and receive sensitive user data with the user's authentication context.

Fixed pattern
<?php
$allowed_origins = array(
    'https://trusted-partner.example.com',
    'https://app.example.com'
);

$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';

if (in_array($origin, $allowed_origins, true)) {
    header('Access-Control-Allow-Origin: ' . $origin);
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Methods: GET, POST');
} else {
    http_response_code(403);
    exit('Forbidden');
}

$user_data = array(
    'user_id' => 123,
    'email' => 'user@example.com'
);
echo json_encode($user_data);
?>

05Prevention Checklist

Explicitly list trusted origins
— Never use * as the Access-Control-Allow-Origin value. Maintain a whitelist of specific, fully qualified domain names (e.g., https://partner.example.com, not *.example.com).
Avoid Allow-Credentials: true with broad origins
— If you must allow credentials, restrict the origin list to only the domains that genuinely need them.
Validate the Origin header
— Check that incoming requests have an Origin header matching your whitelist before responding with CORS headers.
Use HTTPS only
— Restrict allowed origins to HTTPS URLs to prevent man-in-the-middle attacks that could inject malicious origins.
Review and audit CORS policies regularly
— Treat CORS configuration as a security control; document why each origin is whitelisted and remove entries that are no longer needed.
Implement CSRF tokens for state-changing requests
— Even with a restrictive CORS policy, use additional protections (SameSite cookies, CSRF tokens) for POST, PUT, and DELETE operations.

06Signs You May Already Be Affected

Check your application's HTTP response headers for Access-Control-Allow-Origin: * or overly broad patterns. Review your web server or application framework configuration files (e.g., .htaccess, nginx.conf, middleware settings) for CORS rules. If you find a wildcard or null origin combined with Allow-Credentials: true, or if your whitelist includes domains you don't recognize or no longer use, your application may be vulnerable.

07Related Recent Vulnerabilities