skip to content

What does ZAP's Control.Mode setting restrict, and which value does a headless run start in?

level: middleimportance: must knowfreq 60%

answer

  1. the switch that can refuse a scan
  2. stored in the view namespace
  3. its default is the unrestricted value
  4. nothing shipped for automation sets it
  5. -config view.mode= at start

basics

~20 s

Control.Mode takes safe, protect, standard or attack, and is persisted under the key view.mode with standard as its default. A headless run gets standard — unrestricted — because nothing ZAP ships for automation ever sets it.

solid answer

~40 s

Core's `Control.Mode` has the values `safe`, `protect`, `standard` and `attack`. `safe` refuses to start a scan at all; `protect` starts a scan only if its start node is already in scope; `standard` is unrestricted; `attack` is unrestricted and additionally queues each newly discovered in-scope node for active scanning. The setting is persisted as **`view.mode`** and defaults to `standard`. `-cmd` and `-daemon` do not touch it, and neither the packaged wrapper scripts nor the `automation` add-on set it — so every unattended run is unrestricted. It is still an ordinary configuration key: `-config view.mode=protect` at start, or the `core` component's `setMode` action on a running instance.

code

bash · 7 lines
bash
# Nothing ZAP ships for automation sets view.mode, so a headless
# instance runs as 'standard' - unrestricted - unless you say otherwise.
zap.sh -daemon -config view.mode=protect

# 'protect' admits a scan only when its START node is already in scope.
# It does not filter the requests an admitted scan then sends, and it
# does not stop the proxy forwarding traffic on behalf of a browser.

go deeper

for a junior

Recall the values — safe, protect, standard, attack — and the one that matters most: the default is standard, which restricts nothing.

for a middle

Explain that the setting is persisted as view.mode, that -cmd and -daemon leave it alone, and that attack adds automatic scanning of newly in-scope nodes rather than merely permitting scans.

for a senior

Show you know the absence as well as the mechanism: nothing under the shipped automation paths sets it, so an unattended run is unrestricted unless your own start options change that.

for a principal

Weigh whether a restricted mode belongs in your standard job template at all, given that it constrains scan admission only and leaves the proxy path untouched.

## The setting, and where it lives `Control.Mode` is declared in core, on `org.parosproxy.paros.control.Control`, with the values `safe`, `protect`, `standard` and `attack`. It is the only control in the program that can refuse to run a scan at all — the only switch whose purpose is to make ZAP do *less* to a target than it otherwise would. What matters about it, more than the list of values: - **It is persisted in the `view` options namespace, under the key `view.mode`**, read on `OptionsParamView`. `Control.getMode()` reads that key through the options model and caches the result. The namespace is not cosmetic — it is a plain statement of which audience the feature was built for. - **Its default is `standard`**, set where the option is loaded. `standard` is the unrestricted value. ## What each value does | value | effect at a scan-start gate | what else changes | |---|---|---| | `safe` | a scan start is refused outright | nothing stops the proxy forwarding traffic | | `protect` | a start is refused unless its start node is already in scope | the check is on the start node only | | `standard` | no restriction | the default, and what every unattended run gets | | `attack` | no restriction | an attack-mode scanner queues each newly discovered in-scope node for active scanning | `standard` and `attack` are indistinguishable **at the gate** — both fall straight through the switch. They differ in what happens afterwards: in `attack`, an attack-mode scanner subscribes to site-tree events and pushes every newly added in-scope node onto a stack to be actively scanned, so merely browsing through the proxy starts attacks. It is the most aggressive value, not a synonym for `standard`. ## The asymmetry that matters for a pipeline When the active-scan extension initialises and finds the mode already set to `attack`, it reverts to `standard` — but only when a view exists. The guard is conditioned on there being a desktop window, and the source comment says as much: attack mode is disabled "for safeties sake (when running with the UI)". A headless instance started in `attack` keeps it, and the attack-mode scanner starts with no prompt. So the program's self-protective downgrade protects the desktop user and not the pipeline. That is the shape of this whole feature. ## Nothing shipped sets it The decisive measurement is an absence, and it is worth stating with its scope attached: `view.mode` is set by **nothing under the core repository's `docker/` directory and nothing under the `automation` add-on**. The wrapper scripts do pass configuration at start — database, API-key and statistics keys — but never this one. The automation framework does not either; its extension implements the mode-changed listener as an explicit no-op, as do the proxy add-on and the passive-scan add-on. The honest form of the claim is therefore *nothing shipped sets it*, **not** *nothing can*. It is an ordinary configuration key, and it is set the way any other is: 1. **At start**, with core's `-config` option: `-config view.mode=protect`. `-config` puts an arbitrary key/value pair over the persisted configuration, so this works headless. 2. **At runtime**, through the `core` component's `setMode` action on a running instance, with the matching `mode` view to read it back. Neither happens unless you do it. Every unattended run is `standard` — unrestricted — because that is the default and because no packaged path changes it. ## The lifetime flags do not touch it `-cmd` and `-daemon` decide how long the process lives and whether a window opens. Neither reads, writes or implies anything about `view.mode`; the bootstrap classes contain no reference to the mode at all. A headless run is not a more cautious run. It is the same unrestricted `standard` with nobody watching. What follows is worth carrying into an interview: - a run's mode is whatever the persisted configuration says, and by default that is unrestricted; - setting it is cheap, and nothing will set it for you; - reading it back later is possible on a live instance and impossible after the process exits. ## How to answer this Name the values, name the key, name the default, and then say the part that is actually interesting: the control that limits offence is stored under `view`, is off by default, and is set by nothing the project ships for automation. A candidate who stops at the list of values has described a feature; a candidate who adds the default and the absence has described the risk.

  • Why is the mode stored under the `view` options namespace?
    Because it was built as a desktop control, and the namespace records that. The consequence is the interesting part: the switch that limits what ZAP will do to a target lives among the settings an automated path never reads or writes, which is why every wrapper and plan run inherits the unrestricted default.
  • Are `standard` and `attack` the same thing?
    Not at all. They behave identically at the scan-start gate — both fall through with no check — but `attack` additionally runs an attack-mode scanner that watches the site tree and queues every newly added in-scope node for active scanning. Browsing through the proxy then starts attacks on its own.
  • Does `-daemon` make a run safer than a desktop session?
    The opposite, if anything. The bootstraps do not touch the mode, so a headless run is plain `standard`. And the self-protective downgrade in the program — reverting `attack` to `standard` at start-up — is conditioned on a view existing, so it fires for the desktop user and not for the pipeline.

saying these in an interview costs you the question

  • Says a headless or daemon run defaults to a restricted mode
  • Treats standard and attack as equivalent because both start scans
  • Claims the mode cannot be set outside the desktop at all
  • Thinks the wrapper scripts or automation plans set the mode for you
  • Calls safe mode a kill switch that stops all outgoing traffic