skip to content

Which OWASP ZAP confidence value stops an alert being counted, and where does that show up?

level: seniorimportance: should knowfreq 42%

answer

  1. not a flag, a scale value
  2. the bottom rung means not real
  3. counts view returns a fifth key
  4. site tree skips it for highest risk

basics

~20 s

The bottom of the confidence scale, the value named False Positive. It is a confidence value rather than a flag, and consumers special-case it: such alerts drop out of the highest-risk figure, the default alert listing and the risk counts.

solid answer

~40 s

Marking a ZAP finding a false positive sets `confidence` to its lowest value — there is no boolean field for it. That one value is then read as "not real" rather than "barely sure", so it is special-cased everywhere: the site tree skips it when computing a node's highest risk, the per-site report fragment omits it, the `alerts` view hides it unless you ask, and `alertCountsByRisk` files it under a fifth **False Positive** key instead of its risk bucket. A High finding reclassified this way silently leaves the High count, which is why a shrinking count is not by itself evidence of a fix.

code

java · 12 lines
java
// AlertAPI, the alertCountsByRisk view: four risk buckets, and one that is not
    int[] riskCounts = new int[] {0, 0, 0, 0};
    int falsePositiveCount = 0;

    if (alert.getConfidence() == Alert.CONFIDENCE_FALSE_POSITIVE) {
        falsePositiveCount += 1;      // leaves its risk bucket entirely
    } else {
        riskCounts[alert.getRisk()] += 1;
    }

    // ...and the fifth key is a CONFIDENCE label, not a risk one
    counts.put(Alert.MSG_CONFIDENCE[Alert.CONFIDENCE_FALSE_POSITIVE], falsePositiveCount);

go deeper

for a junior

Know that false positive is one of the confidence values, not a separate switch. It sits at the bottom of the same scale that runs up through Low, Medium, High and Confirmed.

for a middle

Explain what the value does to consumers: it is read as "not real", so alerts carrying it are skipped by highest-risk calculations, the default listing and the report fragment rather than merely ranked last.

for a senior

Show that you know a risk summary is not purely a risk summary. Be able to explain a moved count to a team without guessing, and say why suppressions applied by hand do not survive a fresh session.

for a principal

The call to own is where suppression is allowed to live. Marks made inside a run are invisible to the next one, so if suppression matters to your gate it belongs somewhere durable and reviewable rather than in a session a person edited.

## The bottom of the confidence scale is not a degree of confidence In OWASP ZAP, marking a finding a false positive is not a flag, a tag, or a deletion. There is no boolean field for it anywhere on the alert. It is a **value on the confidence axis** — `CONFIDENCE_FALSE_POSITIVE`, the bottom rung, sitting below Low, Medium, High and Confirmed on the same scale. The desktop offers a one-click menu item that does exactly this and nothing else, and over the control API it is the plain "update confidence" action with the bottom value. That design keeps the alert's history intact — the risk value it was raised with is still on the object, and so is the rule that raised it — but it means one confidence value carries a meaning the other four do not. The other four say *how sure*. This one says *not real*. ## Consumers special-case it, and that is what changes your counts Because it means "not real", code all over the program branches on it explicitly rather than treating it as a low number: | where | what it does with a confidence-zero alert | |---|---| | the site tree's highest-risk calculation | skips it entirely when working out the worst alert on a node | | the per-site report fragment | leaves it out of the alert list altogether | | the `alerts` API view | omits it unless you pass the optional `falsePositive` parameter, which defaults to false | | the `alertCountsByRisk` API view | counts it under a **False Positive** key instead of its risk bucket | | the desktop alert list | swaps the risk-coloured flag for a plain OK icon, with a source comment saying there is no risk | | the `automation` add-on's exit-status job | skips it when deciding a run's outcome | The `alertCountsByRisk` row is the one that surprises people in a pipeline. The view's name says "by risk", and the risk scale has four rungs — but the map it returns has **five** keys. Four are the risk labels; the fifth is a *confidence* label. The bucketing is a plain if/else: if the alert's confidence is zero it goes to the False Positive key, **else** it is counted under its risk. So a finding raised at High that someone later marked a false positive does not appear in the High bucket at all. Two runs over the same target can report different High counts with no change to the application, because a person changed a confidence value between them. ## What this means for a run in CI Three practical consequences: 1. **Your summary is keyed on two axes, not one.** Four of the five buckets are risk buckets and one is a confidence bucket. If you sum only the risk buckets you are counting non-suppressed findings, which is usually what you wanted — but say so, because "total alerts" it is not. 2. **Suppression is session state, not configuration.** The mark lives on the stored alert. A fresh run with a fresh session starts with nothing marked, so a verdict that depended on suppressions applied by hand will not reproduce. 3. **Do not read a shrinking High count as an improvement** without checking whether the finding was fixed or reclassified. The two are indistinguishable in the count and distinguishable in the alert list. ## The mirror image at the top of the scale `CONFIDENCE_USER_CONFIRMED` is the same idea in the other direction, and it is worth naming for symmetry: it records that the finding **is** real. Neither end of the scale is ever set by a rule — measured across the shipped rule add-ons, rules raise only at Low, Medium and High — so either end appearing on an alert is evidence that something other than the detection itself put it there. Unlike the bottom value, though, it changes nothing downstream: a confirmed alert is counted under its risk exactly like a High-confidence one. The asymmetry is deliberate. Suppression has to be honoured by every consumer or it is not suppression; confirmation only needs to be recorded. So the honest summary of the two axes is: **independent at every value except one.** Risk says how bad, confidence says how sure, neither is derived from the other, and there is no blended score — but a confidence of zero overrides the risk on the way to almost every count and view that a pipeline reads.

  • Does marking an alert a false positive change its risk value?
    No. The risk field is left exactly as the rule set it, which is why the alert still shows its original band if you open it. Only the confidence value moves, and it is the consumers reading that value that stop counting the alert under its risk.
  • What sets `CONFIDENCE_USER_CONFIRMED`, and what does it change?
    A person does, through the desktop editor or the update-confidence action on the control API — no shipped scan rule raises at that value. Unlike the bottom of the scale it changes nothing downstream: a confirmed alert is still counted under its risk like any other.
  • Two runs against an unchanged application report different High counts. What should you check first?
    Whether anything was reclassified rather than fixed. A finding moved to the bottom confidence value leaves the High bucket without the application changing. Check the alert list rather than the counts, and remember that such marks live on the stored session, so a fresh session starts with none of them.

saying these in an interview costs you the question

  • Thinks the alert has a boolean false-positive flag
  • Says marking a false positive deletes the alert
  • Believes marking one lowers its risk band too
  • Assumes a counts-by-risk view is keyed only on risk
  • Reads a falling High count as proof of a fix