Skip to content
Penetration Testing Guide

OWASP for Penetration Testers

The Top 10 is an awareness document, not a test plan — and treating it as one is why so many applications pass an assessment and get breached anyway. This handbook covers what the categories look like in a running application, how to prove impact without breaking production, and how to write it up so it gets fixed.

Offensive Focus

  • Manual exploitation flows
  • WAF evasion techniques
  • Logic & IDOR chaining
  • Cloud metadata pivoting

Business Value

  • Translate risk to executives
  • CVSS v4.0 scoring
  • MITRE ATT&CK mapping
  • Actionable remediation

The OWASP Way

Four documents, each built for a different job. Most people only ever read one of them.

Compliance Checks vs. Real Pentesting

PCI-DSS and ISO 27001 answer what must exist and produce evidence that it does. That evidence is genuinely useful — to an auditor. It says nothing about whether the control works against someone actively trying to get past it, which is why an application can be fully compliant and trivially exploitable on the same afternoon. OWASP answers how: how the flaw is found, how far it reaches, and what the impact is once you stop describing it and demonstrate it. Use both, and never let a compliance deadline set the scope of a penetration test.

The Four Pillars of OWASP

  • ASVS: what a correctly built application looks like, by verification level. Most useful before a line of code exists, and as the thing you cite when a developer asks what “fixed” means.
  • WSTG: the testing guide, and the one to work through methodically. It is the difference between covering an application and covering the parts you happen to find interesting.
  • Top 10: the categories worth checking first, ordered by what industry data showed at the time of publication. It is awareness material — start here, do not stop here, and remember that business logic flaws have no category at all.
  • Cheat Sheets: the remediation reference. Paste the relevant one into the finding — a developer given a link fixes it faster than one given a lecture.
Prerequisites

Chapter 0:
Building Your Testing Lab

The lab is not optional and it is not primarily about learning. It is where you confirm an exploit behaves the way you think before you ever point it at a client, which is the difference between a finding and an incident report with your name on it.

0.1 Why You Need a Local Lab

Testing systems you have no written permission to touch is a criminal offence in most jurisdictions, and “it was for my portfolio” has never been a defence. So you run deliberately vulnerable applications you own. One practical warning that catches people: keep the lab off your home LAN. A vulnerable container bridged to the network your router and personal devices sit on is a real exposure, and scanning tools do not stop politely at the target you had in mind.

Why Use Docker for Your Lab?

Docker starts a broken app in seconds, resets it to a known state instantly, and runs several targets at once — which is why it beats VMs for practice. Know the two costs. Containers share the host kernel, so a container is a weaker boundary than a VM and malware analysis belongs in the latter. And Docker writes its own iptables chain, consulted before UFW's, so a published port can be reachable from the network while your firewall status claims otherwise. Verify with nmap from another machine rather than trusting either tool.

  • Isolation: The app breaks in its own sandbox, not your system.
  • Reset in seconds: Blow up the app, restart it fresh, and try again. No cleanup needed.
  • Run multiple apps: Have Juice Shop on 3000, DVWA on 8080, and WebGoat on 8081 all at once.

0.2 Your Pentesting Setup

Lab Topology
graph LR A[Kali Linux OS] --> B(Burp Suite Proxy) B -->|HTTP/HTTPS| C(Docker Daemon) C --> D[OWASP Juice Shop] C --> E[WebGoat] C --> F[bWAPP] class A danger; class B safe; class C warning; class D,E,F card;

0.3 Your Essential Toolkit

A short list, learned properly. Depth in Burp and one scripting language will out-test a directory full of tools you have run twice each.

  1. 1
    Burp Suite or OWASP ZAP Intercept requests, modify parameters on the fly, and see exactly what the app does. This is your main weapon.
  2. 2
    FoxyProxy (Browser Plugin) Switch your browser's proxy on and off with one click instead of diving into settings every time.
  3. 3
    SecLists Huge collections of payloads, passwords, and wordlists for fuzzing. This saves hours of manual work.

