skip to content

Program and Packaging

The installed program itself: how you start it, what actually ships inside it, and where it will run code you wrote. Most of what reads as this tool is not in the core download.

on this pageshow

explore

questions

16

In OWASP ZAP, which capabilities live in the core program and which arrive as add-ons?

level: juniorimportance: must knowfreq 62%

answer

  1. one program, many separate packages
  2. core is a single version line
  3. add-ons are archives in `plugin/`
  4. a move-out may leave a deprecated shim
  5. the passive engine left, the active stayed

basics

~20 s

Core is one versioned program: the command line, the control API, the active-scan engine, and the alert and context models. Almost everything else — the local proxy, the passive-scan engine, the crawlers, automation, reports — ships as separately versioned add-ons.

solid answer

~40 s

ZAP is a small core program plus a directory of `.zap` add-on archives, each with its own version and its own release line. Core owns the command line, the control API, the session database, the **active-scan engine** in `org.parosproxy.paros.core.scanner`, and the `Alert` and `Context` models. The local HTTP proxy and root certificate authority are the `network` add-on; the passive-scan **engine** is the `pscan` add-on, although the passive **rule contract** (`PassiveScanner`, `PluginPassiveScanner`) stayed in core and is live; the crawlers, automation, reports and alert filters are add-ons too. Each add-on registers itself through `ExtensionHook`, so its command-line arguments and API components are indistinguishable from core's at the surface. The trap: when a subsystem moves out, core often keeps a `@Deprecated` shim, so the class still resolves even though the capability is elsewhere.

go deeper

for a junior

Be able to say that ZAP is a small program plus separately versioned add-on archives, and to name two capabilities that are add-ons rather than core — the local proxy and the passive-scan engine are the usual pair.

for a middle

Explain the registration path: an add-on hooks into core and contributes flags, API components and job names that look native. Then explain the asymmetry — the passive engine moved out, the active engine stayed, and the passive rule contract stayed with it.

for a senior

Show that you check ownership rather than assume it. A moved-out class still resolving in core is a deprecated shim, and treating the hit as evidence is how mis-attributed claims get into a report someone else has to defend.

for a principal

Own the vocabulary your organisation uses. If findings are attributed to "ZAP" rather than to a named add-on and rule package, nobody can reproduce a result or reason about what an upgrade changed.

