The OWASP Top 10 is the most widely recognized list of critical web application security risks. Published by the Open Worldwide Application Security Project, it serves as the standard awareness document for developers and security testers.
Overview of the OWASP Top 10
| Rank | Category | Risk Level |
|---|---|---|
| A01 | Broken Access Control | Critical |
| A02 | Cryptographic Failures | Critical |
| A03 | Injection | High |
| A04 | Insecure Design | High |
| A05 | Security Misconfiguration | High |
| A06 | Vulnerable and Outdated Components | Medium |
| A07 | Identification and Authentication Failures | High |
| A08 | Software and Data Integrity Failures | Medium |
| A09 | Security Logging and Monitoring Failures | Medium |
| A10 | Server-Side Request Forgery (SSRF) | High |
A01: Broken Access Control
The most common vulnerability. Users can act outside their intended permissions.
Testing for Broken Access Control
# Test: Can a regular user access admin endpoints?
curl -H "Authorization: Bearer USER_TOKEN" \
https://api.example.com/admin/users
# Test: Can user A access user B's data? (IDOR)
# User A's profile is /api/users/101
# Try accessing /api/users/102 with User A's token
curl -H "Authorization: Bearer USER_A_TOKEN" \
https://api.example.com/api/users/102
# Test: Can you bypass access control by changing the HTTP method?
curl -X PUT -H "Authorization: Bearer USER_TOKEN" \
https://api.example.com/admin/settings
Common Findings
- Insecure Direct Object References (IDOR) -- changing an ID in the URL to access another user's data
- Missing function-level access control -- admin pages accessible without admin role
- Path traversal -- accessing files outside the intended directory
A02: Cryptographic Failures
Sensitive data exposed due to weak or missing encryption.
Testing for Cryptographic Failures
# Check if sensitive data is transmitted over HTTP
import requests
# Test for HTTP redirect to HTTPS
response = requests.get('http://example.com/login', allow_redirects=False)
if response.status_code != 301 and response.status_code != 302:
print("FINDING: Login page accessible over HTTP")
# Check TLS configuration
import ssl
import socket
hostname = 'example.com'
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(f"TLS Version: {ssock.version()}")
# TLS 1.0 and 1.1 are deprecated -- flag as findingWhat to Look For
- Passwords stored in plain text or with weak hashing (MD5, SHA1)
- Sensitive data transmitted over HTTP
- Weak TLS configurations (TLS 1.0, 1.1)
- Hardcoded encryption keys in source code
A03: Injection
Untrusted data sent to an interpreter as part of a command or query.
SQL Injection Testing
# Classic SQL injection test in a login form
# Username field: ' OR '1'='1' --
# Password field: anything
# Testing with curl
curl -X POST https://example.com/login \
-d "username=' OR '1'='1' --&password=test"
# Time-based blind SQL injection
curl "https://example.com/products?id=1' AND SLEEP(5) --"
# If the response takes 5+ seconds, the app is vulnerableCommand Injection Testing
# Test user input fields that might execute system commands
# If a form pings a host, try:
# Input: 127.0.0.1; cat /etc/passwd
# Input: 127.0.0.1 | whoami
# Input: 127.0.0.1 && ls -la
# Using curl to test
curl -X POST https://example.com/network-tools/ping \
-d "host=127.0.0.1;whoami"A04: Insecure Design
Flaws in the application's architecture that cannot be fixed by implementation alone.
Testing for Insecure Design
Checklist:
[ ] Does the app implement rate limiting on sensitive operations?
[ ] Are there account lockout mechanisms after failed login attempts?
[ ] Does the password reset flow verify the user's identity?
[ ] Are business logic flaws possible? (e.g., negative quantities in cart)
[ ] Does the app fail securely? (errors don't expose system details)# Test: Rate limiting on login
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code}\n" \
-X POST https://example.com/login \
-d "username=admin&password=wrong$i"
done
# If all return 200, there is no rate limitingA05: Security Misconfiguration
Default configurations, unnecessary features, or missing security hardening.
Testing for Misconfigurations
# Check for default credentials
curl -X POST https://example.com/login \
-d "username=admin&password=admin"
# Check for exposed debug endpoints
curl https://example.com/debug
curl https://example.com/actuator
curl https://example.com/.env
curl https://example.com/phpinfo.php
# Check HTTP security headers
curl -I https://example.com | grep -iE \
"strict-transport|content-security|x-frame|x-content-type"Required Security Headers
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()A06: Vulnerable and Outdated Components
Using libraries or frameworks with known vulnerabilities.
# Node.js: Check for vulnerable dependencies
npm audit
# Python: Check with safety
pip install safety
safety check
# Check a specific library against the NVD
# https://nvd.nist.gov/vuln/search
A07: Authentication Failures
# Test weak password policy
curl -X POST https://example.com/register \
-d "username=test&password=123" # Should be rejected
# Test session fixation
# 1. Note session ID before login
# 2. Login
# 3. Check if session ID changed (it should)
# Test for credential enumeration
curl -X POST https://example.com/login \
-d "username=existing@email.com&password=wrong"
# vs
curl -X POST https://example.com/login \
-d "username=nonexistent@email.com&password=wrong"
# If error messages differ, the app leaks user existenceA08-A10: Quick Reference
A08: Software and Data Integrity Failures
- Verify CI/CD pipeline integrity
- Check for unsigned updates or code
- Test deserialization vulnerabilities
A09: Security Logging and Monitoring Failures
- Verify login attempts are logged
- Check that logs do not contain sensitive data
- Confirm alerting on suspicious activity
A10: Server-Side Request Forgery (SSRF)
# Test if the application fetches user-supplied URLs
curl -X POST https://example.com/fetch-url \
-d "url=http://169.254.169.254/latest/meta-data/"
# This targets the AWS metadata endpoint
# If it returns data, the app is vulnerable to SSRFKey Takeaways
- The OWASP Top 10 is your roadmap for security testing priorities
- Broken Access Control is the most prevalent vulnerability
- Always test both automated and manual approaches for each category
- Document every finding with reproduction steps and severity rating
- Security testing requires a methodical, checklist-driven approach
Next, you will learn how to use vulnerability scanning tools to automate the detection of these risks.