Most web application penetration tests fail in the scoping call, not the exploitation phase. You agree a flat fee, hand over a URL, and receive a report full of TLS configuration notes while the broken access control that actually matters goes untested.
This guide walks through how a web application penetration test runs end to end: what you scope, which classes of flaw get tested, what the tester needs from you, and how to read the report you get back.
Start from the current OWASP Top 10, not the one you remember
The OWASP Top 10 was updated in 2025. If a proposal or report references the 2021 list, that is a useful signal about how current the tester's methodology is.
The 2025 list reads:
Three changes matter when you scope a test.
Software Supply Chain Failures at A03 is broader than the old "Vulnerable and Outdated Components". It covers your build pipeline, your dependency resolution and your distribution process, not just the version numbers in your lockfile. A test scoped only to the running application will not touch it.
Security Misconfiguration moved up to A02. This is the category that rewards environment access. A tester working purely from the outside will find a fraction of what a tester with a staging environment and configuration visibility will find.
Mishandling of Exceptional Conditions is new at A10. Error paths, failure modes and partial states. These are hard to reach without knowing how the application is meant to behave, which is an argument for giving your tester documentation rather than making them guess.
Decide what kind of test you are buying
The phrase "penetration test" covers three quite different exercises, and the difference is how much you tell the tester.
Black box tests are popular because they feel like a realistic attack. They are also the least efficient way to find flaws in your own application, because your tester spends a third of the engagement rediscovering things you already know.
If this is your first test, a grey box engagement usually returns more findings per day spent. Save black box for when you want to test detection and response rather than the application itself.
Scope by function, not by URL
A scope that reads "test https://app.example.com" is not a scope. The tester has to guess which functionality matters, and they will guess wrong in both directions: too little coverage of your business logic, too much time on your marketing pages.
Scope by what the application does:
- Authentication and session handling. Login, logout, password reset, multi-factor enrolment, session expiry, and every alternative route in. The alternative routes are where the flaws usually are.
- Authorisation boundaries. List every role you have, then every pair of roles that should not be able to see each other's data. This is where A01 findings come from, and it is the single most valuable thing you can hand your tester.
- The money path. Checkout, subscription changes, refunds, credit transfers. Anything where a logic flaw converts directly into financial loss.
- Data entry points that reach other systems. File upload, imports, webhook receivers, anything that gets parsed downstream.
- Administrative functionality. Usually the least tested part of an application and the most valuable to an attacker.
- Integrations and third-party components. Your A03 exposure lives here.
Write this list yourself before you speak to a vendor. It changes the conversation from "how many days do you want" to "here is what needs covering, how long does that take you".
What the tester needs from you
An engagement stalls for predictable reasons, and nearly all of them are avoidable.
Credentials for every role, created in advance. Two accounts per role, so the tester can attempt horizontal privilege escalation between two users at the same level. Asking for these on day one costs you a day.
A test environment that mirrors production. If you test production you will be constrained about what you can attempt, which narrows the findings. If you test an environment three releases behind, the findings may not apply.
Rate limiting and WAF rules relaxed for the tester's source addresses. Otherwise you are testing your WAF, not your application. Test the WAF separately if you want to know how it performs.
Documentation. API specifications, an architecture diagram, a list of third-party integrations. Every hour a tester spends reconstructing your architecture is an hour not spent testing it.
A named contact who can answer questions within the day. Testers hit ambiguities constantly: is this behaviour intended, does this account have elevated rights, should this endpoint be reachable. Slow answers turn into assumptions, and assumptions turn into either false positives or missed findings.
How the test runs
A web application penetration test follows the same broad shape regardless of vendor, and knowing it helps you tell a thorough engagement from a scan with a report attached.
The proportion that matters is manual to automated. Automated scanning finds known vulnerability classes in known places. It does not find business logic flaws, authorisation gaps between roles, or chained weaknesses where three low-severity issues combine into one critical.
Ask any prospective vendor what share of the engagement is manual. Then ask what their scanner found on the last engagement and what their testers found by hand. The ratio tells you what you are buying.
Authorisation testing deserves its own conversation
Broken Access Control has sat at A01 across multiple revisions of the Top 10, and it is the class of flaw that automated tools handle worst.
The reason is straightforward. A scanner can tell that an endpoint returns data. It cannot tell that the data belongs to a different customer, because it does not know who owns what. Only someone who understands your domain model can make that call.
For this to be tested properly your tester needs:
- Every role enumerated, including the ones that exist only in configuration
- Two accounts per role, so same-level access can be tested
- A statement of which objects belong to which tenant or user
- Any endpoint that changes behaviour based on a role claim in a token
If a proposal does not mention authorisation testing explicitly, assume it is not being done properly.
From our work
A second pattern worth naming: findings cluster in the parts of the application built earliest, before the team settled on conventions, and in the parts built most recently, before those conventions were applied consistently.
Neither observation is a substitute for testing your own application. They are offered as a prompt for where to look first when you read your own report.
Reading the report
A report is useful in proportion to how reproducible it is. For each finding you should be able to answer:
Can I reproduce it? The report must contain the exact request, the exact parameters and the observed response. "The application is vulnerable to IDOR" is not a finding, it is a category.
What is the actual impact here? Severity ratings are generic. A high-severity finding on an internal admin tool behind a VPN may matter less to you than a medium on your public checkout. Ask the tester to rate impact in your context, not just against a scoring framework.
What is the fix, specifically? "Implement proper access control" is not remediation guidance. "Check tenant ownership in the handler for GET /api/v2/invoices/{id} before returning the record" is.
Was this chained? Individually low findings that combine into a critical path should be reported as the chain, not as three separate low findings that a triage process will deprioritise.
Insist on a retest after remediation, and agree its scope when you sign the original engagement rather than negotiating it afterwards.
Common scoping mistakes
Testing only the production environment, with restrictions. You get a constrained test and call it a clean bill of health.
Excluding authenticated functionality to save money. Most of your risk is behind the login. An unauthenticated-only test covers the smallest and best-defended part of your attack surface.
Scoping a single application when the risk is in the integration. If your application trusts a partner system, and that trust is misplaced, neither application's individual test will find it.
Treating the report as the deliverable. The deliverable is the remediation. Budget engineering time for fixes in the same planning cycle as the test, or you will hold a report describing flaws you have not fixed, which is worse than not having tested.
Frequency and triggers
Annual testing is the usual baseline for compliance. It is rarely the right frequency for engineering risk.
Test when something material changes: a new authentication mechanism, a new payment flow, a significant architectural change, a move to a new cloud provider, or a new third-party integration handling sensitive data. Continuous or quarterly testing suits teams shipping weekly; an annual test on a codebase that changed entirely during the year tells you about an application that no longer exists.
If you want a view of what a test would cost before you scope one, our penetration testing costs guide sets out the ranges and what drives them, and our penetration testing tools guide covers what testers actually run.
If you would like help scoping a web application penetration test against your own architecture, talk to our security testing team.