-- IETF QUIC Worki">
Classroom Glossary Public page

NET-301 Week 9 -- QUIC, HTTP/3, and Encrypted Transport Security

1,346 words

"QUIC makes network monitoring harder, not easier. That is not a side effect; in some deployment contexts it is a feature. For defenders, it is a challenge." -- IETF QUIC Working Group, RFC 9000 Security Considerations


Lecture (90 min)

9.1 QUIC Protocol Mechanics

QUIC (RFC 9000, 2021) is a multiplexed, secure transport protocol that runs over UDP and provides the reliability, ordering, and congestion control properties that TCP provides -- but with integrated TLS 1.3 and several architectural improvements over TCP+TLS.

Why QUIC exists: Three TCP-era problems drove its design.

Problem TCP+TLS behavior QUIC solution
Head-of-line blocking A lost packet in any TCP stream stalls all HTTP/2 streams sharing the connection QUIC streams are independent; a lost packet in stream 3 does not stall stream 5
Connection establishment latency TCP 3-way handshake + TLS 1.2 handshake = 3 RTT minimum; TLS 1.3 = 2 RTT QUIC 1-RTT for new connections; 0-RTT for session resumption
Connection migration TCP connections are identified by 4-tuple (src IP, src port, dst IP, dst port); changing IP breaks the connection QUIC uses Connection IDs; a UE moving from WiFi to cellular keeps the QUIC connection alive

QUIC packet number spaces and encryption levels:

Every QUIC packet is encrypted. There are four encryption levels:

  1. Initial packets -- encrypted with keys derived from the destination Connection ID (known standard; eavesdropper can decrypt Initial packets with the published derivation)
  2. 0-RTT packets -- encrypted with keys from a previous session (session resumption without a full handshake; replay attack surface)
  3. Handshake packets -- encrypted with keys from the TLS 1.3 Handshake
  4. 1-RTT packets -- encrypted with keys from the completed TLS 1.3 handshake (application data)

For NSM purposes: Initial packets are decodable (Wireshark does this automatically). Everything above Initial requires the session keys, which are ephemeral TLS 1.3 keys.

Connection establishment (1-RTT):

Client                              Server
  |                                    |
  |-- Initial (CRYPTO: ClientHello) -->|
  |<- Initial (CRYPTO: ServerHello)  --|
  |<- Handshake (CRYPTO: Cert+Fin)   --|
  |-- Handshake (CRYPTO: ClientFin) -->|
  |-- 1-RTT (application data)-------->|
  |<- 1-RTT (application data)---------|

Total: 1 RTT for application data to begin flowing (vs. 2 RTT for TCP + TLS 1.3).

9.2 HTTP/3 over QUIC

HTTP/3 (RFC 9114) runs over QUIC streams. Each HTTP request/response pair occupies a dedicated QUIC stream. The elimination of head-of-line blocking at the transport layer makes HTTP/3's stream multiplexing genuinely parallel, unlike HTTP/2's multiplexing over a single TCP connection.

QPACK header compression (RFC 9204): HTTP/3's header compression scheme. HTTP/2 uses HPACK, which maintains a shared dynamic table between client and server -- vulnerable to CRIME/BEAST-style attacks and tied to single-connection sequencing. QPACK uses separate encoder/decoder streams to avoid HOL blocking in the dynamic table updates.

NSM impact of HTTP/3:

  • HTTP/3 uses UDP port 443 (QUIC Alt-Svc advertisement in HTTP/2 responses routes clients to HTTP/3)
  • QUIC's encrypted headers hide the HTTP method, URL, and response code from passive inspection
  • The TLS SNI in the Initial CRYPTO ClientHello is visible in plaintext (until Encrypted ClientHello / ECH is deployed)
  • No http.log in Zeek for HTTP/3 traffic -- only ssl.log and conn.log entries

9.3 MASQUE and QUIC as a Tunneling Substrate

MASQUE (RFC 9297, 2022) uses HTTP/3 CONNECT method extended with the connect-udp and connect-ip upgrade tokens to proxy arbitrary UDP or IP datagrams over an HTTP/3 session. This makes QUIC/HTTP3 a VPN substrate that:

  • Looks like normal HTTPS traffic to a firewall (destination port 443)
  • Carries arbitrary UDP datagrams or IP packets inside
  • Encrypts all metadata above the TLS SNI level

C2 implications: Red teams have adopted QUIC/MASQUE for command-and-control because:

  1. QUIC port 443 passes through most enterprise egress policies
  2. The TLS SNI can point to a legitimate CDN that fronts the C2 server
  3. Connection migration makes source IP attribution harder
  4. Zeek and Suricata lose their Layer-7 visibility

9.4 Detection Challenges: The NSM Visibility Gap

Mapping the visibility loss vs. TCP+TLS:

