Guide 152 worked guide

How to map an ASVS requirement to code and deployment evidence

Map an ASVS requirement to source, configuration and runtime evidence, separating originating permissions from authorization changes and unresolved controls.

Start with the exact ASVS requirement text, then name the application behavior it governs. Trace that behavior through code, shared controls and deployed configuration; collect evidence for each step; and mark what remains unobserved. One source line or one scanner rule mapping is rarely enough. For a data-access requirement, the review needs the caller, object, authorization decision and every relevant path that returns the data. If deployment settings or runtime behavior determine the result, request that evidence separately. Your output is a dated requirement row with an evidence-supported conclusion, an open question or a candidate finding—not a percentage.

This guide works through one invented invoice API. The same method applies to other requirements, but the needed evidence changes with the control. Use the OWASP ASVS 5.0.0 catalog as the source of the requirement's wording and level; OWASP recommends versioned IDs because requirement numbers can change.

The requirement and the system boundary

Illustrative example: HarborLedger's customers view invoices through GET /api/invoices/{invoice_id} and download PDFs through GET /api/invoices/{invoice_id}/pdf. The team is examining v5.0.0-8.2.2, which concerns explicit permission to specific data items to address IDOR or broken object level authorization (OWASP ASVS 5.0.0). In plain language: can one customer obtain another customer's invoice merely by changing the ID?

The target boundary is the staging deployment that matches a specific API revision, worker revision and gateway configuration. The engineer has access to the source repository and a staging read-only configuration export, but has not yet been granted two test tenant accounts. That access limit matters: a code trace can identify a likely missing check, but it cannot be described as a successful cross-tenant request.

Step 1: turn the requirement into a testable claim

Write a statement specific enough to fail:

For both invoice read and PDF download, a signed-in customer can receive an invoice only if the trusted service layer establishes that the caller may access that invoice's tenant and object; a changed invoice ID does not bypass the decision.

The statement names the actor, action, object, security boundary and paths. It avoids treating “we have authentication” as an answer to an authorization question. Authentication tells the service who the caller is; it does not by itself decide which invoice the caller may read.

List the assumptions under it: invoices are tenant-owned; the route is deployed; the gateway forwards authenticated identity claims; the PDF worker's service identity may have wider data access than an end user. Ask the API owner to confirm each one. If a business policy allows a customer to share an invoice externally, add that documented exception and test its constraints rather than forcing every shared object into the same rule.

Step 2: draw the evidence path

Start at the entry point and follow each handoff to the returned bytes. For the read route, record:

  1. Caller and identity: session middleware, trusted token validation, tenant claim source and what happens when claims are absent or stale.
  2. Entry point: route declaration, handler and parameters. Look for alternate endpoints, GraphQL resolvers and internal RPCs that read the same object.
  3. Authorization decision: the exact server-side policy or guard that checks this caller against this invoice. A UI visibility rule is not sufficient; ASVS v5.0.0-8.3.1 calls for enforcement at a trusted service layer (ASVS catalog).
  4. Data access and effect: repository query, tenant predicate, cache key, object storage key and serialization. Check whether a failed decision blocks before any sensitive response.
  5. Other consumers: PDF worker, export job, support tooling and signed download link. The same requirement may need separate component rows.

Write down the file, immutable revision, function or configuration key for every observation. “Auth service exists” is weaker evidence than “the deployed read handler calls canReadInvoice(user, invoice) before returning bytes.” The latter still needs checks for bypass paths and the actual deployment. OWASP's secure code review guidance treats architecture, business logic and authorization as review concerns; follow the data rather than searching only for a function name.

Step 3: compare source with deployment

Source can describe intended behavior without proving it is active. Ask the platform owner for the deployed API and worker image digests, route map, gateway authentication setting and identity provider claim mapping for the assessed environment. Keep the date and environment with each artifact. If infrastructure as code is available, compare it to the current deployment or change record. A configuration file committed last month may not represent today's gateway.

For this example, the source appears to call canReadInvoice on the API read route. The PDF path passes the invoice ID to a worker that uses a service credential. The engineer needs to see whether the worker receives an authorized user-and-invoice decision or simply trusts that any caller with a valid session can request a PDF. A service credential that can read all invoices is not a substitute for preserving the originating user's permissions. ASVS v5.0.0-8.3.3 addresses access based on the originating subject where an intermediary service acts on their behalf (versioned catalog). That requirement has its own scope and level; do not silently claim it was assessed merely because it informed this trace.

Step 4: seek counterevidence before making a finding

An apparent missing tenant predicate may be enforced in a shared query helper, row-level database policy, gateway or service method. Conversely, a guard in the handler may be bypassed by an export route. Actively look for both kinds of evidence. Record the result of every countercheck, including “could not inspect” and why.

