Skip to main content
Security Testing·Lesson 2 of 5

OWASP Top 10

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

RankCategoryRisk Level
A01Broken Access ControlCritical
A02Cryptographic FailuresCritical
A03InjectionHigh
A04Insecure DesignHigh
A05Security MisconfigurationHigh
A06Vulnerable and Outdated ComponentsMedium
A07Identification and Authentication FailuresHigh
A08Software and Data Integrity FailuresMedium
A09Security Logging and Monitoring FailuresMedium
A10Server-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 finding

What 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 vulnerable

Command 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 limiting

A05: 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 existence

A08-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 SSRF

Key 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.