Security Vulnerability Patterns
This reference catalogs common security vulnerability patterns, insecure coding idioms, and historical CVE-style patterns with detection techniques and exploitability assessment.
Table of Contents
- Injection Vulnerabilities
- Authentication and Session Management
- Cross-Site Scripting (XSS)
- Insecure Deserialization
- Path Traversal
- Buffer Overflow
- Cryptographic Failures
- Access Control Issues
- Server-Side Request Forgery (SSRF)
- XML External Entity (XXE)
- Race Conditions
- Command Injection
- Exploitability Assessment
Injection Vulnerabilities
Pattern 1: SQL Injection
Detection:
- String concatenation in SQL queries
- User input directly embedded in queries
- No parameterized queries or prepared statements
Example (Python):
# VULNERABLE
def get_user(username):
query = "SELECT * FROM users WHERE username = '" + username + "'"
cursor.execute(query)
Why Risky: Attacker can inject SQL code to:
- Bypass authentication
- Extract sensitive data
- Modify or delete data
- Execute administrative operations
Exploitation Conditions:
- User input reaches SQL query
- No input validation or sanitization
- Database errors exposed to user
Safe Pattern:
# SAFE
def get_user(username):
query = "SELECT * FROM users WHERE username = ?"
cursor.execute(query, (username,))
Pattern 2: NoSQL Injection
Detection:
- Direct object construction from user input
- No input validation for MongoDB/NoSQL queries
- User input in query operators ($where, $regex, etc.)
Example (JavaScript):
// VULNERABLE
app.post('/login', (req, res) => {
db.users.findOne({ username: req.body.username, password: req.body.password });
});
Why Risky:
Attacker can inject query operators like {$ne: null} to bypass authentication.
Exploitation Conditions:
- User input directly used in NoSQL queries
- No type validation
- Query operators not sanitized
Pattern 3: LDAP Injection
Detection:
- String concatenation in LDAP filters
- User input in LDAP queries without escaping
Example (Java):
// VULNERABLE
String filter = "(uid=" + username + ")";
NamingEnumeration results = ctx.search("ou=users", filter, controls);
Why Risky: Attacker can modify LDAP queries to access unauthorized data.
Exploitation Conditions:
- User input in LDAP filter
- No special character escaping
- LDAP errors exposed
Authentication and Session Management
Pattern 4: Hardcoded Credentials
Detection:
- Passwords, API keys, tokens in source code
- Credentials in configuration files committed to version control
- Secrets in environment variable defaults
Example (Python):
# VULNERABLE
API_KEY = "sk-1234567890abcdef"
DATABASE_PASSWORD = "admin123"
Why Risky:
- Credentials exposed in version control history
- Anyone with code access can authenticate
- Difficult to rotate compromised credentials
Exploitation Conditions:
- Code repository is public or leaked
- Credentials still valid
- No additional authentication factors
Pattern 5: Weak Session Management
Detection:
- Predictable session IDs
- Session IDs in URLs
- No session expiration
- Session fixation vulnerabilities
Example (PHP):
// VULNERABLE
session_id($_GET['sessionid']); // Session fixation
session_start();
Why Risky: Attacker can hijack user sessions or fix session IDs.
Exploitation Conditions:
- Session ID predictable or exposed
- No session regeneration after login
- Long or infinite session lifetime
Pattern 6: Insecure Password Storage
Detection:
- Plain text password storage
- Weak hashing algorithms (MD5, SHA1)
- No salt or weak salt
- Insufficient iteration count
Example (Java):
// VULNERABLE
String hashedPassword = MessageDigest.getInstance("MD5").digest(password.getBytes());
Why Risky: Passwords can be recovered through rainbow tables or brute force.
Exploitation Conditions:
- Database breach
- Weak hashing algorithm
- No or predictable salt
Cross-Site Scripting (XSS)
Pattern 7: Reflected XSS
Detection:
- User input directly rendered in HTML
- No output encoding/escaping
- innerHTML or similar DOM manipulation with user data
Example (JavaScript):
// VULNERABLE
document.getElementById('result').innerHTML = "Hello " + req.query.name;
Why Risky: Attacker can inject JavaScript to steal cookies, session tokens, or perform actions as the victim.
Exploitation Conditions:
- User input reflected in response
- No Content-Security-Policy
- Sensitive data in cookies/localStorage
Pattern 8: Stored XSS
Detection:
- User input stored and displayed without sanitization
- Rich text editors without proper filtering
- User-generated content rendered as HTML
Example (Python/Flask):
# VULNERABLE
@app.route('/comment', methods=['POST'])
def add_comment():
comment = request.form['comment']
db.save_comment(comment)
return render_template('comments.html', comment=comment)
Why Risky: Persistent attack affecting all users viewing the content.
Exploitation Conditions:
- Stored data rendered without encoding
- Multiple users access the content
- No input validation or output encoding
Pattern 9: DOM-based XSS
Detection:
- Client-side JavaScript using unsafe sinks (innerHTML, eval, document.write)
- User-controlled data from URL fragments, postMessage
- No sanitization before DOM manipulation
Example (JavaScript):
// VULNERABLE
let userInput = location.hash.substring(1);
eval(userInput);
Why Risky: Entirely client-side attack, bypassing server-side protections.
Exploitation Conditions:
- Unsafe sink with user-controlled source
- No client-side validation
- Sensitive operations in JavaScript
Insecure Deserialization
Pattern 10: Unsafe Deserialization
Detection:
- Deserializing untrusted data
- pickle, yaml.load, unserialize without validation
- Java ObjectInputStream with untrusted data
Example (Python):
# VULNERABLE
import pickle
user_data = pickle.loads(request.data)
Why Risky: Attacker can execute arbitrary code during deserialization.
Exploitation Conditions:
- Application deserializes user input
- Gadget chains available in classpath
- No integrity checks on serialized data
Safe Pattern:
# SAFE
import json
user_data = json.loads(request.data)
Path Traversal
Pattern 11: Directory Traversal
Detection:
- File paths constructed from user input
- No path validation or sanitization
- Direct file access with user-controlled names
Example (Node.js):
// VULNERABLE
app.get('/download', (req, res) => {
let filename = req.query.file;
res.sendFile('/uploads/' + filename);
});
Why Risky:
Attacker can access files outside intended directory using ../ sequences.
Exploitation Conditions:
- User controls file path
- No path canonicalization
- Sensitive files accessible
Buffer Overflow
Pattern 12: Stack Buffer Overflow
Detection:
- Unsafe C functions (strcpy, sprintf, gets)
- No bounds checking on buffer writes
- Fixed-size buffers with variable-length input
Example (C):
// VULNERABLE
void process_input(char *user_input) {
char buffer[64];
strcpy(buffer, user_input); // No bounds check
}
Why Risky: Attacker can overwrite return addresses, execute arbitrary code.
Exploitation Conditions:
- No stack canaries or ASLR
- Executable stack
- Attacker controls input length
Pattern 13: Heap Buffer Overflow
Detection:
- malloc/new without size validation
- Off-by-one errors in loops
- Integer overflow in size calculations
Example (C++):
// VULNERABLE
int size = user_size;
char *buffer = new char[size];
memcpy(buffer, user_data, user_length); // user_length > size
Why Risky: Heap metadata corruption, arbitrary code execution.
Exploitation Conditions:
- Heap exploitation techniques available
- Attacker controls size or data
- No heap protections
Cryptographic Failures
Pattern 14: Weak Encryption
Detection:
- DES, RC4, or other deprecated algorithms
- ECB mode for block ciphers
- Small key sizes (< 128 bits)
Example (Java):
// VULNERABLE
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
Why Risky: Encrypted data can be decrypted through cryptanalysis.
Exploitation Conditions:
- Sufficient ciphertext available
- Known plaintext attacks possible
- Weak algorithm or mode
Pattern 15: Insecure Random Number Generation
Detection:
- Using non-cryptographic RNGs for security (rand(), Math.random())
- Predictable seeds
- Insufficient entropy
Example (Python):
# VULNERABLE
import random
session_token = ''.join(random.choices(string.ascii_letters, k=32))
Why Risky: Predictable tokens can be guessed or brute-forced.
Exploitation Conditions:
- Attacker can observe multiple tokens
- Seed is predictable
- Used for security-critical operations
Safe Pattern:
# SAFE
import secrets
session_token = secrets.token_urlsafe(32)
Pattern 16: Missing Certificate Validation
Detection:
- SSL/TLS certificate validation disabled
- Accepting self-signed certificates
- No hostname verification
Example (Python):
# VULNERABLE
import ssl
context = ssl._create_unverified_context()
urllib.request.urlopen(url, context=context)
Why Risky: Man-in-the-middle attacks possible.
Exploitation Conditions:
- Network traffic interceptable
- Attacker can present fake certificate
- Sensitive data transmitted
Access Control Issues
Pattern 17: Insecure Direct Object Reference (IDOR)
Detection:
- User IDs or object IDs in URLs/parameters
- No authorization check before data access
- Predictable or sequential identifiers
Example (Python/Flask):
# VULNERABLE
@app.route('/user/<user_id>')
def get_user(user_id):
return db.get_user(user_id) # No auth check
Why Risky: Attacker can access other users' data by changing IDs.
Exploitation Conditions:
- No authorization checks
- Predictable identifiers
- Sensitive data accessible
Pattern 18: Missing Function-Level Access Control
Detection:
- Admin functions accessible without role check
- Client-side access control only
- No server-side authorization
Example (JavaScript/Express):
// VULNERABLE
app.post('/admin/delete-user', (req, res) => {
deleteUser(req.body.userId); // No admin check
});
Why Risky: Privilege escalation, unauthorized administrative actions.
Exploitation Conditions:
- Attacker knows endpoint
- No authentication or authorization
- Sensitive operations exposed
Server-Side Request Forgery (SSRF)
Pattern 19: SSRF via URL Parameter
Detection:
- User-controlled URLs in HTTP requests
- No URL validation or allowlist
- Internal network accessible
Example (Python):
# VULNERABLE
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
response = requests.get(url)
return response.content
Why Risky: Attacker can access internal services, cloud metadata endpoints.
Exploitation Conditions:
- Application makes requests to user URLs
- Internal network accessible
- Cloud metadata available (169.254.169.254)
Pattern 20: SSRF via File Upload
Detection:
- Processing URLs in uploaded files (XML, SVG, PDF)
- No validation of external references
- XXE combined with SSRF
Why Risky: Bypass network restrictions, access internal resources.
Exploitation Conditions:
- File processing follows external references
- Internal network accessible
- No URL filtering
XML External Entity (XXE)
Pattern 21: XXE Injection
Detection:
- XML parsing with external entities enabled
- No DTD validation disabled
- User-controlled XML input
Example (Java):
// VULNERABLE
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(userXmlInput);
Why Risky: File disclosure, SSRF, denial of service.
Exploitation Conditions:
- External entities not disabled
- File system accessible
- XML parser processes DTDs
Safe Pattern:
// SAFE
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder builder = factory.newDocumentBuilder();
Race Conditions
Pattern 22: Time-of-Check Time-of-Use (TOCTOU)
Detection:
- File operations with check-then-use pattern
- Shared resource access without locking
- Non-atomic operations on critical data
Example (C):
// VULNERABLE
if (access(filename, W_OK) == 0) {
// File is writable
fd = open(filename, O_WRONLY); // Race window here
write(fd, data, size);
}
Why Risky: Attacker can modify file between check and use.
Exploitation Conditions:
- Shared file system
- Predictable timing
- Privileged process
Pattern 23: Race Condition in Web Applications
Detection:
- Non-atomic database operations
- No transaction isolation
- Concurrent access to shared state
Example (Python):
# VULNERABLE
balance = db.get_balance(user_id)
if balance >= amount:
db.set_balance(user_id, balance - amount) # Race here
Why Risky: Double-spending, inconsistent state.
Exploitation Conditions:
- Concurrent requests possible
- No locking or transactions
- Financial or critical operations
Command Injection
Pattern 24: OS Command Injection
Detection:
- User input in system(), exec(), shell commands
- No input validation or escaping
- Shell metacharacters not filtered
Example (PHP):
// VULNERABLE
$filename = $_GET['file'];
system("cat /var/log/" . $filename);
Why Risky: Arbitrary command execution on server.
Exploitation Conditions:
- User input reaches shell command
- Shell metacharacters not escaped
- Sufficient privileges
Safe Pattern:
# SAFE
import subprocess
subprocess.run(['cat', '/var/log/' + filename], shell=False)
Pattern 25: Code Injection
Detection:
- eval(), exec() with user input
- Dynamic code generation from user data
- Template injection
Example (Python):
# VULNERABLE
user_code = request.form['code']
eval(user_code)
Why Risky: Complete application compromise, arbitrary code execution.
Exploitation Conditions:
- User input in eval/exec
- No sandboxing
- Application privileges
Exploitability Assessment
Severity Levels
Critical:
- Remote code execution
- Authentication bypass
- Complete data breach
- System compromise
High:
- Privilege escalation
- Sensitive data exposure
- SQL injection with data access
- SSRF to internal services
Medium:
- XSS with session theft
- IDOR to user data
- Information disclosure
- Weak cryptography
Low:
- Information leakage
- Minor configuration issues
- Low-impact XSS
- Verbose error messages
Exploitability Factors
Attack Complexity:
- Low: Simple exploit, no special conditions
- Medium: Requires specific conditions or timing
- High: Complex exploit chain, rare conditions
Privileges Required:
- None: Unauthenticated attack
- Low: Basic user account needed
- High: Administrative access required
User Interaction:
- None: Fully automated exploit
- Required: Victim must take action (click link, etc.)
Impact:
- Confidentiality: Data exposure
- Integrity: Data modification
- Availability: Service disruption
CVE-Style Pattern Examples
CVE-2021-44228 (Log4Shell):
- Pattern: JNDI lookup in log messages
- Detection:
${jndi:ldap://in user input reaching logger - Exploitability: Critical, no authentication, remote code execution
CVE-2017-5638 (Struts2):
- Pattern: OGNL injection in Content-Type header
- Detection: Struts2 file upload with malformed Content-Type
- Exploitability: Critical, remote code execution
CVE-2014-0160 (Heartbleed):
- Pattern: Buffer over-read in TLS heartbeat
- Detection: OpenSSL 1.0.1 through 1.0.1f
- Exploitability: High, memory disclosure, no authentication
Detection Confidence Levels
High Confidence (90-100%):
- Exact pattern match with known vulnerability
- Clear exploit path
- No mitigating controls
Medium Confidence (60-89%):
- Pattern resembles vulnerability
- Exploitation requires specific conditions
- Some mitigating controls present
Low Confidence (30-59%):
- Potential vulnerability
- Unclear exploit path
- Multiple mitigating factors
- Requires manual verification