Imagine a hypothetical B2B ticketing service. It has a web interface, a public REST API for integrations, CSV report exports, a nightly background job that compiles summaries for managers, and a cache in front of some endpoints. Its customers are separate companies, and each works in its own tenant. Before a major release that introduces a new "organization administrator" role, the CTO asks for the application to be "checked for vulnerabilities". A scanner crawls the pages and returns a dozen remarks about headers. Yet the questions that matter most stay unanswered: can a user from one company obtain another company's report through the export, can an ordinary employee see fields intended for administrators, and does the cache serve someone else's data after a session changes?
The example is invented, but the gap it exposes is typical of how the task gets framed. Web application vulnerability testing is authorized, structured work: finding weaknesses an attacker could exploit, confirming how much they matter, and turning the results into fixes that have passed a retest. What follows is a practical sequence for people responsible for a product, its development or its security: what to include in scope, how to test roles and trust boundaries, where a scanner helps and where it cannot, and how to accept the result.
What a web application check actually covers
An assessment covers more than the pages a user sees. The OWASP Application Security Verification Standard (ASVS) describes itself as a basis for verifying an application's technical security controls, as well as the environment controls the application relies on. In practice, the scope conversation should include code and business logic, authentication and session management, APIs, HTTP-level configuration, and the supporting components the application depends on.
Asset inventory before the first request
Testing starts with a list, not a scanner. The team records domains and environments, the web interface and any mobile clients that use the same back end, public and internal APIs, export and import mechanisms, background jobs, queues, webhooks, caches and CDNs, third-party integrations and administration panels. It is worth noting separately which of these parts handle data from different customers and which roles reach them. Without such a list, an assessment checks what is visible and misses what is important.
The table below helps make a decision about each boundary before it enters the plan.
Scroll sideways to compare
| Boundary | Scoping decision | What testing must show | Risk if skipped |
|---|---|---|---|
| Visible web interface | Which roles and scenarios are walked through manually | The interface exposes no actions or data beyond the role's rights | The check reduces to confirming that buttons are hidden |
| Public and internal API | Which endpoints and versions are in scope, and whether a specification exists | Object, property and function authorization for every role | Bypassing the interface with direct requests stays untested |
| Exports and imports | Which formats, filters and parameters are in scope | The export applies tenant and permission checks exactly as the screen does | Data leaves through a file around on-screen restrictions |
| Background jobs and queues | Which jobs a user can trigger and whose rights they run with | The job does not mix tenant data or raise privileges | An isolation failure stays invisible in the interface |
| Caches and CDNs | Which responses are cached and under which key | Personal responses are not served to another user or tenant | Someone else's data arrives from the cache after a session change |
| Administrative functions | Whether support panels and operator roles are included | Administrator functions are unavailable to ordinary roles | Privilege escalation through a forgotten route |
Authorization and the edges of the engagement
Only systems you own, or systems whose owner has given explicit written permission, may be tested. A good plan names the applications, environments and interfaces in scope, the roles and test accounts, explicit exclusions, testing windows and emergency contacts. It also sets data-handling rules: whether production may be used, which actions are not allowed, and what to do if real personal data turns up. Acceptance criteria are worth writing down in advance as well; they are covered below.
Roles, authenticated states and trust boundaries
Many of the questions that matter to the business arise not on the login page but after it. An assessment should therefore cover not a single account but a matrix: an anonymous visitor, an ordinary user, a user with extended rights, a tenant administrator, a support operator role, and at least two independent tenants if the product is multi-tenant. For each role the state matters too: a freshly logged-in user, a user after a password change, after a role downgrade, after logout, and after session expiry.
A trust boundary is a point where data or control passes from a less trusted party to a more trusted one: from the browser to the server, from a partner integration into the API, from user input into a background job, from one tenant into shared storage. Each such boundary becomes a testing question: does the receiving side check what it got, or does it rely on a check having happened earlier?
Authentication is not authorization
Authentication answers the question "who are you"; authorization answers "what are you allowed to do with this specific object, field or function". A successful login says nothing about the second. A dangerous assumption is that if a user has logged in and the interface shows them only their own buttons, access is already restricted. The server must make an access decision on every request, based on identity, role and object ownership, not on the fact that the client did not render a link.
Tenant isolation beyond the visible API
In a SaaS product, tenant isolation is a subject of verification in its own right. It is not enough to confirm that a record-read endpoint returns an error for someone else's identifier. The same data can leave through an export where the tenant filter is implemented separately; through a background job that builds a report with system rights; through search or autocomplete suggestions; through a cache whose key ignores the user or tenant. In our hypothetical service, the export and the nightly summary are exactly the places where isolation logic may have been implemented anew, so they deserve a separate check under two tenants.
Three API authorization questions: object, property, function
The OWASP API Security Top 10 2023 separates several categories that are easy to blur in practice. Keeping them apart is useful, because each needs its own tests and its own fix. The order in which they appear below says nothing about prevalence or importance.
Object level and property level
Object-level authorization asks whether this user may work with this particular record: a ticket, an invoice, a file. The check consists of accessing, under one role and one tenant, an object that belongs to another user or tenant, and confirming that the server refuses, for every method: read, update, delete and export.
Property-level authorization is a subtler question: even when access to the object is allowed, may every one of its fields be read and changed? An API response may return internal fields that the interface simply does not display, and an update request may accept fields the user should not change: a role, a payment status, organization membership. The test compares what the role should see and change with what the server actually returns and accepts.
Function level
Function-level authorization concerns operations rather than data: may this role call this function at all? Administrative endpoints, bulk operations, user management and plan changes all need checking under every role, including roles for which the interface has no corresponding menu. In the hypothetical service, the new "organization administrator" role must be checked in both directions: does it get the functions it needs, and does it avoid getting the functions of support operators?
Resource consumption and sensitive business flows
Two other categories in the OWASP API Security Top 10 2023 are easy to confuse, although they are about different things. Unrestricted resource consumption means the API does not limit the volume, frequency or cost of requests: page size, the number of items in an export, heavy filters, calls to paid external services. Unrestricted access to sensitive business flows means a legitimate function can be used in an automated way and at a scale that harms the business: mass sign-ups, bulk purchasing, invitation spam, promo-code guessing. The first is a question of resources and cost, the second a question of business-process abuse, and their tests and defences differ. For a closer look at how such an assessment is built for APIs, see the guide to REST API security assessment.
Business logic a scanner cannot judge
Business logic is the set of rules that make a product a product: who may approve a ticket, when money is charged, how many times an invitation works, in what order checkout steps run. These rules are not described in the protocol, and a tool does not know what the correct behaviour should be. Weaknesses here are therefore found by a person who understands what a function is for and deliberately checks what happens when it is used the wrong way.
Workflow steps, limits and state transitions
The practical questions sound like this. Can a step be skipped, or steps performed in a different order? Can an operation that should run once be repeated? Are limits respected under parallel requests? What happens to an object moving from one status to another if a request arrives at an unexpected moment? Does the value the server recalculates match the one the client sent? Each such question is derived from the product description, so the tester needs documentation, test data and access to someone who can say what counts as correct. On scoping this work and choosing a provider for it, see the article on business logic security testing.
HTTP controls, sessions and browser policies
The HTTP layer is a good starting point: checking it is low-risk and quickly shows how carefully the application is configured. But it is a starting point, not the result.
Session state is an application design decision
HTTP as a protocol does not tie requests to one another: each request carries what is needed to process it. The application adds state, most often through a cookie holding the identifier of a session whose data the server stores, or through tokens. Ordinary server-side sessions over HTTP are standard practice. What gets tested, therefore, is not the protocol but how the application creates, binds, refreshes and ends a session: does the identifier change after login, is the session invalidated on logout and password change, is its lifetime limited, do cookies carry the Secure and HttpOnly attributes and a suitable SameSite value, and does an old token keep working after a role downgrade?
Headers as evidence, not proof
Modern browsers offer mechanisms that an application must configure correctly. Content Security Policy defines which resources a page may load and helps mitigate XSS and data injection. CORS controls how a site responds to cross-site requests, and an overly broad policy combined with credentialed requests can expose responses to a foreign origin. Cross-Origin Resource Policy protects resources from certain cross-site loads, and Permissions Policy restricts the browser features available to page code. Error handling deserves a check as well: are responses consistent, and do they reveal too much? Even so, a header being present does not prove security. A strict CSP will not fix an authorization flaw, and a correct CORS policy will not protect an export that ignores the tenant.
Scanning breadth, manual depth and confirmed consequences
NIST's technical guide to security testing, SP 800-115, treats vulnerability scanning, penetration testing and security assessment as related but distinct activities and stresses that each technique has benefits and limitations. For web applications this distinction has direct practical meaning.
What each approach can and cannot show
Automated scanning provides breadth: it moves quickly and repeatably across many pages, parameters and versions, finds known configuration problems and common classes of input-handling errors. It suits frequent checks within the delivery process. Its limit is intent: a scanner does not know whether user A should see user B's ticket, and it does not understand that an approval step must not be skipped. Its results need triage, otherwise the report fills up with false positives.
Manual testing provides depth: a specialist walks through roles and tenants and checks object, property and function authorization, business processes, background jobs and exports. It is slower and depends heavily on skill, so coverage has to be planned rather than assumed.
Confirming realistic consequences answers a third question: can the weaknesses found be chained, within agreed boundaries, into an outcome that matters to the business, such as reading another tenant's data? This is a point-in-time snapshot, and such work is done only within the authorization, with minimal impact and without leaving scope.
Combining approaches in one assessment
A sensible sequence looks like this: scanning covers breadth and clears the obvious, manual work goes into roles, trust boundaries and logic, and consequence confirmation is applied where the business needs to see the real significance of a finding. In the hypothetical service, the scanner helps with headers and known component issues, while the questions about the export, the nightly summary and the cache require manual checks under two tenants. No approach replaces another: they answer different questions.
The roles of Top 10, ASVS and WSTG
Confusion about standards easily leads to a vague scope. Each document has its own job.
The OWASP Top 10 is an awareness document about the most critical web application risks. It gives developers, managers and executives a shared vocabulary and works well for training. A contract or test plan built only on the Top 10, however, will be less precise than one that cites specific requirements.
Versioned ASVS requirements as acceptance criteria
ASVS was designed to normalize the coverage and rigour of verification, so it answers well what "verification complete" should mean. A team selects the requirements that apply to its architecture and records a result for each: passed, failed or not applicable. A requirement identifier consists of chapter, section and requirement numbers, and the project warns that these numbers may change between versions. The version is therefore stated explicitly: for example, v5.0.0-1.2.5 is the fifth requirement in the Injection Prevention section of the Encoding and Sanitization chapter of version 5.0.0. An identifier without a version becomes ambiguous as the standard evolves. Requirement lists are available in machine-readable formats, including CSV and JSON, which makes it easy to load them into a tracker and compare results between releases.
WSTG as testing guidance, CWE as root-cause language
The OWASP Web Security Testing Guide describes how to test individual areas of a web application: authentication, authorization, session management, input handling and business logic. It is methodology guidance, not an acceptance criterion. The MITRE CWE catalogue helps describe findings at the level of root cause: when every confirmed issue is mapped to a CWE entry, a whole class of defects can be eliminated rather than a single instance. NIST SP 800-115 is useful for process structure, covering planning, execution, analysis and mitigation, while web-specific techniques are best taken from current OWASP material, since the NIST document was published in 2008.
Evidence, prioritization and retest
Testing creates value at the final stage, when a finding becomes a fix confirmed by a retest.
What a usable finding contains
A finding a developer can work with includes the role and tenant under which it reproduces; the exact request and response, or the steps in the interface; the affected objects, fields or functions; the observed result and the expected behaviour; a reference to a CWE entry and a versioned ASVS requirement; and an assessment of consequences in the context of this specific product. Raw scanner output without triage is not a finding but material for analysis.
How to set priorities
A sensible triage rule rests on three inputs: the technical severity of the weakness, evidence of real-world exploitation of that weakness class, and the impact on the specific asset. MITRE publishes lists of the most dangerous weaknesses, as well as weaknesses linked to the CISA Known Exploited Vulnerabilities catalog, which helps with the second input. None of these sources prescribes a single formula, so an organization should write down its own rule and apply it consistently. For a multi-tenant product, a tenant isolation failure generally deserves high priority because of its business impact, even if it looks technically simple.
Retest and closure
A fix is not considered confirmed until it has been checked in the same way the problem was found, and until the neighbouring paths have been shown to be closed too. For an authorization flaw, this means repeating the request under the same role and the same tenant, then checking related methods, the export, the background job and the cache. For a detailed look at proving that fixes actually work, see the article on penetration test remediation validation.
Scroll sideways to compare
| Check | Acceptance evidence | Retest action | When to treat as closed |
|---|---|---|---|
| Object-level authorization | Requests under two roles and two tenants with server responses | Repeat the original request and every method for the same object | The server refuses on every method and returns no data |
| Property-level authorization | Comparison of the fields a role should see and change against actual ones | Send a request with forbidden fields for reading and updating | Extra fields are neither returned nor accepted |
| Isolation in exports and background jobs | A file or report generated under one tenant's role | Generate the export and run the job again with the same parameters | The output contains only the tenant's own data |
| Caching of personal responses | A response received by another user or after logout | Repeat the sequence with a session change and a tenant change | The cache serves no foreign or stale personal response |
| Session lifecycle | Token behaviour after logout, password change and role downgrade | Repeat the actions and test the old identifier | The server rejects the old session |
| ASVS requirement | A result recorded against the versioned requirement identifier | Re-verify the requirement after the fix | Status "passed" with evidence attached |
- ConfirmReproduce the issue with the recorded role, tenant and request
- FixRemove the root cause on the server instead of hiding an interface element
- RepeatRun the original check in the same way and with the same data
- Neighbouring pathsCheck related methods, the export, the background job and the cache
- CloseRecord the evidence and the residual risk in the tracker
How to buy a web application assessment
The ASVS aim of normalizing coverage and rigour works in the buyer's favour: the standard offers a common yardstick for comparing proposals that would otherwise describe their work in incompatible terms. CISA's Secure by Demand guidance rests on the same principle of asking suppliers for verifiable evidence. It is written for product procurement, but it applies equally to security testing services.
Questions to ask a provider
- Which ASVS version and which requirements will be verified, and how will the result for each one be reported?
- Which roles, tenants and authenticated states will manual testing cover?
- Are APIs, exports, background jobs and caches in scope, not just the visible interface?
- Which WSTG areas are covered manually, and which checks are automated?
- How are scope, test accounts, exclusions and written authorization documented?
- Will every finding be mapped to a CWE entry and a versioned ASVS requirement and come with reproduction evidence?
- Is a retest included, and how is residual risk documented?
- How are sensitive data and production stability protected during the work?
Warning signs include a report made up mostly of scanner output, findings without root-cause or requirement references, no retest, and no defined authorization procedure. Any claims a provider makes about certification or past results are worth verifying independently.
What a pentest result is and is not
A penetration test is a snapshot of security within an agreed scope at a given moment. It shows which weaknesses were found and confirmed, how they connect, and what was fixed after the retest. A pentest is not a certification, an attestation or an assurance opinion, and it cannot guarantee the absence of vulnerabilities. Changes to code, configuration and integrations after the test create new surface, so lightweight automated checks are worth building into delivery, while deep manual assessment is worth repeating before major releases and after significant architectural change; the exact cadence is the organization's own decision. If application testing needs to connect to a broader programme, from architecture to development processes, the guide to application security audit is a useful next step.
For the hypothetical service from the opening, the result of a good assessment would not be a list of headers but an answer to the original questions: are tenants isolated across the API, the export, the nightly summary and the cache, do the new role's rights match the intent, and which fixes have been confirmed by a retest. Pentest.red can help define such a scope and carry out an authorized assessment; a convenient starting point is to describe your pentest scope, covering systems, roles, access and constraints.
PENTEST.RED
Discuss pentest scope and pricing
We start by agreeing on systems, access, constraints and the expected evidence.
Based on in-depth research, edited for clarity and practical use.