skip to content

In a ZAP active scan, which parts of a request may rules change by default, and which are left alone?

level: middleimportance: must knowfreq 62%

answer

  1. three parts in, three parts out
  2. it is a bitmask, not a policy entry
  3. config job, not policy job
  4. TARGET_INJECTABLE_DEFAULT omits the cookie

basics

~20 s

By default a ZAP active scan may change query-string parameters, post-data parameters and a plain request body. Cookies, HTTP headers and URL path segments are left alone: TARGET_INJECTABLE_DEFAULT omits them, and no scan policy can add them.

solid answer

~40 s

Core's `ScannerParam` holds the attackable request parts as a bitmask, and `TARGET_INJECTABLE_DEFAULT` is `TARGET_QUERYSTRING | TARGET_POSTDATA | TARGET_PLAINBODY`. Constants for cookies, HTTP headers and URL path segments exist, but they are not in that default, so an out-of-the-box active scan never puts a payload in a cookie. What changes it is the automation plan's `activeScan-config` job, under its `inputVectors` block (`cookieData.enabled`, `httpHeaders.enabled`, `urlPath`), or the raw config key `scanner.injectable`. It is deliberately not on the policy: a `.policy` file and the `activeScan-policy` job carry only which rules run, their attack strength and their alert threshold. So enabling every rule at maximum strength still leaves a cookie-borne bug unreachable, because no rule is ever handed that cookie as a parameter it may modify.

code

yaml · 7 lines
yaml
- type: activeScan-config
    inputVectors:
      cookieData:
        enabled: true
      httpHeaders:
        enabled: true
        allRequests: true

go deeper

for a junior

Remember the shipped set: query string, post data, plain body. Cookies, headers and path segments are off until someone turns them on.

for a middle

Be able to say it is one bitmask on ScannerParam, that the plan key is the activeScan-config job's inputVectors block, and that the policy has no say in it.

for a senior

Show the diagnostic: given a missed cookie bug and a fully-enabled policy, go to the vector set rather than the rule list, and say what the report should have recorded.

for a principal

Own the standard: which vectors unattended runs enable everywhere, who may widen them on which targets, and how coverage is stated so a clean result is not read as a guarantee.

## The setting is a bitmask in core, not a policy entry An **active scan** in ZAP is a rule sending modified copies of a recorded request and judging the responses. *Which part of that request a rule may modify* is a single setting, held in core's `org.parosproxy.paros.core.scanner.ScannerParam` as an integer bitmask and persisted under the config key `scanner.injectable`. `ScannerParam` declares one constant per request part — `TARGET_QUERYSTRING`, `TARGET_POSTDATA`, `TARGET_COOKIE`, `TARGET_HTTPHEADERS`, `TARGET_URLPATH`, `TARGET_PLAINBODY` — and then one constant for what ships enabled: ```java public static final int TARGET_INJECTABLE_DEFAULT = TARGET_QUERYSTRING | TARGET_POSTDATA | TARGET_PLAINBODY; ``` Three of the six parts are in. Three are not, and the ones that are not are exactly the ones people assume are covered. ## What is in the default set, and what is not | request part | `ScannerParam` constant | in the shipped default | `activeScan-config` key | |---|---|---|---| | query-string parameters | `TARGET_QUERYSTRING` | yes | `urlQueryStringAndDataDrivenNodes.enabled` | | parameters parsed out of the body | `TARGET_POSTDATA` | yes | `postData.enabled` | | a body with no parameters in it | `TARGET_PLAINBODY` | yes | *none — the job has no key for it* | | cookies | `TARGET_COOKIE` | no | `cookieData.enabled` | | HTTP request headers | `TARGET_HTTPHEADERS` | no | `httpHeaders.enabled` | | URL path segments | `TARGET_URLPATH` | no | `urlPath` | ## Why a policy cannot rescue you This is the sentence to have ready in an interview, because it is where the two settings get confused. Take a real shape: a session cookie whose value is read into a database predicate. - Enable **every** active rule. Set each one's **attack strength** as high as it goes and its **alert threshold** as low as it goes. - Read a shipped `.policy` file, or the `activeScan-policy` job's `policyDefinition`. Both carry a policy name, a default strength, a default threshold, and a per-rule list of the same two dials. **Neither carries any notion of a request part.** - So the fully-enabled policy changes *how hard* each rule pushes on the parameters it is handed, and changes nothing about *which* parameters it is handed. The cookie is never in that list, so the bug is never reached, and the scan finishes clean. That is a configuration fact, not a limitation of the rules. The cookie-borne bug is found the moment `cookieData.enabled` is true and not one moment earlier. ## The part of the path the default set does touch One nuance keeps the claim honest. When the query-string bit is on and the URL-path bit is off — which is exactly the shipped default — the engine also builds a **data-driven-node** path variant. A data-driven node is a path segment you have marked in a context as a *value* rather than a structural name, so that `/user/alice/profile` and `/user/bob/profile` collapse to one node in the site tree. Those marked segments become parameters; every other segment does not. So the precise claim is: *path segments are not attacked by default unless you have declared them data-driven.* The plan key is named `urlQueryStringAndDataDrivenNodes` for that reason — one key, two behaviours. ## Turning a vector on, and where you may do it 1. **In a plan** — an `activeScan-config` job with an `inputVectors` block. This is the path a CI run should use, because the plan is the artefact under review. 2. **At startup** — `-config scanner.injectable=<mask>`, an integer. It works, it is unreadable at a glance, and any `activeScan-config` job later in the plan rewrites it. 3. **Over the control API** — `ExtensionActiveScan` registers `ScannerParam` as API options, so every setter becomes an `ascan` option action, including the injectable mask. 4. **On the desktop**, in the active-scan options panel and in the custom-scan dialog. None of those four is the policy, and that is the whole point. ## What a pipeline owner should take away - A green active scan means *the rules found nothing in the parts of the request they were allowed to change*. It is not a statement about cookies or headers. - Widening the vector set changes the traffic you send to the target, so treat it as a scoped decision on a system you were permitted to test, not a dial to max out. - If your report does not record which vectors were enabled, nobody reading it later can tell a clean result from an unasked question.

  • A report says the active scan was clean. What must it also record before that is meaningful?
    The enabled input vectors, alongside the policy. Two runs of the same rules against the same target return different findings depending on whether `cookieData` and `httpHeaders` were enabled, so the vector set is part of the result, not part of the setup.
  • Does enabling the httpHeaders vector cover the cookie as well?
    No. The header variant carries a deny-list of headers it refuses to modify, and `Cookie` is on it, with a source comment saying the cookie has its own variant. `Authorization`, `Content-Length`, `Connection` and the CSRF-token headers are excluded the same way.
  • Why is a plain body a separate vector from post data?
    `postData` covers bodies the engine can parse into named parameters — form-encoded, JSON, XML, multipart. The plain-body variant is narrower: it offers the entire body as one unnamed value, and only when the request carries no `Content-Type` header at all or declares `text/plain`.

A locksmith you hired to test the front and back doors will report both sound. The window was never on the list, and their clean report is not a claim about it.

saying these in an interview costs you the question

  • Thinks enabling every rule makes the scan cover every request part
  • Says input vectors are configured in the scan policy
  • Assumes cookies are attacked because passive rules report on them
  • Believes the URL path is scanned whenever the query string is
  • Treats a clean active scan as evidence the cookie is safe