Target Apps to Practice On

  • OWASP Juice Shop A modern app with real vulnerabilities. Built with Node.js and Angular like production apps.
  • DVWA Classic and simple. Perfect for learning the basics with PHP and MySQL.
  • WebGoat OWASP's interactive Java app for learning and practicing exploitation.

0.4 Get These Apps Running

OWASP Juice Shop Docker Deployment

Terminal
Bash
docker run --rm -p 3000:3000 bkimminich/juice-shop

Access It

Once it's running, go to http://localhost:3000 in your browser.

DVWA (PHP/MySQL)

Terminal
Bash
docker run --rm -it -p 8080:80 vulnerables/web-dvwa

Visit http://localhost:8080. Login: admin/password. Hit "Create/Reset Database" on the setup page.

bWAPP (Interactive Labs)

Terminal
Bash
docker run -d -p 8081:80 hackersploit/bwapp-docker

First time: go to http://localhost:8081/install.php to setup. Then login at http://localhost:8081/login.php with bee/bug.

Enable HTTPS Interception

Why Your Certs Fail

If you try to intercept HTTPS without installing Burp's certificate, your browser blocks it with a security error. You need to tell your browser to trust Burp.
  • How to Set It Up
    1. Open Burp and enable Proxy Intercept.
    2. In your proxy-configured browser, go to http://burp.
    3. Click "CA Certificate" to download the cert file.
    4. Import it into your browser's trusted certificates.
OWASP Top 10 - A01:2025

Chapter 1:
Broken Access Control

The app verified you're logged in, but does it actually check that you own the data you're accessing? That's where access control fails. We show you how to find and exploit it.

1.1 Where It Goes Wrong

Authentication answers who you are. Authorisation answers what you may touch, and it is the second one that gets skipped. The server confirms you are logged in, then trusts whatever identifier you hand it: ask for user 456 and you get user 456. Fixing one endpoint is not the fix — if authorisation is decided per handler rather than centrally, you have found the first of an unknown number, and the honest finding says so.

Deep Dive: The 'Trust' Fallacy

In a properly secured application, the processing flow must involve: Authentication (Who are you?), Authorisation (Can you do this?), and Object-Level Validation (Can you do this to this specific object?). BAC occurs when step 3 is missing. For example, an API endpoint accepts an object ID and performs an action, but the server-side code neglects to check if the authenticated user actually owns that object.

  • Over-reliance on Client-Side State: Hiding admin buttons in React, but leaving the /api/admin/deleteUser endpoint unprotected.
  • Predictable Identifiers: Using sequential IDs (id=1) makes enumeration trivial.
  • Blind Trust in Input: Treating user-supplied parameters (like "isAdmin": true in a JSON body) as benign.

1.2 Request Lifecycle & IDOR Exploitation

IDOR Attack Flow Architecture
sequenceDiagram actor Attacker (User A) participant WebApp as Web Application participant Database Attacker->>WebApp: GET /api/profile?id=A_123 (Legitimate) WebApp->>Database: SELECT * FROM users WHERE id=A_123 Database-->>WebApp: Returns Data A WebApp-->>Attacker: 200 OK (Data A) Note over Attacker,Database: The IDOR Attack Phase Attacker->>WebApp: GET /api/profile?id=B_456 (Malicious) Note over WebApp: MISSING CHECK: Does User A own B_456? WebApp->>Database: SELECT * FROM users WHERE id=B_456 Database-->>WebApp: Returns Data B WebApp-->>Attacker: 200 OK (Data B Leaked)

1.3 How to Find It

