skip to content

Report Templates

A report is a template folder rendered over whichever alerts survive your cut-offs, so format, sections and the scores included are all choices. Interviewers ask who the report is really for.

on this pageshow

questions

5

In a ZAP report job, where do the risks, confidences and sections lists sit, and what do they default to?

level: middleimportance: must knowfreq 55%

answer

  1. two levels in one job
  2. the lists sit beside parameters
  3. absent means include everything
  4. a typo narrows, it does not widen

basics

~10 s

They are job-level keys, siblings of parameters rather than entries inside it. Omit any one and the report includes everything that key could filter: every risk, every confidence band, every section the template declares.

solid answer

~40 s

A `report` job has two levels. Under `parameters:` sit the presentation and destination settings - `template`, `theme`, `reportDir`, `reportFile`, `reportTitle`, `reportDescription`, `displayReport`. Beside `parameters:`, at the job's own level, sit the four lists that decide *content*: `risks`, `confidences`, `sections` and `sites`. Indent one of those under `parameters:` and it stops being a filter. Each list defaults to everything when the key is absent, so an unfiltered report carries every risk and every confidence band, the lowest one included. An entry the job does not recognise is a warning that contributes nothing - which means a list of nothing but typos produces an empty report rather than a full one.

code

yaml · 11 lines
yaml
- type: report
  parameters:
    template: risk-confidence-html
    theme: original        # presentation only, never content
    reportFile: audit-example-com
  risks:                   # job level, NOT under parameters
    - high
    - medium
  confidences:
    - high
    - confirmed            # accepted, but missing from the shipped example

go deeper

for a junior

Learn the indentation: template and theme go under parameters, while risks, confidences, sections and sites sit beside it at the job's own level.

for a middle

Explain the defaults and the failure mode - absent means everything, an unrecognised entry means nothing, so a typo makes the report narrower rather than wider.

for a senior

Diagnose an empty report from the plan alone: bad filter entries, the plan's contexts, and substring matching on sites all narrow the output for different reasons.

for a principal

Decide what your organisation's reports are allowed to omit and who gets to change that list, given that the filtered document is what most readers will ever see of a run.