## The shape of the product ZAP is not one monolithic application. It is a **core program** on a single version line plus a directory of **add-ons** — `.zap` archives read out of the install's `plugin/` folder at startup, each with its own independent version number and its own release cadence. Saying *"ZAP does X"* is therefore ambiguous in a way that matters operationally: two installs that report the same program version can differ in what they can do, because they carry different add-on sets. An add-on plugs into core through one surface, `ExtensionHook`. Through it an add-on registers extensions, command-line arguments (`addCommandLine`), control-API components, HTTP-sender listeners, input-vector `Variant`s and automation job names. Because the registration is uniform, an add-on's contributions are **indistinguishable from core's** once ZAP is running: an add-on's flag looks like a core flag, an add-on's API component looks like a core component. That uniformity is the whole reason this distinction has to be learned rather than observed. ## What is genuinely core | capability | where it lives | |---|---| | the command line, the control API, the session database | core | | the **active-scan engine** (`paros.core.scanner`) | core — only the active **rules** are add-ons | | the passive-scan **rule contract** (`PassiveScanner`, `PluginPassiveScanner`) | core, and not deprecated | | the passive-scan **engine** that schedules and runs those rules | the `pscan` add-on | | the local HTTP proxy listener and the root certificate authority | the `network` add-on | | the crawlers | the `spider`, `spiderAjax` and `client` add-ons | | automation plans, rendered reports, alert filters | three separate add-ons | The asymmetry in the middle rows is the single most useful thing on this subject. **The passive engine left core; the active engine did not.** And the passive row itself split: a passive rule is written against a **core** base class, and it is **an add-on** that drains the history table and runs it. Whenever you describe passive scanning, say which half you mean. ## Three shapes the boundary takes Two of these are ways a subsystem leaves core; the third is a packaging shape that never involved a move at all. 1. **A move-out that leaves a deprecated shim.** The old package survives in core with type-level `@Deprecated` markers so that add-ons compiled against it still link. This is the case for the proxy, the certificate authority and the passive engine. 2. **A move-out that leaves nothing.** The traditional spider moved into the `spider` add-on and its old core package simply does not exist any more. A move-out does not have to leave a footprint, so the absence of a shim is not evidence that a capability is core. 3. **An add-on that was never core code at all.** Some add-ons ship **no classes at all** — their manifest lists files that are unpacked into ZAP's home directory on install, for a core subsystem to read. The standard scan policies are packaged this way: the policy *machinery* is core and reads a directory, and the shipped policy *files* arrive as an add-on that drops them there. Nothing about the add-on boundary implies code, and nothing about an add-on's data implies that the subsystem reading it moved. ## Why the shim is a trap A grep or an IDE lookup will happily resolve a moved-out class in the core source tree. That hit proves a shim is present; it does not prove the capability runs from there. The honest checks are different: - read whether the type carries a type-level `@Deprecated` marker; - ask which package the *live* implementation sits in; - from a running install, list what is actually loaded rather than reasoning from the source tree. ## Why a pipeline reader should care - A capability you rely on may be **absent from this build** even though it is present in the project, because its add-on was never installed. - A capability may be present and still **not running**, because its add-on failed a requirement at load time. - Upgrading the program does not upgrade the add-ons, and upgrading an add-on does not upgrade the program. They are separate decisions with separate blast radii. - Describing a finding as *"ZAP reported it"* loses the information a reviewer needs. *"An `ascanrules` active rule reported it"* or *"a `pscan`-scheduled passive rule reported it"* is reproducible. ## How to say it correctly Name the owner every time: *"core's active-scan engine"*, *"the `pscan` add-on"*, *"the `network` add-on's local proxy"*. Never *"ZAP lets you…"*. Every identifier in a mis-attributed sentence can be real while the sentence is false, and no tooling catches that — only the habit of naming the owner does.

  • If the passive-scan engine is an add-on, where does a passive rule's base class live?
    In core. `PassiveScanner` and `PluginPassiveScanner` are declared in core's `org.zaproxy.zap.extension.pscan` package and carry no type-level `@Deprecated` marker; every passive rule shipped in the add-on repository extends them. The **engine** that drains recorded traffic and runs those rules is the `pscan` add-on. So the contract is core and the scheduler is an add-on — name the half you mean.
  • Can an add-on ship no Java code at all?
    Yes. An add-on's manifest can list plain files that are unpacked into ZAP's home directory when it installs, with no classes to load. The standard scan policies arrive that way: core owns the policy machinery and reads the policy directory, and the add-on's only contribution is the files it drops there. Nothing about the add-on boundary implies code.
  • Why does grepping core for a moved-out class find it anyway?
    Because the project usually leaves a `@Deprecated` shim in core so that add-ons compiled against the old package still link. The class is genuinely there; the capability is not. Distinguish the shim from the implementation by checking for a type-level deprecation marker and by locating the live class, rather than treating any hit as proof.

saying these in an interview costs you the question

  • Says the local HTTP proxy and root certificate authority are core code.
  • Treats a class resolving in the core tree as proof the capability runs there.
  • Calls add-ons optional extras rather than where most capability lives.
  • Assumes every moved-out subsystem left a deprecated stub behind it.
  • Thinks one program version describes what the whole install can do.
open as a page

How is the set of add-ons in a ZAP distribution or container image actually decided?

level: middleimportance: must knowfreq 55%

basics

~20 s

A list in ZAP's core repository names every add-on folded into a main release, pinning each by download URL and SHA-256 hash; entries flagged core are the smaller core distribution. Container images then freeze that set at image-build time.

open as a page

In ZAP, what is the real difference between starting the program with `-cmd` and with `-daemon`?

level: middleimportance: must knowfreq 62%

basics

~20 s

Lifetime, not the interface. Both switches turn the window off and both bring up the local listener. -cmd runs the registered work inline and then shuts down; -daemon runs it on a background thread and loops.

open as a page