No scanner finds this, because nothing in the response looks wrong — the app returns 200 and valid data, exactly as it would for the legitimate owner. You need two accounts at different privilege levels, and the discipline to replay every request from one as the other. Tedious, and the highest-yield hour in most engagements.

  1. 1
    Recon & Mapping Explore the app as unauthenticated, low-privilege, and admin. Identify all IDs (numeric, UUIDs, strings in JWTs).
  2. 2
    Dual-Session Setup Establish two distinct sessions (User A and User B) in Burp Suite to easily swap contexts.
  3. 3
    Systematic Tampering Capture User A's request, swap the ID parameter to User B's ID, and observe the backend response.

Critical Vectors

  • Horizontal IDOR Accessing a peer's data.
  • Vertical Escalation Hitting admin endpoints.
  • Mass Assignment Injecting unauthorized JSON fields.

1.4 Testing & Reporting

Real-World Request Modification

/api/v1/users/profile
Original Request
PUT /api/v1/users/profile HTTP/1.1
Host: api.target.com
Authorization: Bearer eyJhbGciOi...[User A Token]
Content-Type: application/json

{"{"}"email": "userA@test.com", "name": "User A"{"}"}

Attack Scenario (BOPLA)

Injecting privileged properties assuming the backend doesn't sanitize the JSON bind. By adding "isAdmin": true, we test if the server implicitly trusts the client object.
/api/v1/users/profile
Malicious Payload
PUT /api/v1/users/profile HTTP/1.1
Host: api.target.com
Authorization: Bearer eyJhbGciOi...[User A Token]
Content-Type: application/json

{"{"}"email": "userA@test.com", "name": "User A", "isAdmin": true, "role": 1{"}"}

Pentester Detection Methodology

  • Burp Suite Autorize: The most critical tool. Supply a low-privileged token, and Autorize automatically replays all captured high-privileged requests to test for authorisation failures.
  • Burp Repeater: Manual, iterative modification of IDs. Crucial for analysing complex error messages.
  • Param Miner: Discovers hidden or unlinked parameters that might control authorisation state.

WAF & Filter Bypass Techniques

A WAF cannot help here and should not be offered as mitigation: it has no idea who owns record 456. Watch for the half-measures too — an identifier swapped for a UUID makes enumeration harder while leaving the authorisation gap exactly where it was.

HTTP Parameter Pollution (HPP)

If the WAF checks the first parameter (MY_ID) but the backend Node/Express server processes the last parameter (VICTIM_ID), the attack succeeds.
/api/get_receipt
HPP Payload
GET /api/get_receipt?user_id=MY_ID&user_id=VICTIM_ID

Developer Remediation

Common Developer Mistake

Assuming that using a UUID instead of a sequential integer ID prevents Broken Access Control. A UUID only prevents enumeration. If an attacker discovers a UUID (e.g., via a leaked link or another API), the authorisation check is still missing.
  • Centralized Server-Side Enforcement All access decisions must occur on the server. Implement robust ABAC/RBAC mechanisms in a unified middleware layer.
  • Ownership Verification: For every request using an object ID, query the database ensuring the owner_id matches the session.
  • Avoid Implicit Binding: Do not automatically map JSON request body properties to internal database models to prevent Mass Assignment. Explicitly whitelist allowed properties.
OWASP Top 10 - A03:2025

Chapter 2:
Injection & Code Execution

Injection is a confusion of layers: the application believes it is passing data, the interpreter reads it as instructions. Everything else — SQL, OS commands, LDAP, template engines — is that same mistake in a different dialect.

2.1 Why It Happens

The developer builds a database query by mashing your input straight into SQL code. Instead of treating your input as safe data, the query becomes something like: SELECT * FROM users WHERE username = 'yourInput'. If you inject SQL into yourInput, the database runs your code. It's the most fundamental security mistake.

Deep Dive: Interpreter Processing

Once code and data are concatenated into one string, the interpreter has no way to tell them apart — the information about which part came from the developer was destroyed before it arrived. This is why input filtering is a losing strategy and parameterised queries are not: they keep the two channels separate rather than trying to spot bad values in one. ORMs help by defaulting to parameters, then hand it back the moment someone reaches for the raw-query escape hatch, which every ORM has.

  • Database (SQL/NoSQL): Leads to data exfiltration or modification.
  • Operating System Shell: Leads to Remote Code Execution (RCE) via command injection.
  • Template Engine (SSTI): Leads to server-side code execution if the template evaluates untrusted syntax.

