What does a matching pass-through entry do to an HTTPS connection through ZAP's network add-on?
answer
- it stops being a proxy, not just quiet
- only a CONNECT is ever tested
- decided once, per connection
- authority searched, not fully matched
- an alias takes precedence
basics
~20 sIt stops ZAP acting as a proxy for that connection. On a matching CONNECT, ZAP answers that the connection is established, clears its handler pipeline and relays raw bytes, so nothing downstream ever sees the traffic.
solid answer
~50 sA pass-through is a regular expression over the requested **authority**, held in the `network` add-on's options. The check runs only on a `CONNECT` request: if it matches, ZAP replies `200 Connection established`, tears every handler out of the connection's pipeline and installs a plain byte relay to the target. No certificate is generated, no message is recorded, and nothing further in ZAP sees the connection — it is not "do not scan this", it is "stop being a proxy for this socket". Three consequences follow. The decision is made **once per connection**, so every request multiplexed onto that tunnel is covered. The pattern is applied as an unanchored **search** over the escaped authority, so a short pattern matches more authorities than you expect. And an enabled alias for the listener wins: if the authority is an alias, the connection is never passed through.
go deeper
Remember what it is for: some clients cannot be intercepted at all, and a pass-through lets their connections through untouched while everything else is still proxied.
Explain the mechanics: the check runs on the CONNECT, a match answers 200 and replaces the pipeline with a byte relay, and the pattern is searched against the authority rather than matched against a URL.
Show the operational judgment: a pass-through removes traffic from the run with no trace, it is decided once per connection, and an over-broad pattern silently widens that hole.
Frame the distinction that generalises: a rule that declines to act leaves evidence, a rule that declines to participate does not. Decide which of those your team is allowed to configure, and how it is reviewed.
## What a pass-through actually is The `network` add-on keeps a list of **pass-through** entries. Each is a compiled regular expression over an HTTP **authority** — the host and port a client asked for — plus an enabled flag. Nothing is on that list by default; it is entirely something you add. The entry is consulted by a handler placed at the very front of a connection's pipeline, and it does one thing: decide whether ZAP should behave as a proxy for this connection at all. ## The mechanism, step by step 1. A client opens a connection and sends `CONNECT host:port` — the request that asks a proxy to open a tunnel for TLS. 2. The handler checks the method. **If it is not `CONNECT`, the answer is no**, and the handler removes itself. Plain HTTP is never passed through, because there is no `CONNECT` to test. 3. If it is `CONNECT`, the requested authority is tested against the enabled pass-through patterns. 4. On a match, ZAP writes back `HTTP/1.1 200 Connection established`, then **removes every handler from the pipeline** and adds a read-timeout handler and a byte relay that simply copies bytes between the client and the target. 5. On no match, the handler removes itself and the connection proceeds down the normal path, where ZAP terminates TLS with a certificate it signs itself and every other handler runs. Step 4 is the part worth internalising. ZAP does not decline to scan the traffic; it **stops being a proxy** for that socket. There is no message object, so there is nothing to record, nothing to pass to any downstream consumer, and nothing to see afterwards. The traffic reaches its destination exactly as if ZAP were a dumb tunnel, which is precisely what it has become. ## Three properties that surprise people **It is per connection, not per request.** The decision is taken once, on the `CONNECT`, and the deciding handler then removes itself. Everything that subsequently travels over that tunnel — every request on a keep-alive connection, every stream multiplexed onto it — is covered by that one decision, and the authority of those inner requests is never examined. **The pattern is searched, not matched.** The authority is tested with a *find* — an unanchored search — rather than a full match. A pattern intended for one host therefore also matches any authority that merely contains it, which in the pass-through direction means quietly excluding more hosts than you meant to, and excluding them invisibly. **Case and port are part of the string.** The pattern is compiled with no case-insensitivity flag and is applied to the escaped authority, which includes the port when the client supplied one. A pattern written against a bare lowercase hostname is not automatically the rule you imagined. ## An alias beats a pass-through Before the pass-through list is consulted at all, the add-on asks whether the requested authority is a configured **alias** for this listener — an extra name under which ZAP's own API answers. If it is, the answer is an immediate *no pass-through*, whatever the patterns say. An alias is matched by exact equality on the host name, which is a much stricter discipline than the pass-through search, and it takes precedence. | | alias | pass-through | |---|---|---| | what is compared | the host name | the escaped authority, host and port | | how it is compared | exact equality | unanchored regular-expression search | | when it applies | any request | only a `CONNECT` | | effect | the request is treated as an API request | ZAP becomes a byte relay | | precedence | **wins** | only reached if no alias matched | ## Using it without losing visibility - **Reach for it when interception must not happen**, not when a scan is merely noisy. Certificate pinning is the classic case: a client that refuses a certificate it did not expect cannot be proxied at all, and a pass-through is the way to let it work while the rest of the traffic is still proxied. - **Write patterns that are as specific as the search allows.** Because the match is a search, anchor the parts you can and prefer a longer, more distinctive pattern to a short one. - **Expect no trace.** If you are wondering why a host you know was visited does not appear anywhere in the run, a pass-through entry is one of the few mechanisms that can remove it completely rather than merely flagging it. - **Review the list when you inherit a configuration.** It is small, it is easy to forget, and each enabled entry is a standing decision to make some traffic invisible. The general shape here is one worth carrying into any interception tooling: there is a real difference between a rule that says *do not act on this* and a rule that says *do not participate in this*. The first leaves evidence behind; the second is the one that leaves none, and it is therefore the one to audit.
- Does a pass-through entry apply to plain HTTP requests?No. The handler tests the method first and answers no for anything that is not a `CONNECT`, then removes itself. Pass-through is a property of the tunnel a client asks for, so plain HTTP always takes the normal proxied path.
- Why is a passed-through host harder to notice than an excluded one?Because there is no message to record. Other controls mark or skip a message that still exists; a pass-through replaces the whole pipeline with a byte relay, so nothing downstream ever receives an object to log, flag or count.
- What happens to later requests on a connection that was passed through?They are relayed too, unexamined. The decision is taken once on the CONNECT and the deciding handler removes itself, so every request carried by that tunnel inherits it regardless of what it asks for.
saying these in an interview costs you the question
- Says a passed-through request is still recorded but unscanned
- Thinks the pattern is matched against the full URL
- Believes pass-through applies to plain HTTP too
- Assumes a pass-through pattern beats a matching alias
- Treats the decision as per request rather than per connection