# Vulnerability Patterns Reference Detailed patterns for identifying security vulnerabilities across languages and frameworks. ## Table of Contents - [Injection Vulnerabilities](#injection-vulnerabilities) - [Authentication and Session Issues](#authentication-and-session-issues) - [Cryptographic Weaknesses](#cryptographic-weaknesses) - [Insecure Deserialization](#insecure-deserialization) - [Server-Side Request Forgery](#server-side-request-forgery) - [File Operations](#file-operations) - [Framework-Specific Patterns](#framework-specific-patterns) ## Injection Vulnerabilities ### SQL Injection **Vulnerable patterns** (string concatenation or f-strings in queries): ``` # Python execute(f"...{var}...") execute("..." + var + "...") execute("...%s..." % var) # JavaScript query(`...${var}...`) query("..." + var + "...") # Go db.Query("..." + var + "...") fmt.Sprintf("SELECT ... %s", var) passed to Query() # Java statement.execute("..." + var + "...") ``` **Safe alternatives**: Parameterized queries, prepared statements, ORM query builders. ### NoSQL Injection **Vulnerable patterns**: ```javascript // MongoDB: user input directly in query object db.collection.find({ user: req.body.user, pass: req.body.pass }) // Attacker sends: { "pass": { "$gt": "" } } ``` **Safe alternative**: Validate input types, use `$eq` explicitly, sanitize with libraries like `mongo-sanitize`. ### Command Injection **Vulnerable functions by language**: ``` Python: os.system(), os.popen(), subprocess.call(shell=True), subprocess.Popen(shell=True) Node.js: child_process.exec(), child_process.execSync() Go: exec.Command("sh", "-c", userInput) Java: Runtime.exec(userInput) PHP: exec(), system(), passthru(), shell_exec(), backticks Ruby: system(), exec(), backticks, %x{} ``` **Safe alternative**: Use subprocess with list arguments (no shell), validate and allowlist input values. ### LDAP Injection **Vulnerable pattern**: ```python ldap.search_s(base, scope, f"(uid={username})") ``` **Safe alternative**: Escape special characters `()*\` and null bytes in user input. ### XSS (Cross-Site Scripting) **Vulnerable sinks**: ``` JavaScript: innerHTML, outerHTML, document.write(), eval(), v-html, dangerouslySetInnerHTML Template: |safe, {% autoescape off %}, !=, !{}, {!! !!} ``` **Safe alternatives**: Use `textContent`, template auto-escaping, CSP headers, DOMPurify for required HTML. ## Authentication and Session Issues ### Weak Password Storage **Vulnerable**: ```python # Plaintext or weak hashing hashlib.md5(password.encode()).hexdigest() hashlib.sha256(password.encode()).hexdigest() ``` **Safe**: ```python # Use adaptive hashing with salt import bcrypt hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) ``` ### JWT Vulnerabilities **Common issues**: - Accepting `alg: "none"` - Using symmetric algorithms (HS256) with public keys - Not validating expiry (`exp`) or issuer (`iss`) - Storing sensitive data in payload (JWT is base64, not encrypted) **Verification checklist**: ```python # Ensure algorithm is explicitly specified jwt.decode(token, key, algorithms=["RS256"]) # explicit algorithm jwt.decode(token, key) # VULNERABLE: accepts any algorithm ``` ### Session Management **Issues to flag**: - Session IDs in URLs - Missing `HttpOnly`, `Secure`, `SameSite` flags on session cookies - No session timeout or rotation after authentication - Predictable session identifiers ## Cryptographic Weaknesses ### Insecure Algorithms **Deprecated/broken** (flag if found): ``` Hash: MD5, SHA1 (for security purposes) Cipher: DES, 3DES, RC4, Blowfish Mode: ECB mode for any block cipher RSA: Key size < 2048 bits ``` **Acceptable**: ``` Hash: SHA-256, SHA-384, SHA-512, BLAKE2 Cipher: AES-128/256-GCM, ChaCha20-Poly1305 RSA: 2048+ bits with OAEP padding ECDSA: P-256 or P-384 curves ``` ### Hardcoded Cryptographic Material **Flag if found in source**: - Encryption keys, IV/nonce values - Private keys (RSA, ECDSA, Ed25519) - Salt values for password hashing ## Insecure Deserialization **Vulnerable functions by language**: ``` Python: pickle.loads(), yaml.load() (without SafeLoader), marshal.loads() Java: ObjectInputStream.readObject(), XMLDecoder PHP: unserialize() Ruby: Marshal.load(), YAML.load() Node.js: node-serialize, js-yaml.load() (with dangerous schema) ``` **Safe alternatives**: Use JSON for data exchange, use safe loaders (`yaml.safe_load()`), validate and type-check deserialized data. ## Server-Side Request Forgery **Vulnerable pattern**: ```python # User controls the URL requests.get(user_provided_url) urllib.request.urlopen(user_provided_url) ``` **Mitigations**: - Validate URLs against an allowlist of domains/IPs - Block requests to internal/private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x) - Disable redirects or validate redirect targets - Use a network-level firewall for outbound requests ## File Operations ### Path Traversal **Vulnerable pattern**: ```python # User controls filename open(os.path.join(base_dir, user_filename)) ``` **Safe pattern**: ```python import pathlib base = pathlib.Path(base_dir).resolve() target = (base / user_filename).resolve() if not str(target).startswith(str(base)): raise ValueError("Path traversal detected") ``` ### Unrestricted File Upload **Checklist**: - Validate file type by content (magic bytes), not just extension - Enforce maximum file size limits - Store uploads outside the web root - Generate random filenames, do not use user-supplied names - Scan uploads for malware when possible ## Framework-Specific Patterns ### Django ```python # Dangerous: raw SQL Model.objects.raw(f"SELECT * FROM t WHERE id = {user_id}") # Safe: ORM or parameterized raw Model.objects.filter(id=user_id) Model.objects.raw("SELECT * FROM t WHERE id = %s", [user_id]) # Check settings.py DEBUG = True # Must be False in production ALLOWED_HOSTS = ['*'] # Must be restricted CSRF_COOKIE_SECURE = False # Must be True with HTTPS SESSION_COOKIE_SECURE = False # Must be True with HTTPS ``` ### Flask ```python # Dangerous: XSS via Markup from markupsafe import Markup return Markup(f"
{user_input}
") # Safe: Use templates with auto-escaping return render_template("page.html", data=user_input) # Check for debug mode app.run(debug=True) # Must be False in production ``` ### Express.js ```javascript // Missing security headers - use helmet const helmet = require('helmet'); app.use(helmet()); // Missing CSRF protection on state-changing routes // Missing rate limiting on auth endpoints // Missing input validation (use express-validator or zod) ``` ### Spring Boot ```java // Dangerous: SpEL injection parser.parseExpression(userInput).getValue(); // Check application.properties server.error.include-stacktrace=always // Leaks internals management.endpoints.web.exposure.include=* // Exposes actuator ```