HTTPS Interception
Probe inspects HTTPS by acting as a man-in-the-middle. It terminates the TLS handshake using a per-host leaf certificate signed by Probe’s own CA, then opens a separate TLS connection upstream to the real origin. With the CA installed and trusted on your device, the leaf is accepted and the encrypted stream becomes readable in the Detail panel.
This page explains the mechanics — what’s happening on the wire, how the system proxy is configured, and how to chain Probe behind a corporate upstream proxy.
How interception works
Section titled “How interception works”A typical HTTPS request through Probe goes through these steps:
- The client sends
CONNECT api.example.com:443 HTTP/1.1to Probe (port9099by default). - Probe replies
200 Connection establishedand starts a TLS handshake as the server. - On the fly, Probe asks its GuideAuthority to mint a leaf certificate for
api.example.com, signed by the Probe CA. The leaf is generated once and cached for the session. - The client validates the leaf — it chains to the Probe CA, which you’ve already trusted on this device, so the handshake succeeds.
- Probe opens its own TLS connection to
api.example.com:443upstream. - Bytes flow client → Probe → origin and origin → Probe → client. Probe holds the plaintext in the middle and writes it to the log.
The leaf certificate marks itself with IsCa::ExplicitNoCa (BasicConstraints CA:FALSE plus a Subject Key Identifier). Without that extension iOS rejects the leaf even if the CA is trusted, so it’s not optional — it’s a requirement of Apple’s stricter validation.
If the CA isn’t installed yet, see Set up the CA certificate. For phones, see Mobile debugging.
System proxy
Section titled “System proxy”When you click Start, Probe flips your operating system’s HTTP and HTTPS proxy to point at 127.0.0.1:9099. When you click Stop — or quit the app — the previous settings are restored.
- macOS uses
networksetupto update every active network service (Wi-Fi, Ethernet, Thunderbolt). Bypass entries cover loopback, link-local, and private LAN ranges so local services don’t get tunneled through Probe. - Windows writes to the WinINET registry keys and broadcasts
INTERNET_OPTION_REFRESHso apps that read WinINET (Chromium, Edge, most desktop apps) pick up the change immediately.
A handful of apps ignore the system proxy — Firefox has its own setting, some Electron apps respect HTTP_PROXY only on launch, and Java apps need -Dhttp.proxyHost. For those, set the proxy explicitly to 127.0.0.1:9099.
Upstream proxies
Section titled “Upstream proxies”If your network forces traffic through a corporate proxy, Probe can chain through it. Set the standard HTTPS_PROXY (and HTTP_PROXY) environment variables before launching Probe — the Rust core picks them up and forwards intercepted traffic through that upstream after decrypting it locally.
# macOS / Linux shellexport HTTPS_PROXY=http://corp-proxy.internal:8080open -a Probe# Windows$env:HTTPS_PROXY = "http://corp-proxy.internal:8080"& 'C:\Program Files\Probe\Probe.exe'NO_PROXY is honored too — list domains that should connect directly without going through the upstream.
Why bodies are readable
Section titled “Why bodies are readable”Probe strips the Accept-Encoding header on every outgoing request before forwarding it upstream. Origins respond with uncompressed bodies, so what you see in the log is the actual JSON, HTML, or text — no gzip/br decoding step needed in the UI.
The trade-off: response sizes shown in the Summary tab are the uncompressed sizes, which won’t match what the client would have received over the network if compression was negotiated. For most debugging this is what you want; if you specifically need to test compression behavior, disable that step in Settings.
Related
Section titled “Related”- Set up the CA certificate
- Detail panel — what you see once interception is working
- Mobile debugging — how to point a phone at Probe
- Sessions — save the captured traffic for later