2.2 The SQLi Data Exfiltration Chain

SQL Injection Execution Path
flowchart LR A[Attacker]:::danger -->|Injects Payload| B(Web Form / API) B -->|String Concatenation| C[(Database Server)]:::safe C -->|Syntax Error| D[Application Error] C -->|Union Select| E[Exfiltrate Data]:::safe C -->|Sleep Command| F[Time Delay]:::warning E --> A F -.->|Observes Delay| A

2.3 Finding Injection Flaws

A scanner finds error-based injection in minutes. What it misses is the blind case — no error, no change in the response body, only timing or a boolean difference — and that is exactly the case that stays unpatched for years because nothing ever surfaced it. Time-based extraction is slow enough that you should confirm the finding and stop, rather than dumping a production table to prove a point.

  1. 1
    Input Mapping Identify every single input vector (URL params, JSON fields, custom headers like X-Forwarded-For).
  2. 2
    Syntax Breaking Send single quotes ', double quotes ", or template syntax {{7*7}} to induce backend errors.
  3. 3
    Blind Identification If errors are hidden, use boolean logic (AND 1=1) or time delays (pg_sleep(10)).

Critical Injection Types

  • Time-Based Blind Measuring response time to extract data bit by bit.
  • Out-Of-Band (OOB) Forcing a DNS request to an attacker server.
  • SSTI Injecting Jinja2/Twig syntax to execute code.

2.4 Exploiting & Fixing

Real-World Payloads

Time-Based Blind SQLi (PostgreSQL)
Payload
1' AND (SELECT 1 FROM (SELECT(sleep(10)))a)--

Server-Side Template Injection

SSTI in Jinja2 allows attackers to escape the template sandbox. We use Python's built-in __globals__ to access the `os` module and execute arbitrary system commands, bypassing the web application entirely.
SSTI (Jinja2) resulting in Remote Code Execution
Payload
{"{"}{"{"} self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() {"}"}{"}"}
Command Injection (Bypassing Space Filters)
Payload
127.0.0.1;cat$IFS/etc/passwd

Pentester Detection Methodology

  • Burp Intruder: Fuzzing parameters with specialised wordlists (e.g., SecLists) designed to trigger specific database errors or time delays.
  • sqlmap: Highly automated database takeover tool. Pentesters use it after manually confirming an injection point to speed up exfiltration.
  • Burp Collaborator: Essential for Out-of-Band (OOB) injections. Generates unique domain names to detect if a backend system executes a DNS lookup payload.

WAF Bypass & Filter Evasion

WAFs match signatures, so evasion means changing the payload's appearance while preserving what it does — encoding, comments, case, alternate syntax. Worth demonstrating for one reason: a WAF rule reported as the remediation for an injection flaw is a delay, not a fix, and showing the bypass is what moves the conversation back to the query.

Evasion Strategy

Never rely on a single payload. If a WAF blocks `SELECT`, try `S%45LECT` or `SEL/**/ECT`. The database parser will often reconstruct the obfuscated string before execution.
  • Encoding: Using URL encoding, Hex encoding, or Unicode variations to hide keywords.
  • Obfuscation: Inserting SQL comments inside keywords (e.g., SEL/**/ECT) to break WAF regex.
  • sqlmap --tamper: Using built-in tamper scripts (e.g., space2comment.py) to automatically encode payloads on the fly.

Developer Remediation

  • Parameterized Queries (Prepared Statements) The absolute best defence against SQLi. It forces the database to treat input strictly as data, never as executable code, regardless of the characters it contains.
  • Strict Allow-listing: Validate all input against a strict whitelist of allowed characters or formats.
  • Avoid Shell Execution: Never use exec() or system() functions with user-supplied data. Use built-in language APIs instead.
