skills/open-cors-anti-pattern/SKILL.md
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.
npx skillsauth add igbuend/grimbard open-cors-anti-patternInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Severity: Medium
Misconfigured CORS policies allow any website to make authenticated requests on behalf of users. Servers responding with Access-Control-Allow-Origin: * or reflecting client Origin headers enable data theft and unauthorized actions.
The anti-pattern is overly permissive Access-Control-Allow-Origin headers: wildcard (*) or reflecting client Origin values.
# 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 Origin header.
# Attacker site (https://evil.com) can make requests.
origin = request.headers.get('Origin')
if origin:
response.headers['Access-Control-Allow-Origin'] = origin
# DANGEROUS: Wildcard with credentials.
# Most browsers block, but 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():
# Endpoint for frontend, relies on session cookie.
user = get_user_from_session()
return jsonify(user.to_dict())
# Attack:
# 1. Logged-in user visits https://evil.com
# 2. Script fetches https://yourapp.com/api/user/profile
# 3. Permissive CORS allows request with session cookie
# 4. Server responds with user's sensitive profile
# 5. evil.com exfiltrates user data
# SECURE: Maintain a strict allowlist of trusted origins.
from flask import Flask, request, jsonify
app = Flask(__name__)
# Strict allowlist of permitted origins.
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:
# Set header only if origin in trusted list.
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
# Vary tells caches response depends on 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())
# Script from https://evil.com: origin not in ALLOWED_ORIGINS,
# no CORS headers sent. Browser same-origin policy blocks request.
Access-Control-Allow-Origin. Is it *? Does it match the Origin of your request even if that origin is untrusted?curl: Make a request and set a custom Origin header to see if the server reflects it:
curl -H "Origin: https://evil.com" -I https://yourapp.com/api/some-endpoint
Check if the response contains Access-Control-Allow-Origin: https://evil.com.Origin header: Validate against allowlist before reflecting.* unsafe for endpoints using cookies or Authorization headers. Only use for public, unauthenticated resources.Access-Control-Allow-Credentials carefully: Set to true only when necessary and only for allowlisted origins.Vary: Origin header: Tells caches response depends on Origin. Prevents cached response for trusted origin being served to malicious one.development
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.