# Permissive Cross-domain Policy with Untrusted Domains (CWE-942) The product uses a cross-domain policy file that includes domains that should not be trusted. - Prevalence: High Frequently exploited - Impact: High 1 high-severity rules - Prevention: Documented 9 fix examples **OWASP:** Security Misconfiguration (A05:2021-Security Misconfiguration) - #5 ## Description A cross-domain policy file specifies the permissions for a web client to handle data across multiple domains. When overly permissive settings are used, malicious sites can abuse these permissions to access sensitive data or perform unauthorized actions on behalf of the user. ## Prevention ### Python Restrict CORS to specific trusted origins instead of wildcard '*' Restrict Flask-CORS to specific trusted origins instead of wildcard '*' Use exact string matching against an allowlist instead of regex for origin validation ### Go Configure specific allowed origins in Chi CORS middleware Configure specific allowed origins in Echo CORS middleware Configure specific allowed origins in Fiber CORS middleware ## Warning Signs - [HIGH] CORS validation uses weak pattern matching that can be bypassed - [HIGH] CORS implementations using weak regex patterns, prefix/suffix matching, or substring checks that can - [MEDIUM] FastAPI uses CORSMiddleware with allow_origins=['*'] and allow_credentials=True - [MEDIUM] overly permissive CORS configuration in FastAPI applications - [MEDIUM] Flask application uses CORS(*, supports_credentials=True) which allows any origin to make authenticated requests - [MEDIUM] Gin CORS middleware configured with wildcard origin - [MEDIUM] CORS policy allows untrusted origins - [MEDIUM] overly permissive CORS (Cross-Origin Resource Sharing) configurations that allow any origin (*) with ## Consequences - Read Application Data - Bypass Protection Mechanism - Modify Application Data ## Mitigations - Carefully evaluate access policies and limit domains in the cross-domain policy file - Do not use wildcards (*) to allow all domains - Review and restrict CORS headers to only trusted origins ## Detection - Total rules: 9 - Languages: python, go ## Rules by Language ### Go (5 rules) - **Chi Permissive CORS** [MEDIUM]: Wildcard CORS allows any origin to access resources. - Remediation: Specify allowed origins instead of wildcard. ```go r.Use(cors.Handler(cors.Options{ AllowedOrigins: []string{ "https://example.com", "https://app.example.com", }, })) ``` Learn more: https://shoulder.dev/learn/go/cwe-942/cors - **Echo Permissive CORS** [MEDIUM]: Wildcard CORS allows any origin to access resources. - Remediation: Specify allowed origins instead of wildcard. ```go e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{ "https://example.com", "https://app.example.com", }, })) ``` Learn more: https://shoulder.dev/learn/go/cwe-942/cors - **Fiber Permissive CORS** [MEDIUM]: Wildcard CORS allows any origin to access resources. - Remediation: Specify allowed origins instead of wildcard. ```go app.Use(cors.New(cors.Config{ AllowOrigins: "https://example.com,https://app.example.com", })) ``` Learn more: https://shoulder.dev/learn/go/cwe-942/cors - **Gin Permissive CORS** [MEDIUM]: Wildcard CORS allows any origin to access resources. - Remediation: Specify allowed origins instead of wildcard. ```go config := cors.DefaultConfig() config.AllowOrigins = []string{ "https://example.com", "https://app.example.com", } r.Use(cors.New(config)) ``` Learn more: https://shoulder.dev/learn/go/cwe-942/cors - **Permissive CORS Configuration** [MEDIUM]: CORS allows wildcard origin or reflects Origin header without validation. - Remediation: Whitelist specific allowed origins instead of using wildcards. ```go allowedOrigins := map[string]bool{ "https://app.example.com": true, } origin := r.Header.Get("Origin") if allowedOrigins[origin] { w.Header().Set("Access-Control-Allow-Origin", origin) } ``` Learn more: https://shoulder.dev/learn/go/cwe-942/permissive-cors ### Python (4 rules) - **FastAPI CORS Misconfiguration** [MEDIUM]: Detects overly permissive CORS configuration in FastAPI applications. Allowing all origins (*) with credentials enabled can lead to CSRF and data theft. - Remediation: Restrict CORS to specific origins: ```python from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["https://example.com", "https://app.example.com"], allow_credentials=True, allow_methods=["GET", "POST"], allow_headers=["*"], ) ``` - **Flask CORS Misconfiguration** [MEDIUM]: Detects overly permissive CORS configuration in Flask applications using flask-cors. Allowing all origins (*) with credentials enabled can lead to cross-site request forgery and data theft. - Remediation: Restrict CORS to specific trusted origins: ```python # GOOD: Restrict to specific origins CORS(app, resources={ r"/api/*": { "origins": ["https://example.com", "https://app.example.com"], "supports_credentials": True } }) ``` - **CORS Misconfiguration** [MEDIUM]: Detects overly permissive CORS (Cross-Origin Resource Sharing) configurations that allow any origin (*) with credentials, or reflect the Origin header without validation. This can expose sensitive data to malicious sites. - Remediation: Use an explicit origin whitelist instead of wildcard (*). ```python ALLOWED_ORIGINS = { 'https://example.com', 'https://app.example.com', } @app.after_request def add_cors(response): origin = request.headers.get('Origin') if origin in ALLOWED_ORIGINS: response.headers['Access-Control-Allow-Origin'] = origin response.headers['Access-Control-Allow-Credentials'] = 'true' return response ``` Learn more: https://shoulder.dev/learn/python/cwe-942/cors-misconfiguration - **CORS Regex Bypass Vulnerability** [HIGH]: Detects CORS implementations using weak regex patterns, prefix/suffix matching, or substring checks that can be bypassed by attackers to allow unauthorized cross-origin access from malicious domains. Common bypass patterns: 1. Unanchored regex: r"https://.*\.example\.com" matches "https://evil.com/.example.com" 2. Unescaped dots: r"https://app.trusted.com" matches "https://appXtrusted.com" 3. Prefix matching: startswith("https://trusted.com") allows "https://trusted.com.evil.com" 4. Suffix matching: endswith(".trusted.com") can be abused with subdomain takeover 5. Contains check: "trusted.com" in origin matches "nottrusted.com" - Remediation: Use strict origin validation with exact matching against an allowlist: ```python ALLOWED_ORIGINS = { "https://app.example.com", "https://api.example.com", } @app.middleware("http") async def cors_middleware(request: Request, call_next): response = await call_next(request) origin = request.headers.get("origin", "") # SAFE: Exact match against allowlist if origin in ALLOWED_ORIGINS: response.headers["Access-Control-Allow-Origin"] = origin response.headers["Access-Control-Allow-Credentials"] = "true" return response ``` If you must use regex, ensure: 1. Use fullmatch() not match() 2. Anchor patterns with ^ and $ 3. Escape all dots as \. 4. Don't use .* wildcards in domain positions