NSM field TCP + TLS 1.2 QUIC + TLS 1.3
TLS SNI (server name) Visible in ClientHello Visible in QUIC Initial CRYPTO (until ECH deployed)
JA3 fingerprint Available from TLS ClientHello cipher list Partial -- QUIC transport parameters interact with TLS; JA3 for QUIC is non-standard
HTTP method (GET/POST) Visible (unencrypted in HTTP/1.1; exposed via HPACK tables in HTTP/2) Not visible -- HTTP/3 is encrypted end-to-end
HTTP URL path Visible in HTTP/1.1; mostly visible in HTTP/2 Not visible
Response code Visible Not visible
X-Forwarded-For header Visible in proxy scenarios Not visible
Connection duration Available via conn.log Available via conn.log
Byte counts Available Available

What detection remains:

  • Zeek dpd.log: Zeek's Dynamic Protocol Detection identifies QUIC by protocol signature on UDP/443. Zeek logs quic as the service in conn.log.
  • Suricata quic keyword (Suricata 7+): detects QUIC Initial packets; can match on the QUIC SNI extracted from the Initial CRYPTO frame.
  • Flow-level metadata: connection duration, byte totals, packet counts remain available. Beaconing detection via RITA still works on QUIC flows.
  • JA3 for QUIC (emerging): browser-specific TLS parameter fingerprints are partially preserved in QUIC Initial CRYPTO frames. Not as reliable as TCP JA3.

Example Suricata rule for QUIC SNI detection:

alert quic any any -> any any (
    msg:"NET-301 QUIC C2 SNI indicator";
    quic.sni; content:"suspicious-domain.com";
    classtype:command-and-control;
    sid:9000001; rev:1;
)

Example Zeek QUIC identification:

# QUIC connections appear in conn.log with service=quic
zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p service proto < conn.log \
  | awk '$6 == "quic"' | head -20

9.5 Defensive Options and Documentation

Option 1: TLS 1.3 downgrade for internal traffic. Internal east-west traffic (within a datacenter or VPN perimeter) can be forced to TLS 1.2 or TLS 1.3 over TCP via policy. This preserves JA3 fingerprinting and HTTP-level logging for internal flows. Not applicable to egress internet traffic.

Option 2: Explicit QUIC blocking at the egress. Some organizations block UDP/443 at the perimeter firewall, forcing all HTTPS traffic to TCP/443. This recovers full Zeek/Suricata visibility for egress flows. Cost: legitimate HTTP/3 performance benefits are lost; some applications may experience degraded performance.

Option 3: Decrypt-and-inspect via TLS inspection proxy. A TLS/QUIC-aware decryption proxy can terminate QUIC connections and forward decrypted HTTP/3 to the backend. Cost: requires deploying an enterprise proxy that speaks QUIC (as of 2026, supported by major vendors including Palo Alto, Zscaler, Cisco Secure); certificate transparency considerations apply.

Option 4: Coverage-gap documentation. Accept the visibility gap and document it formally in the NSM policy. This is the correct answer for organizations that cannot deploy QUIC inspection: document what cannot be detected, design compensating controls (flow analysis, DNS monitoring, endpoint telemetry), and review quarterly as QUIC detection tooling matures.


Architecture Comparison Sidebar: TCP+TLS vs. QUIC+TLS — NSM Visibility Matrix

Property TCP + TLS 1.2 TCP + TLS 1.3 QUIC + TLS 1.3
TLS SNI Plaintext Plaintext (until ECH) Plaintext in Initial (until ECH)
JA3/JA3S Full Full Partial/experimental
HTTP method Visible (HTTP/1.1) Visible (HTTP/1.1) Not visible (HTTP/3)
HTTP response code Visible Visible Not visible
Session resumption detection Visible (Session Ticket) Visible (Session Ticket) Partially (0-RTT indicator)
Connection migration tracking N/A (4-tuple fixed) N/A Connection ID required
Zeek ssl.log Full Full Partial (Initial frame only)
Zeek http.log Full (HTTP/1.1/2) Full None
Suricata content match Full Full Initial frame content only
Flow metadata Full Full Full

Design evolution framing: TCP+TLS was designed for a world where network operators had strong incentives to inspect traffic (enterprise security, CDN optimization, content filtering). QUIC was designed for a world where end-to-end encryption is the default and network operator visibility is explicitly deprioritized. The NSM community is adapting to a deployment reality where the assumption "I can see Layer-7 metadata on my own network" is progressively less true.


Reflection Prompts

  1. An organization blocks UDP/443 at its perimeter to preserve Zeek/Suricata HTTP-level visibility. What is the operational cost of this policy? Name two classes of applications that would degrade in performance and explain why.
  2. QUIC's 0-RTT session resumption reduces connection latency but introduces a replay attack surface. What conditions must an attacker meet to exploit 0-RTT replay? What does the QUIC specification say about what servers are permitted to do with 0-RTT data?
  3. The JA3 fingerprinting technique for QUIC is described as "partial/experimental" in the NSM visibility matrix. What specific information does JA3 for TCP extract from the TLS ClientHello, and which of those fields is or is not preserved in a QUIC Initial packet?