OWASP API Top 10 & Cloud Pivot

Chapter 3:
APIs & Cloud

The front end is a client now, not a boundary. Every rule the UI appears to enforce is enforced again by the API or not at all — and the instance metadata endpoint sitting at 169.254.169.254 turns one server-side request flaw into credentials.

3.1 Why APIs Are Dangerous

APIs expose the logic directly: no form to constrain the input, no page flow to imply an order of operations. That is why the interesting bugs here are rarely injection — they are the endpoint that accepts a field the UI never sends, or a sequence the developer assumed nobody could perform out of order. Cloud makes the consequence worse. If you can persuade the application to make a request you control, the metadata service hands over the instance role's credentials, and the blast radius is whatever that role was granted rather than whatever the application needed. IMDSv2 raises the bar by requiring a PUT for a token, which defeats naive SSRF; it is not a fix, and plenty of estates still allow v1 for compatibility with something nobody wants to touch.

SSRF to Cloud Takeover

SSRF is when you trick the app into making requests to URLs you control. In AWS/GCP/Azure, there's a magic IP (169.254.169.254) that serves instance credentials. If the app has an "image fetch" feature and you inject that IP as the URL, the app will return the server's IAM credentials. Game over—you own the infrastructure.

3.2 The SSRF to Cloud Pivot Chain

