HTTP/3 inspection, captured on the wire
HTTP/3 in. HTTP/3 out. Malware stopped in between.
Can a security gateway terminate an incoming HTTP/3 connection, establish another HTTP/3 connection to the origin and still perform deep inspection on the response? We captured Cloud Fellows Web Gateway doing exactly that.
The demonstration is intentionally small and verifiable. One client sends three requests through Web Gateway to sse-testcenter.org. Both network legs use QUIC and HTTP/3. A benign file is allowed, the harmless EICAR antivirus test file is blocked, and another benign file succeeds immediately afterwards on the same downstream QUIC connection.
The result in one table
| Request | Origin to gateway | Gateway to client | Decision |
|---|---|---|---|
/eicar/benign.txt | HTTP/3 - 200 | HTTP/3 - 200 | Allowed |
/eicar/eicar.com | HTTP/3 - 200 | HTTP/3 - 403 | Blocked |
/eicar/benign.txt | HTTP/3 - 200 | HTTP/3 - 200 | Allowed |
Two independent HTTP/3 connections
The packet capture contains 87 UDP packets and zero TCP packets. It records two distinct QUIC conversations:
- client to Web Gateway on UDP port 9443
- Web Gateway to the origin on UDP port 443
Both connections negotiate QUIC version 1 and HTTP/3. They have separate connection identifiers, handshakes and TLS sessions. Web Gateway is therefore not forwarding opaque QUIC packets. It terminates the client connection and originates a separate connection to the upstream service.
Three requests on both legs
Filtering the decrypted capture for HTTP/3 paths shows each request twice: first from the client to Web Gateway and then from Web Gateway to the origin. The rows in this screenshot are sorted by source address to group the downstream and upstream legs.
The decisive transaction
The client requests the EICAR test file on downstream HTTP/3 stream 4. Web Gateway requests the same object from the origin on its independent upstream HTTP/3 stream 8.
The origin returns :status 200 and the 68-byte EICAR test signature. The inspection policy reads the decrypted response body, detects the signature and returns a block decision. Web Gateway then generates a new :status 403 response for the client. The EICAR signature never appears in a downstream HTTP/3 frame.
| Frame | Direction | Stream | Observed result |
|---|---|---|---|
| 52 | Client to gateway | 4 | GET /eicar/eicar.com |
| 54 | Gateway to origin | 8 | GET /eicar/eicar.com |
| 60 | Origin to gateway | 8 | :status 200 |
| 64 | Gateway to client | 4 | :status 403 |
The corresponding status-header filter makes the policy decision visible. Again sorted by source, the origin-side group contains three 200 responses. On the client-facing side, the middle response is 403 while the first and third remain 200.
Blocking one stream, not killing the connection
HTTP/3 multiplexes transactions as independent QUIC streams. A gateway that merely closes the complete connection when it finds unwanted content would disrupt every concurrent transaction.
That is why the third request matters. Immediately after the block, the client requests the benign file again on downstream stream 8. It receives a normal 200 response. Enforcement was applied to the affected HTTP transaction while the connection remained usable.
The example is deliberately simple
The Python policy buffers up to 64 KiB of selected response bodies and searches for the EICAR signature. It is a byte-level demonstration, not a complete antivirus engine: it does not unpack archives, test large-object performance or establish throughput.
Its purpose is to demonstrate the inspection interface through which a production security engine can examine content and enforce a decision across HTTP versions. TLS interception also requires the client to trust the gateway's signing CA. Wireshark shows the in the downstream handshake.
What this capture proves
- Web Gateway terminates an incoming QUIC connection and creates an independent upstream QUIC connection.
- Both network legs carry HTTP/3, with no TCP traffic in the capture.
- The gateway inspects decrypted response content and acts on the bytes, not only on the URL.
- Benign content passes while the EICAR test signature is replaced with a 403 response.
- The decision is applied per HTTP/3 stream and the downstream QUIC connection remains usable.
Verify it yourself
The evidence package includes the packet capture, the TLS key log needed to decrypt this synthetic session in Wireshark, the exact configuration and policy, gateway access log, build identity and a SHA-256 manifest.
With the key log configured in Wireshark, these display filters expose the main findings:
| Wireshark display filter | What it shows |
|---|---|
http3.headers.path or http3.headers.status | Requests and status responses on both legs |
http3 contains "X5O!P%@AP[4" | The signature on the upstream leg only |
http3 contains "Access Blocked" | The generated block page on the downstream leg |
Download the evidence
Download the Wireshark evidence package
Archive SHA-256:cb4217c417d88494a0bae524a1b6340743df0be5cfd4bde37b0a46de14bf9de3
The included TLS secrets decrypt only this synthetic demonstration. The archive contains security-testing material and should be handled accordingly.
HTTP/3 should be governed, not bypass inspection
HTTP/3 is now a normal web protocol. Treating it as an opaque exception, or blocking it so that clients fall back to older transports, is not a durable Security Service Edge strategy.
Cloud Fellows Web Gateway applies one transaction and policy model across HTTP generations. The capture makes that architectural claim concrete: HTTP/3 enters, HTTP/3 leaves, and content policy is enforced in between.