skip to content

In ZAP, how does the `exim` add-on's `import` job differ from the `openapi` job in what it sends?

level: seniorimportance: should knowfreq 40%

answer

  1. a definition versus a recording
  2. one family can populate without sending
  3. `sendRequests` defaults to false
  4. the url type always sends anyway
  5. only the replay path checks the mode

basics

~20 s

The exim import job replays recorded traffic and can populate the session without touching the target: for a HAR file sendRequests defaults to false. The definition jobs always issue their requests and have no such switch.

solid answer

~40 s

`exim`'s `import` job takes `type: har`, `modsec2`, `url` or `zap_messages`. The two log types parse a file into history entries and send nothing. `har` sends only when `sendRequests: true` — the default is false, so the recorded responses are used and the target is never contacted. `url` always issues a GET per line and ignores that flag. The definition jobs (`openapi`, `soap`, `graphql`, `postman`) have no equivalent switch: the import *is* the traffic. There is a second asymmetry — the HAR replay path checks the current mode before each request and each redirect hop, and the four definition imports never consult it at all.

code

yaml · 6 lines
yaml
- type: import
  parameters:
    type: har
    fileName: /zap/wrk/session.har
    sendRequests: false   # the default: recorded responses, nothing leaves the runner
    maxMessages: 0        # har only; 0 imports every entry

go deeper

for a junior

Learn the split: a definition has to be turned into requests, a recording already contains the responses. Only the second can fill the session without sending.

for a middle

Know the four exim types and which of them send, and that the flag that controls sending applies to the recorded-traffic type rather than to all of them.

for a senior

Show you would choose the recorded path when sending is not permitted, and that you know the mode check exists on that path and not on the definition imports.

for a principal

Decide what an unattended pipeline may do by default: which environments accept generated traffic at all, and what evidence a run must produce when it is only permitted to observe.

## Two families of import, and only one of them is a request generator Both families put entries into the history and nodes into the Sites tree, which is why they are easy to conflate. They differ in where the bytes come from. | job | input | does it contact the target? | |---|---|---| | `import` with `type: modsec2` | a web-application-firewall log | no — parsed into history | | `import` with `type: zap_messages` | a saved message log | no — parsed into history | | `import` with `type: har` | recorded request/response pairs | only if `sendRequests: true`; default false | | `import` with `type: url` | one URL per line | yes, a GET per line, always | | `openapi` / `soap` / `graphql` / `postman` | a definition or collection | yes, always, with no off switch | The useful mental model: a **definition** describes requests that have never been made, so making them is the only way to turn it into evidence. A **recording** already contains the response, so the tool can reconstruct the exchange from the file. That is why one family has an off switch and the other cannot. ## When the recorded path is the right answer This is the mechanism to reach for when you need passive findings from an environment you may not send traffic to. Capture the session elsewhere, feed the recording in with sending off, and the history fills with real request/response pairs that passive rules will scan — without a single packet leaving the runner. Active scanning is off the table, because that genuinely requires sending, but header, cookie, content-type and information-disclosure findings do not. Turning `sendRequests: true` converts the same file into a replay: each recorded request is re-issued live and the *fresh* response is what gets recorded. Use it when the recording is stale or when you want responses from the environment in front of you, and remember that a replay of a captured session repeats whatever that session did, including anything that changed state. ## The mode asymmetry, which is the part worth carrying away The program's mode enum (`safe`, `protect`, `standard`, `attack`) is its headline offence-limiting control. Measured against the source: - The HAR replay path checks it **per request** — refusing outright in `safe`, and in `protect` requiring the URL to be in scope — and checks it again for **each redirect hop** before following one. - The `openapi`, `soap`, `graphql` and `postman` add-ons never consult it. Their only references to the mode type are empty session-listener overrides. So the one import path that already defaults to sending nothing is also the one that is mode-aware, and the four paths that always send are not. `safe` mode does not stop a definition import. If you were relying on the mode as a backstop for an unattended run, that backstop does not cover this leaf's jobs. ## The caps, which are not the same field twice `maxMessages` appears on both families and means slightly different things: 1. On `openapi`, `soap`, `graphql` and `postman` it caps how many messages the converter generates before any are sent, and defaults to `0` for no cap. 2. On `import` it applies to the **HAR** type only — the comment in the shipped template says so — and bounds how many recorded entries are taken. 3. Either way a negative value is rejected during verification rather than at run time, so a bad plan fails early. ## What every path leaves behind looks the same One detail that trips people reading a session afterwards: **all** of these paths record under the user-sent history type, the log parsers included. An imported firewall log and a live replay of the same traffic are indistinguishable by history type alone; only the job that ran tells you which happened. If a report or a filter needs to separate observed traffic from generated traffic, it has to key on the plan, not on the record. It is also worth reading the shipped `import` template rather than assuming. Its comments say plainly that `sendRequests` applies when the type is HAR and that `maxMessages` bounds a HAR import, and in this case the code agrees with the comments — the flag really is inert for the other three types. ## Choosing between them Ask two questions in order. *Am I permitted to send traffic to this target right now?* If not, the recorded path with sending off is the only import that respects that. *Do I have a recording that covers what I care about?* If not, a definition is the only thing that will reach operations no session ever exercised — and then the caution about writes, destinations and the mode applies in full.

  • Can you get passive findings without sending anything to the target?
    Yes, through the recorded path. Import a HAR with sending off and the history fills with real request/response pairs that passive rules scan normally. Active scanning is not available that way, since attacking requires sending, but everything derived from observing traffic is.
  • Does the url import type honour sendRequests like the har type does?
    No. It issues a GET for each line with a scheme and ignores the flag entirely, so `type: url` always contacts the target. The flag is documented as applying to HAR, and the code matches the documentation here.
  • Will safe mode prevent an openapi import from reaching a host?
    No. The four definition import add-ons never consult the mode; their only references to it are empty session-listener overrides. The HAR replay path does check it, per request and per redirect hop, which is the asymmetry worth remembering.

saying these in an interview costs you the question

  • Says every import job necessarily sends traffic to the target
  • Thinks sendRequests defaults to true
  • Assumes sendRequests applies to every exim import type
  • Believes safe mode blocks a definition import
  • Treats a HAR replay as equivalent to importing the recorded responses