When authorized test accounts and a matching staging deployment are available, use a controlled negative test: create an invoice for tenant A, authenticate as tenant B, request the invoice through each in-scope path, and observe the response and server-side decision. Keep test IDs free of real customer data. A denied response supports the tested case; it does not prove all possible paths or future revisions. If the response succeeds, preserve the request, identity, route, environment and owner review before publishing a finding. This example does not claim such a test occurred.

If a discrepancy remains, phrase the candidate narrowly: “At revision api-7c2, the PDF endpoint appears to enqueue a worker read without carrying an invoice-specific authorization decision. The route's deployed behavior and worker policy are unverified.” A separate reviewer can attempt to defeat that claim with evidence of a downstream check. Until then, it is not a confirmed cross-tenant exposure.

Step 5: reject the reassuring artifact that belongs to another worker

Harbor receives the following synthetic evidence packet. These records are invented inputs to the mapping exercise, not a report of validation performed by the author.

Evidence ID Actual subject and content Claim it can support
E101 API api-7c2 mandatory invoice guard and scoped repository query Source enforcement on the JSON path
E104 Staging API deployment maps to api-7c2 The API source concerns this staging release
E105 Worker policy export dated earlier, bound to image W-old Historical worker control only
E106 Current staging deployment uses W-new E105 does not establish current worker policy
E107 Supplied synthetic denial record: tenant B receives no tenant A JSON body One staging JSON case, not PDF behavior

E105 initially looks like the missing PDF answer: it names the correct service and has an authorization rule. The image mismatch makes it insufficient for the current row. Retain it as rejected evidence with reason “wrong deployed worker subject,” rather than deleting it or treating its age alone as the problem. An older document can still be valid if its binding is demonstrated; here it is not.

The exact replacement request is: “Supply the policy and caller binding for W-new, including how the originating member and invoice scope reach the worker. A policy for the same service name on W-old cannot resolve this row.”

The owner returns E108, the W-new policy and caller trace, plus E109, a synthetic staging PDF denial/allowed-pair record for the same build. The packet supports the selected allowed/denied cases, but the requirement conclusion still depends on the authorization basis for those outcomes. That packet does not yet establish whether the decision uses the originating customer's permissions rather than the worker's own authority, so v5.0.0-8.3.3 remains inconclusive. Revocation freshness is a separate question under v5.0.0-8.3.2; record it as an additional obligation if included, rather than changing the meaning of 8.3.3.

Versioned obligation Before matching packet After E108/E109 Unchanged limit
v5.0.0-8.2.2, JSON staging path Source supported; E107 supplies one denial, positive case not supplied Same limited support; E108/E109 concern PDF only No complete JSON case pair, other object types or production
v5.0.0-8.2.2, PDF staging path Inconclusive; W-old evidence rejected Selected W-new case pair supported; requirement inconclusive pending originating-permission trace Production mapping absent
v5.0.0-8.3.3, worker originating authority Inconclusive Still inconclusive; originating-permission decision not established Do not inherit object-access result as a pass

The mapping improved without making every cell green. Each evidence item earns only the proposition it addresses, and the earlier state stays in the dated history. The real reviewer must check exact ASVS wording, evidence authenticity and method sufficiency before making the corresponding formal assessment decision.

Ask for evidence that answers the unresolved proposition

E108 and E109 narrow Harbor's missing work, but a request for “more authorization evidence” would still be too vague. The next request should ask how W-new chooses the authority for the invoice operation: which originating member is represented, where their permission is resolved, and how that decision is bound to the invoice and work item. The answer may be a caller trace, protected job record and mandatory accessor contract. A second screenshot showing a denial would not necessarily establish that basis.

Have the owner explain what the supplied artifact rules out. If it demonstrates that the worker cannot select an invoice outside the authorized job, record that proposition and its assumptions. If it merely shows a broad service role can read invoices, it answers a different question. A reviewer can accept a useful narrow artifact without promoting it to completion of the whole requirement.

This discipline also prevents waste. Do not ask platform to regenerate the entire staging configuration when the remaining question is in the job-admission contract. Keep the evidence request close to the smallest unresolved link, then update only the conclusions that link can support.

Decide when the mapping is complete enough

A reviewer may close a source review for a declared route once all named code paths and counterchecks have been examined. A conclusion that the requirement is satisfied for a deployed application needs the evidence the requirement actually demands across the stated environment and relevant paths. If runtime or provider settings are decisive and unavailable, the control conclusion remains inconclusive even if the code review is thorough. A partial result is still useful: it identifies exactly who must supply the next artifact.

For a customer, summarize the outcome and limits at the appropriate level, as OWASP's testing report guidance recommends for different audiences. For the engineer's next task, inspect the PDF worker's identity propagation and policy, then run the authorized two-tenant checks at the pinned deployment. For related decisions, see which controls source review cannot verify and how to report a partial assessment.