skills/oauth-security-anti-pattern/SKILL.md
Security anti-pattern for OAuth implementation vulnerabilities (CWE-352, CWE-287). Use when generating or reviewing OAuth/OIDC authentication flows, state parameter handling, or token exchange. Detects missing CSRF protection and insecure redirect handling.
npx skillsauth add igbuend/grimbard oauth-security-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: High
OAuth 2.0/OIDC flows are complex and easily misconfigured. The critical mistake: failing to implement and validate the state parameter. This parameter defends against CSRF attacks during OAuth flows. Missing or predictable state allows attackers to trick victims into logging into the attacker's account, enabling account takeover.
The anti-pattern is initiating OAuth flows without state parameters, or using predictable values not validated on callback.
# VULNERABLE: The OAuth flow is initiated without a `state` parameter.
from flask import request, redirect
OAUTH_PROVIDER_URL = "https://provider.com/auth"
CLIENT_ID = "my-client-id"
CALLBACK_URL = "https://myapp.com/callback"
@app.route("/login/provider")
def oauth_login():
# Redirects user to OAuth provider.
# FLAW: No `state` parameter to prevent CSRF.
auth_url = (f"{OAUTH_PROVIDER_URL}?client_id={CLIENT_ID}"
f"&redirect_uri={CALLBACK_URL}&response_type=code")
return redirect(auth_url)
@app.route("/callback")
def oauth_callback():
# User redirected back from provider.
# No way to verify callback corresponds to user-initiated flow.
auth_code = request.args.get("code")
# Exchanges code for tokens, logs user in.
# Attacker can link victim's session to attacker's account.
access_token = exchange_code_for_token(auth_code)
log_user_in(access_token)
return "Logged in successfully!"
Attack:
https://myapp.com/callback?code=ATTACKER_CODEmyapp.com associates victim's session with attacker's account# SECURE: A unique, unpredictable `state` is generated, stored in the session, and validated on callback.
from flask import request, redirect, session
import secrets
@app.route("/login/provider/secure")
def oauth_login_secure():
# 1. Generate cryptographically random `state`.
state = secrets.token_urlsafe(32)
# 2. Store in user's session.
session['oauth_state'] = state
auth_url = (f"{OAUTH_PROVIDER_URL}?client_id={CLIENT_ID}"
f"&redirect_uri={CALLBACK_URL}&response_type=code"
f"&state={state}") # 3. Send state to provider.
return redirect(auth_url)
@app.route("/callback/secure")
def oauth_callback_secure():
# 4. Provider returns `state` in callback.
received_state = request.args.get("state")
auth_code = request.args.get("code")
# 5. CRITICAL: Validate returned state matches session state.
stored_state = session.pop('oauth_state', None)
if stored_state is None or not secrets.compare_digest(stored_state, received_state):
return "Invalid state parameter. CSRF attack detected.", 403
# State valid, safe to proceed.
access_token = exchange_code_for_token(auth_code)
log_user_in(access_token)
return "Logged in successfully!"
state parameter being generated?state from the incoming request?hmac.compare_digest) to prevent timing attacks?state parameter: Required in all OAuth/OIDC authorization requests.state: Minimum 32 characters. Never use predictable values (user ID, timestamp).state in session cookie before redirect.state with session value. Reject mismatches.state.state parameter must be generated with a cryptographically secure random number generator.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.