← All posts

Our web application pentesting methodology, step by step

How we assess a web application end to end: scope, reconnaissance, mapping, analysis, controlled exploitation and a report the client actually understands.

After more than 27 assessments of web applications, APIs and mobile platforms, one thing is clear to us at Veritus Code: tools don’t find the serious vulnerabilities; methodology does. Nuclei will tell you a security header is missing. It won’t tell you that a regular user can approve their own invoices by changing an ID.

In this post we walk through how we work, phase by phase. Our methodology is built on PTES for structure, OWASP (WSTG and Top 10) for test coverage and MITRE ATT&CK for thinking like a real attacker.

Everything here applies only to systems with written authorization to test. No signed scope, no pentest: just a crime.

0. Scope and rules of engagement

Before sending a single packet, we agree on these in writing with the client:

  • What’s in and what’s out: domains, subdomains, IP ranges, APIs, mobile apps. If a new subdomain shows up during recon, we ask before touching it.
  • Test accounts: at least two users per role (two regular, two admins). Without them you can’t test access control properly.
  • Windows and limits: testing hours, request-rate limits, and whether denial-of-service testing is allowed (almost never in production).
  • Emergency contact: if we find something critical, such as RCE or a mass data leak, we report it immediately instead of waiting for the final report.

This phase looks like paperwork, but it is what separates professional work from amateur work. We also sign a non-disclosure agreement before starting.

1. Reconnaissance

The goal is to know the attack surface better than the client does. There is almost always something that was “no longer in use”.

Passive

Without touching the target: public certificates, historical DNS, search engines and code repositories.

# Subdomains from passive sources
amass enum -passive -d target.com -o subs_amass.txt
subfinder -d target.com -silent -o subs_subfinder.txt

# Issued certificates (Certificate Transparency)
curl -s "https://crt.sh/?q=%25.target.com&output=json" \
  | jq -r '.[].name_value' | sort -u > subs_crt.txt

sort -u subs_*.txt > subdomains.txt

We also search GitHub for leaks (keys, internal endpoints) and the Wayback Machine for old paths that are still alive.

Active

Now inside the agreed scope, we confirm what is alive and what it exposes:

# Which subdomains answer over HTTP/HTTPS?
httpx -l subdomains.txt -title -tech-detect -status-code -o alive.txt

# Ports and services on the main host
nmap -sC -sV -p- --min-rate 1000 -oA nmap_full target.com

# Content discovery
ffuf -u https://app.target.com/FUZZ -w raft-medium-directories.txt \
     -mc 200,204,301,302,307,401,403 -rate 50 -o ffuf.json

The -rate 50 is not a minor detail: respecting the agreed limits is part of the job.

2. Mapping the application

This is where we spend the most time, and where most of the findings come from later. With Burp Suite as a proxy, we browse the application as a real user, with every role:

  1. We go through every feature: sign-up, password reset, profile, payments, exports, file uploads…
  2. We read the frontend JavaScript: it often reveals API endpoints the UI never shows, plus hidden parameters.
  3. We build a map: what each endpoint does, what data it takes, which role should be allowed to use it and which identifiers it handles.

That map is the foundation for everything else. If you don’t understand how the business works, you can’t find business-logic flaws.

3. Vulnerability analysis

We combine two approaches, and the order matters.

Automated: the quick and obvious

nuclei -l alive.txt -severity medium,high,critical -rl 30 -o nuclei.txt

Nuclei and Burp’s scanner find insecure configurations, vulnerable versions and exposed panels. Every automated result is validated by hand: false positives in a report destroy credibility.

Manual: where the critical findings live

These are the tests no scanner does well:

  • Broken access control (IDOR / BOLA): as user A, we request user B’s resources. As a regular user, we call admin endpoints. Burp’s Autorize extension helps make this systematic.
  • Business logic: can a coupon be applied twice? Can the quantity be negative? Can a checkout step be skipped? What happens with two simultaneous requests (race condition)?
  • Injections: SQLi, XSS, template injection (SSTI) and command injection, in every parameter that reaches the server, including headers and nested JSON.
  • SSRF: any feature that takes a URL (webhooks, import from URL, PDF generation, link previews).
  • Authentication and sessions: password reset, JWT (algorithm, signature, expiry), bypassable MFA, sessions that aren’t invalidated on logout.
  • File uploads: extension, MIME type, content, and where and how the file is served afterwards.

4. Controlled exploitation

Finding a vulnerability is not enough: you have to prove its real impact without causing damage. Our rules:

  • Minimal impact: for SQLi we extract the database version and one table name, not the customer table. sqlmap is used carefully (low --level and --risk, a narrow --technique) and never against forms that write data without permission.
  • Reproducible proofs of concept: the exact request, the response and the steps, so the client’s team can verify it themselves.
  • Chaining: a low-impact XSS, plus a session token without HttpOnly, plus an endpoint that changes the account email, adds up to account takeover. Chaining is what turns medium findings into critical ones, and it is what our clients value most.

5. Reporting: the part the client pays for

Clients don’t buy “a pentest”. They buy knowing what risk they have and how to fix it. Every report we deliver has two levels:

  • Executive summary for leadership: a few pages, no jargon, with risk expressed as business impact (“any registered user can download any customer’s invoices”).
  • Technical findings for the development team, each with:
Field Content
Severity CVSS and in-context justification
Description What it is and where it is
Evidence Requests, responses and screenshots
Steps to reproduce Numbered and exact
Impact What an attacker can do
Recommendation How to fix it, with references (OWASP, CWE)

Afterwards we run a free retest: verifying that the fixes actually work is what closes the loop, and we deliver it with a verification letter.

What 27+ assessments have taught us

  1. Manual mapping pays off more than any scanner. The hours spent understanding the application come back many times over.
  2. Access control is the most common and most serious vulnerability we find. There is almost always at least one endpoint that doesn’t check who is making the request.
  3. A good report is worth as much as a good finding. If the team can’t reproduce it, it doesn’t get fixed.
  4. Automate the repetitive work (recon, validation), not the work that needs thinking.

In upcoming posts we’ll go deeper into each phase: our Bash and Python recon workflow, how we test access control in REST APIs, and the flaws that show up in almost every assessment.

Want to know how your application would hold up against this methodology? Request a quote and we’ll get back to you within 24 hours.

Elieser Hernández

Founder · Offensive pentester · Veritus Code

Offensive pentester specialized in web applications, APIs and infrastructure, following OWASP, PTES and MITRE ATT&CK. 27+ professional assessments and bug bounty.