In OWASP ZAP, what do a scan rule's `Plugin.AttackStrength` and `Plugin.AlertThreshold` each control?
answer
- two dials, not one setting
- one is about sending, one about reporting
- only one of them has an off position
- the engine passes them; the rule reads them
basics
~20 sAttackStrength sets how hard a rule tries: how many payloads and requests it spends per parameter. AlertThreshold sets how much evidence it demands before raising anything. They are separate dials, and only the threshold has an OFF value.
solid answer
~40 sBoth live on core's `Plugin` interface and both are set per rule by a scan policy. `AttackStrength` is the attack-side dial — `LOW`, `MEDIUM`, `HIGH`, `INSANE`, plus `DEFAULT` meaning *use the policy default* — and it governs how many payloads and requests a rule spends on each target. `AlertThreshold` is the reporting-side dial — `LOW`, `MEDIUM`, `HIGH`, plus `DEFAULT` and `OFF` — and it governs how much evidence the rule wants before it raises an alert. The asymmetry is real: `OFF` exists only on the threshold, which is why it doubles as the per-rule disable switch. Both are **advisory**: the engine hands them to the rule and enforces neither, so a rule that never reads them behaves identically at every setting.
code
java · 3 linespublic enum AlertThreshold { OFF, DEFAULT, LOW, MEDIUM, HIGH }
public enum AttackStrength { DEFAULT, LOW, MEDIUM, HIGH, INSANE }go deeper
Recall which dial is which: strength is about how hard the rule attacks, threshold is about how sure it must be before it reports. Do not swap them.
Explain the mechanics — the value sets, what DEFAULT defers to, and that the engine only hands the dials to the rule while the rule decides what to do with them.
Show you know the split is a design intent rather than an isolation guarantee: raising a threshold can remove whole check families and their traffic, while strength never moves the reporting bar.
Own the consequence for standardisation: because both dials are advisory and rule-dependent, a policy name is not a reproducible scan without a pinned add-on set.
## The two dials Core's `org.parosproxy.paros.core.scanner.Plugin` interface declares two nested enums, and every active scan rule carries one value of each. A scan policy is, in essence, a way of writing those two values down — once as a default for everything, and optionally again per rule. - **`AttackStrength`** — the *attack-side* dial. It is the rule's budget: how many payload variants it tries, how many requests it spends on each parameter, and in some rules which whole families of check it bothers to run. Turning it up finds more and costs more traffic and time. - **`AlertThreshold`** — the *reporting-side* dial. It is the rule's evidence bar: how confident the rule's own logic must be before it raises anything. Turning it up reports less. ## The values, and the one that exists on only one of them | | `AttackStrength` | `AlertThreshold` | |---|---|---| | ordinary values | `LOW`, `MEDIUM`, `HIGH`, `INSANE` | `LOW`, `MEDIUM`, `HIGH` | | the inherit value | `DEFAULT` — use the policy's default | `DEFAULT` — use the policy's default | | an off position | **none** | **`OFF`** | | applies to passive rules | no | yes — `PluginPassiveScanner` carries a threshold and no strength | `DEFAULT` is not a level. It means *defer to whatever the policy set as the default*, and `getAttackStrength()` / `getAlertThreshold()` resolve it before the rule ever sees it; the `incDefault` overloads exist for the UI, which does need to show the difference. `ScanPolicy` refuses `DEFAULT` as a policy-wide default outright, and its own exception text spells out the legal sets: the threshold must be *one of OFF, LOW, MEDIUM, or HIGH*, the strength *one of LOW, MEDIUM, HIGH, or INSANE*. The missing off position on the strength side is not an oversight. There is no such thing as a rule that runs but sends nothing; a rule you do not want is a rule you turn off, and the threshold's `OFF` is where that is expressed. The other asymmetry is the active/passive boundary. A passive rule never sends a request, so a strength would be meaningless for it — and indeed `PluginPassiveScanner` imports and stores only an `AlertThreshold`. One dial crosses the boundary; the other cannot. ## Both dials are advisory This is the part people are surprised by. The active scan engine does **not** enforce either value. `HostProcess` pushes the policy's defaults onto each rule instance and then runs it; nothing in the engine counts a rule's requests against its strength, and nothing filters a raised alert against its threshold. The rule itself reads its own dials, or it does not. Many rules do read them, and read them carefully — branching on `getAttackStrength()` to choose how large a payload list to walk, and on `getAlertThreshold()` to decide which checks are reliable enough to run. Rules that never call either method behave identically whatever you write in the policy. That is why the practical answer to "what does Insane strength do" is always *it depends which rules you have enabled*. ## The clean split is the intent, not a guarantee The textbook line — strength decides how many requests, threshold decides how sure — is the right mental model and it is how the enums are meant. It is not an isolation guarantee in the other direction. Because the threshold is simply an input to a rule's own logic, a rule is free to implement "be more sure" by *not running its noisiest checks at all*, and shipped rules do exactly that: raising a rule's threshold to `HIGH` can switch off whole check families and the requests they would have sent. So: 1. Raising the **strength** does not raise the reporting bar: it is not consulted when a rule decides whether it has seen enough. The rule tries more; it demands no more evidence. 2. Raising the **threshold** always raises the reporting bar, and frequently reduces traffic as a side effect — rule by rule, not as a contract you can plan capacity on. ## Where the values come from In a `.policy` file the policy-wide pair is `<scanner><level>` (threshold) and `<scanner><strength>`, with per-rule overrides under `<plugins>`. In an automation plan's `activeScan-policy` job they are `defaultThreshold` and `defaultStrength`, with per-rule `threshold` and `strength` entries under `rules`. The vocabulary differs between the two surfaces — the file says `level`, the plan says `threshold` — but they set the same enum on the same object.
- What does the `DEFAULT` member of each enum actually mean?Not a level — a deferral. It means *use whatever the policy set as the default*, and the plain `getAttackStrength()` / `getAlertThreshold()` accessors resolve it away before the rule sees it. `ScanPolicy` rejects `DEFAULT` as a policy-wide default, since there would be nothing left to defer to.
- If two teams both run a policy at Insane strength, why can their scans still differ wildly?Because strength is advisory. Only rules that read `getAttackStrength()` change behaviour, and which rules are installed depends on the add-on set on that machine. The same policy on two different builds is not the same scan.
- Does a passive rule have an attack strength?No. A passive rule never sends a request, so there is nothing for a strength to budget. `PluginPassiveScanner` carries an `AlertThreshold` only — the reporting dial crosses the active/passive boundary and the attack dial does not.
A metal detector has two knobs: how many sweeps you make over the ground, and how strong a signal must be before it beeps. Fewer sweeps does not mean fewer beeps - it means you walk over things you never hear.
saying these in an interview costs you the question
- Treats strength and threshold as two names for one setting
- Says setting strength to Off disables a rule
- Believes the engine caps a rule's requests at its strength
- Thinks DEFAULT is a level between Low and Medium
- Assumes raising the threshold cannot change how many requests are sent