In OWASP ZAP, what does an `httpsender` script implement, and which traffic does it see?

level: middleimportance: must knowfreq 45%

basics

~20 s

An httpsender script implements two entry points, sendingRequest and responseReceived, each handed the message, an initiator naming which part of ZAP caused it, and a send helper. It sits on the sending path every component uses.

open as a page

Which ZAP container image tag should a CI job pull, and what does the `bare` tag leave out?

level: juniorimportance: should knowfreq 55%

basics

~20 s

Pull the default tag unless you know you do not need what it carries. The bare tag is a JRE-on-Alpine image with bash and curl added: no browser, no X server, no Python, and one architecture.

open as a page

In ZAP, what is a `targeted` script, and what has to happen before one runs?

level: juniorimportance: should knowfreq 28%

basics

~10 s

A targeted script implements one method, invokeWith, handed a single HTTP message. It never fires on traffic: something must choose a message and invoke the script with it.

open as a page

What does an OWASP ZAP add-on's alpha, beta or release status actually tell you?

level: middleimportance: should knowfreq 45%

basics

~20 s

An add-on's status is a statement about how settled its public interface is, not about how important, mature or well-tested it is. ZAP's mandatory networking add-on ships at beta and the live passive-scan engine ships at alpha.

open as a page

In ZAP, how does a `proxy` script differ from an `httpsender` script in reach and power?

level: middleimportance: should knowfreq 38%

basics

~20 s

A proxy script returns a boolean and can stop a message: false drops it and closes the client connection. A sender script returns nothing and cannot veto, but it sees every message the program sends, not only proxied traffic.

open as a page

A ZAP add-on archive sits in the plugin directory but its capability is missing. Why?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Installed is not running. ZAP drops an add-on before loading if the block list or its declared program-version range rejects it, and skips it afterwards if its run requirements fail — a dependency issue, a newer minimum Java version, or missing bundled libraries.

open as a page

In ZAP, why does a `-cmd` run return a failure exit code where a `-daemon` run returns zero?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Only the one-shot bootstrap returns an exit status; the daemon bootstrap returns zero as soon as its background thread is alive. The automation add-on also refuses to record a status unless the process type is cmdline.

open as a page

Your ZAP `httpsender` script stamped every request, then quietly stopped mid-run. Why?

level: seniorimportance: should knowfreq 32%

basics

~20 s

The likeliest cause is that the script threw once. An exception is handled against the script, not the message: it is flagged with an error and disabled, traffic keeps flowing unstamped, and nothing in the run's verdict records it.

open as a page

Should a scanning pipeline pin its ZAP add-on set or refresh it, and how would you decide?

level: principalimportance: should knowfreq 30%

basics

~20 s

ZAP's detection logic is not in the program — the rule packages and job types are separately versioned add-ons. Pinning the set makes two runs comparable and lets coverage age; refreshing buys coverage and makes a new finding ambiguous between tool change and code change.

open as a page

Should a pipeline run ZAP as a fresh container per job or as one long-lived daemon?

level: principalimportance: should knowfreq 35%

basics

~20 s

Default to a fresh container per job running the one-shot lifetime: it is the shape whose exit code is a verdict and whose state cannot leak between targets. Share a daemon only when several steps need the control API.

open as a page

Which OWASP ZAP add-ons will the program refuse to start without, and how is that enforced?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

ZAP hard-codes two mandatory add-ons, callhome and network, in core's ControlOverrides. If either is missing the add-on collection throws at startup, and once marked mandatory neither can be uninstalled, blocked, or have its extensions disabled.

open as a page

In ZAP, what happens to a saved script whose recorded engine name is Nashorn?

level: middleimportance: nice to knowfreq 20%

basics

~20 s

The engine lookup silently rewrites any name containing Nashorn to Graal.js, because that engine left the supported Java runtimes. If the add-on providing the replacement is absent there is no engine, and the script cannot be enabled.

open as a page

How do you run ZAP's windowed session in a container with no display, and what still differs?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Put a virtual display in front of it: the shipped zap-x.sh starts Xvfb, runs zap.sh with your arguments and forwards the exit code. What still differs is that the program branches on whether a view is attached.

open as a page