
open-cors-anti-pattern
Security anti-pattern for open Cross-Origin Resource Sharing (CORS) policies (CWE-942). Use when generating or reviewing server configurations, API backends, or any code that sets CORS headers. Detects overly permissive Access-Control-Allow-Origin headers, including wildcard, null origin, and reflected origin.
"Security anti-pattern for open Cross-Origin Resource Sharing (CORS) policies (CWE-942). Use when generating or reviewing server configurations, API backends, or any code that sets CORS headers. Detects overly permissive Access-Control-Allow-Origin headers, including wildcard, null origin, and reflected origin."
Open CORS Policy Anti-Pattern
Severity: Medium
Summary
Cross-Origin Resource Sharing (CORS) is a browser security feature that controls how web pages from one domain can request resources from another domain. A misconfigured, overly permissive CORS policy is a common vulnerability. This anti-pattern occurs when a server responds with Access-Control-Allow-Origin: * or dynamically reflects the client's Origin header. This allows any website on the internet to make authenticated requests to your application on behalf of your users, potentially leading to data theft and unauthorized actions.
The Anti-Pattern
The anti-pattern is configuring the Access-Control-Allow-Origin header to a value that is too permissive, such as the wildcard (*) or reflecting any value sent by the client in the Origin header.
BAD Code Example
# VULNERABLE: The server reflects any Origin header, or uses a wildcard with credentials.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.after_request
def add_cors_headers(response):
# DANGEROUS: Reflecting the Origin header.
# An attacker's site (https://evil.com) can now make requests.
origin = request.headers.get('Origin')
if origin:
response.headers['Access-Control-Allow-Origin'] = origin
# DANGEROUS: Wildcard `*` combined with `Allow-Credentials`.
# Most browsers block this, but it's a critical misconfiguration.
# response.headers['Access-Control-Allow-Origin'] = '*'
# response.headers['Access-Control-Allow-Credentials'] = 'true'
return response
@app.route("/api/user/profile")
def get_profile():
# This endpoint is intended to be called by your frontend application.
# It relies on the user's session cookie for authentication.
user = get_user_from_session()
return jsonify(user.to_dict())
# Attack Scenario:
# 1. A logged-in user of your site visits https://evil.com.
# 2. A script on evil.com makes a `fetch` request to `https://yourapp.com/api/user/profile`.
# 3. Because of the permissive CORS policy, the browser allows this request,
# and importantly, it attaches the user's session cookie.
# 4. Your server receives a valid, authenticated request and responds with the user's sensitive profile data.
# 5. The script on evil.com now has the user's data and can send it to the attacker.
GOOD Code Example
# SECURE: Maintain a strict allowlist of trusted origins.
from flask import Flask, request, jsonify
app = Flask(__name__)
# Define a strict allowlist of origins that are permitted to access your API.
ALLOWED_ORIGINS = {
"https://www.yourapp.com",
"https://yourapp.com",
"https://staging.yourapp.com"
}
@app.after_request
def add_secure_cors_headers(response):
origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
# Only set the header if the origin is in the trusted list.
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
# Vary header tells caches that the response depends on the Origin.
response.headers['Vary'] = 'Origin'
return response
@app.route("/api/user/profile")
def get_profile_secure():
user = get_user_from_session()
return jsonify(user.to_dict())
# Now, when a script from https://evil.com tries to make a request,
# the `origin` is not in the `ALLOWED_ORIGINS` set, so no CORS headers are sent.
# The browser's same-origin policy blocks the request, protecting the user's data.
Detection
- Use browser developer tools: Open the "Network" tab, make a cross-origin request to your API, and inspect the response headers. Look for
Access-Control-Allow-Origin. Is it*? Does it match theOriginof your request even if that origin is untrusted? - Use
curl: Make a request and set a customOriginheader to see if the server reflects it:
curl -H "Origin: https://evil.com" -I https://yourapp.com/api/some-endpoint
Check if the response containsAccess-Control-Allow-Origin: https://evil.com. - Review CORS configuration: Check your application's code or framework configuration for how CORS headers are being set. Look for wildcards or reflected origins.
Prevention
- [ ] Maintain a strict allowlist of trusted origins. This is the most critical step.
- [ ] Never reflect the user-provided
Originheader without validating it against the allowlist first. - [ ] Do not use the wildcard (
*) forAccess-Control-Allow-Originon any endpoint that requires authentication (e.g., uses cookies orAuthorizationheaders). A wildcard is only safe for truly public, unauthenticated resources. - [ ] Set
Access-Control-Allow-Credentialstotrueonly when necessary and only for origins on your allowlist. - [ ] Add the
Vary: Originheader to tell caches that the response is origin-dependent. This prevents a cached response intended for a trusted origin from being served to a malicious one.
Related Security Patterns & Anti-Patterns
- Missing Security Headers Anti-Pattern: CORS is a key part of the broader suite of security headers an application must manage.
- Cross-Site Scripting (XSS) Anti-Pattern: An attacker could use a permissive CORS policy to exfiltrate data stolen via an XSS attack.
References
You Might Also Like
Related Skills

create-pr
Creates GitHub pull requests with properly formatted titles that pass the check-pr-title CI validation. Use when creating PRs, submitting changes for review, or when the user says /pr or asks to create a pull request.
n8n-io
electron-chromium-upgrade
Guide for performing Chromium version upgrades in the Electron project. Use when working on the roller/chromium/main branch to fix patch conflicts during `e sync --3`. Covers the patch application workflow, conflict resolution, analyzing upstream Chromium changes, and proper commit formatting for patch fixes.
electron
pr-creator
Use this skill when asked to create a pull request (PR). It ensures all PRs follow the repository's established templates and standards.
google-gemini
clawdhub
Use the ClawdHub CLI to search, install, update, and publish agent skills from clawdhub.com. Use when you need to fetch new skills on the fly, sync installed skills to latest or a specific version, or publish new/updated skill folders with the npm-installed clawdhub CLI.
moltbot
tmux
Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
moltbot
create-pull-request
Create a GitHub pull request following project conventions. Use when the user asks to create a PR, submit changes for review, or open a pull request. Handles commit analysis, branch management, and PR creation using the gh CLI tool.
cline