## Two levels in one job The `report` job is one of the few automation jobs whose important settings are not all in `parameters:`. It reads two different places, and the split is meaningful rather than accidental: | where | keys | what they decide | |---|---|---| | under `parameters:` | `template`, `theme`, `reportDir`, `reportFile`, `reportTitle`, `reportDescription`, `displayReport` | which document, what it looks like, where it lands | | at the **job's own level**, beside `parameters:` | `risks`, `confidences`, `sections`, `sites` | **what is in it** | That is a YAML indentation trap with no diagnostic to help you: indent `risks:` under `parameters:` and the job never reads it as a filter, so the report silently contains everything. The reverse mistake is just as quiet. Notice which side `theme` falls on. A theme resolves to a stylesheet inside the template's resources, so it changes colours and layout and nothing else. **A theme changes how the report looks, never which findings it contains.** If someone reaches for a theme to make a report shorter, they have reached for the wrong key. ## Absent means everything This is the single most consequential default in the job: - **`risks` absent** - every risk level is included. - **`confidences` absent** - every confidence band is included, *including the lowest one*, the band that marks an alert as a probable false positive. An unfiltered report is not a filtered-for-signal report. - **`sections` absent** - every section the chosen template declares is rendered. - **`sites` absent** - every site in the session's tree. So the shortest possible `report` job is also the widest one. Narrowing is an opt-in act, and a report nobody configured is the maximal document, not the sensible one. ## What the lists accept, and what a bad entry costs `risks` accepts `high`, `medium`, `low` and `info` (with `information` accepted as an alias). `confidences` accepts `high`, `medium`, `low`, `falsepositive` and `confirmed`. Matching is case-insensitive. Two traps live here. 1. **The add-on's own fully-populated example of this job lists the confidence names without `confirmed`.** The job accepts `confirmed` perfectly well, but a `confidences` list copied from that example and then edited drops every alert a human has explicitly confirmed - the opposite of what anyone filtering for signal intends. Read the accepted values, not the example. 2. **An unrecognised entry is a warning, and contributes nothing.** It does not fall back to including everything. A `risks` list whose entries are all misspelled therefore yields a report containing **no alerts at all**, which looks identical to a clean scan. This is the failure mode to check first when a pipeline suddenly starts reporting nothing. A `sections` entry the chosen template does not declare behaves differently again: it produces a warning and is dropped, and the rest of the report renders normally. Sections can only ever *subtract* from what the template offers, because the template's own markup is what tests each name before emitting its block. A section name the markup never tests does nothing even when you spell it correctly. `sites` is looser than it looks: each entry is matched as a **substring** against the site names in the session tree, and an alert is then kept when its URI starts with a matched site. A short fragment can therefore match more sites than you meant. ## The filter you did not write The job also passes **the plan's own contexts** to the report as a filter, every time, whether or not you asked for it. If your plan defines contexts - and any plan that targets a URL does - then an alert has to fall inside one of them to appear. That is usually what you want, but it means a report can be narrower than its `risks` and `confidences` lists suggest, and the reason lies in a different part of the plan entirely. ## Where the filtering actually happens Filtering is not something the template does. When the job runs it takes the session's alert tree, walks it, and builds a **filtered copy**: an alert instance is carried over only if it is well-formed, falls inside the contexts and sites, and passes both the confidence and risk lists. A parent alert node survives only when at least one of its instances did. The template is then handed that copy and renders whatever reached it. Two things follow. First, the template cannot show you *which alerts* the filter removed, because it never sees them - though it is handed the filter settings themselves, and the default template ships a `reportParameters` section that prints the contexts, the sites and the risk and confidence levels both included and excluded. That disclosure is itself a section, so a `sections` list can remove the paragraph that would have told the reader the report was narrowed. Second, **the session's alerts are untouched** - filtering a report changes the document, not the findings, and running the job again with a different list gives you the other document from the same evidence.

  • A nightly report suddenly contains no alerts, yet the scan clearly ran. Where do you look first?
    At the `risks` and `confidences` lists. An entry the job does not recognise draws a warning and then contributes nothing, so a list that is entirely misspelled selects no levels at all and the report comes out empty. Check the plan's contexts and `sites` next, since both narrow the report independently of those lists.
  • Does filtering a report change anything about the alerts ZAP holds?
    No. The job builds a filtered copy of the alert tree and hands that to the template; the session's own alerts are untouched. That is why two report jobs in one plan can produce two different documents from exactly the same evidence, and why a narrow report is never a claim that the rest was not found.
  • Can the sections list add a section that the chosen template does not declare?
    No. The list can only select from what the template's `template.yaml` declares, and an unknown name is warned about and dropped. Sections work because the template's own markup tests each name before emitting its block, so a name nothing tests has no effect even when it is spelled correctly.

saying these in an interview costs you the question

  • Puts the risks or confidences list under parameters
  • Assumes an unconfigured report is already filtered for signal
  • Expects a misspelled risk name to fall back to including everything
  • Thinks changing the theme will shorten the report
  • Believes sections can add content the template does not declare
  • Says filtering a report removes those alerts from the session
open as a page

In ZAP's automation report job, what does the template parameter actually refer to?

level: juniorimportance: should knowfreq 50%

basics

~10 s

The template's own directory name under ZAP's reports folder - its id, not the display title written inside template.yaml and not the output file name. Leave it empty and the job uses risk-confidence-html.

open as a page

What must a directory contain before ZAP's reports add-on will load it as a report template?

level: middleimportance: should knowfreq 42%

basics

~10 s

A readable template.yaml declaring name, format, mode and extension, plus the Thymeleaf file report.<extension> beside it - report.html when the extension is pdf. A Messages.properties file and a resources folder are optional.

open as a page

How do you get two differently filtered reports out of one ZAP automation plan run?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Put two report jobs in the same plan. Each filters its own copy of the alert tree and renders its own template, so one run yields two documents. Give each a distinct reportFile or the second overwrites the first.

open as a page

When is forking a shipped ZAP report template the right call rather than configuring one?

level: principalimportance: nice to knowfreq 24%

basics

~20 s

Fork only when the document itself is wrong: a shape or an output format nothing ships. Anything reachable by choosing a template and setting its theme, sections and filters should stay configuration, because a fork is markup you own.

open as a page