AWS IAM Extraction via SSRF
sequenceDiagram actor Attacker participant App as Web Application (AWS EC2) participant Metadata as AWS IMDS (169.254.169.254) Attacker->>App: POST /fetch_image (url=http://169.254.169.254/.../s3-admin-role) Note over App: App fails to validate internal IP App->>Metadata: GET /latest/meta-data/iam/security-credentials/s3-admin-role Metadata-->>App: Returns JSON with AccessKeyId, SecretAccessKey, Token App-->>Attacker: Displays JSON as "Image Data" Note over Attacker: Attacker configures local AWS CLI with stolen creds

3.3 How to Break APIs

This part is unglamorous and it is where the findings are. Enumerate every endpoint including the ones the documentation forgot, fuzz every parameter including the ones the client never sends, then chain calls in an order the developer did not anticipate. Budget for it: thorough API work takes longer than the equivalent web application, and a scanner will report a clean run over an API it never discovered.

  1. 1
    Schema Extraction Attempt to find Swagger docs, OpenAPI specs, or use GraphQL Introspection (__schema) to map all endpoints.
  2. 2
    Parameter Fuzzing Look for parameters like url=, path=, or webhook= that might trigger outbound requests (SSRF).
  3. 3
    Logic Manipulation Attempt to call multi-step processes out of order, or batch hundreds of GraphQL queries in a single request to test rate limits.

Critical API Vectors

  • BOLA (API1:2023) The API equivalent of IDOR. Manipulating object IDs in REST paths.
  • Unrestricted Resource Sending deeply nested GraphQL queries to exhaust server memory (DoS).
  • SSRF (API7:2023) Forcing the server to make requests to internal networks.

3.4 Practical Application

Real-World Payloads

/graphql
Recon Payload
{"{"} __schema {"{"} types {"{"} name fields {"{"} name {"}"} {"}"} {"}"} {"}"}

AWS IMDS Extraction

Using SSRF to hit AWS IMDSv1 to extract highly privileged IAM roles from the EC2 instance. This immediately escalates a web vulnerability into full Cloud Account Compromise.
?url=
Malicious Payload
http://169.254.169.254/latest/meta-data/iam/security-credentials/
?url=
Malicious Payload
dict://127.0.0.1:6379/info

Pentester Detection Methodology

  • Postman & Burp API Client: Directly interacting with REST endpoints based on discovered documentation.
  • InQL (Burp Extension): Essential for GraphQL security testing. Automatically issues introspection queries and generates all possible queries/mutations for testing.
  • Burp Collaborator: Used to confirm blind SSRF. Inject a Collaborator URL into an input; if a DNS/HTTP request is received by the Collaborator server, the SSRF is confirmed.

SSRF Filter Evasion

Developers often implement blacklists to block 169.254.169.254 or 127.0.0.1. Pentesters use alternative representations.

DNS Rebinding

Setting up a custom domain that initially resolves to a safe IP (passing the WAF check), but its TTL is 0. By the time the backend logic actually makes the HTTP request, the DNS lookup resolves to an internal IP like `127.0.0.1`.
  • Decimal Encoding: http://2852039166 (resolves to 169.254.169.254).
  • Octal Encoding: http://0251.0376.0251.0376.

Developer Remediation

  • SSRF Fix & IMDSv2 Implement a strict URL whitelist. Do not use blacklists. If fetching external resources is required, resolve the DNS name and verify the target IP is not within an internal subnet before establishing the connection. For AWS, enforce IMDSv2 (requires session tokens) and disable IMDSv1.
  • GraphQL Fix Disable Introspection in production. Implement strict query depth and complexity limits to prevent Denial of Service via recursive queries.
Methodology & Workflow

Chapter 4:
Running a Real Pentest

The structure below is roughly how the time goes. Note that reporting is not a footnote at the end: it routinely takes a third of the engagement, and the hours spent writing are hours not spent testing, which is a trade to make deliberately rather than discover in the final week.

4.1 The Engagement Cycle

PTES Standard Execution Flow
flowchart LR A[Reconnaissance & Enumeration]:::card -->|Map Attack Surface| B(Threat Modelling & Vuln Analysis):::card B -->|Identify Weaknesses| C([Active Exploitation]):::danger C -->|Gain Foothold| D[Post-Exploitation & Pivoting]:::danger D -->|Assess Impact| E[Reporting & Translation]:::safe

Phase 1: Mapping the Target

You cannot test what you have not found, and the forgotten staging host is a recurring way in.

  • Passive Intelligence

    Google for subdomains, use theHarvester and Shodan. Check HTTP headers to see what tech stack they're running.

  • Brute-Force Endpoints

    Wordlists surface admin panels, exposed `.git` directories and stray config files. An exposed `.git` is worth checking early — it often yields the entire source and, with it, the credentials somebody committed once and rotated never.

    Terminal
    Bash
    ffuf -w wordlist.txt -u https://target.com/FUZZ -mc 200,401,403
  • Map Everything

    Proxy everything through Burp and map it before touching anything: every input, endpoint and form field, plus who is allowed to reach each one. Testers who skip this find the obvious bugs quickly and miss the logic flaws entirely.

Phase 2: Exploitation & Impact

Find the flaws, exploit them, and explain to management why it matters.

The Real Skill

Finding SQLi is easy. Explaining to the CEO why it costs the company $2M in data loss—that's what they're paying for. Good pentesters speak business language.
  • Attack Manually

    Repeater is where the engagement is actually won — adjusting one parameter at a time and watching what the application assumes. Automation clears the known patterns; a person is what notices that the price field is trusted from the client.

  • Pivot & Expand

    Post-exploitation is where a finding earns its severity: prove what the foothold reaches — internal services, databases, cloud credentials. Stay inside the rules of engagement while you do it, agree the boundary in writing beforehand, and stop at proof rather than exfiltrating live data to make the point.

  • Report It Right

    An unread finding is an unfixed finding. Executives need impact and cost; the engineer needs reproduction steps precise enough to argue with. Keep severity and business urgency in separate columns — a CVSS base score is designed to know nothing about what your system is worth — and resist inflating a Medium, because the credibility you spend there is what you will need for the next genuine Critical.

    • What: OWASP classification.
    • Severity: CVSS score.
    • Impact: What's the business cost? Data loss? Downtime? Breach liability?
Sponsored Links

Subscribe to my newsletter

Receive my case study and the latest articles on my WhatsApp Channel.

Warning

Ask CyberROX AI