SSL Decrypt / MITM / SSL/TLS Inspection
SSL Decrypt is a security technique used by proxies, firewalls, and
secure web gateways (such as Netskope, Zscaler, Palo Alto, etc.) to
inspect the contents of HTTPS traffic that would otherwise be encrypted
and unreadable.
Core Idea is:
- The proxy temporarily terminates the encrypted connection
from the client, decrypts the traffic, inspects it
- Proxy then creates a new encrypted connection to the destination server.
- 2 encrypted channels exist. 1 from Client to proxy other from Proxy to
Server.
Browser <--TLS--> Proxy <--TLS--> Google
Key Characteristics
* Forged Leaf Certificate: Proxy terminates the Client TLS Connection using its own
forged leaf certificate.
* Seperate TLS Connections: Proxy opens a new TLS connection with upstream server,
and TLS connection with client. It helps inspecting the packet in both directions
* Proxy Root CA Installed on Client: For client to trust forged certificate, proxy's
ROOT CA certificate must be installed on Browser Client's Trust Store.
Flow
1. Client Requests a Website (Browser → https://google.com)
2. Proxy Intercepts the traffic
3. Proxy Creates Its Own TLS Session to google (Proxy → Google)
4. Using Emphemeral CA proxy generates CA Cert(CN = google.com, Issuer =
Corporate CA)
5. proxy sends this cert to Browser, Since Client has already installed
trusted root certificate from proxy into "Trusted Certificate Store",
Client browser accepts the cert
6. Traffic arrives encrypted from browser. Proxy decrypts it. Now it can
inspect
7. After inspection, Proxy encrypts again and sends traffic to Google.
Why HTTP Connect?
Simple Flow
@startuml
actor Client as "Client\nBrowser"
box ZeroTrustForwardProxy
participant server as "server.go"
participant dlp as "DLP Module"
end box
participant Metrics as "Observability/\nGrafanna"
participant Upstream as "Origin Server/\ngoogle.com"
Client -> server: HTTPS CONNECT google.com:443
note over server
Hijack conn=HTTPS
end note
server --> Client: 200 Connection Established
Client -> server: TLS ClientHello
note over server
extractSNI from ClientHello
end note
server -> server: "evaluatePolicy \nbased on sni"
alt bypass
server -> server: use bypass path
server -> Upstream: establish TLS connection
else mitm (ie Intercept HTTPS)
server -> server: "select/issue leaf\n cert via GetCertificate"
server -> Client: complete TLS handshake with forged certificate
server -> Upstream: complete TLS handshake with Origin server
Client -> server: HTTPS request
server -> server: InspectRequest(req)
server -> dlp: Do DLP inspection
dlp -> server: Result
note over server
Apply policy
based on result
end note
server -> Upstream: HTTPS(forward request)
Upstream -> server: HTTPS(Reply)
server -> server: Decrypt and Inspect response
server -> Client: HTTPS(Response)
end
server -> Metrics: ObserveHandshake()/Record*()
server -> server: log audit/event
@enduml
Detialed Flow
@startuml
title proxy — SSL Interception (Ephemeral CA MITM)
skinparam sequenceArrowThickness 2
skinparam BoxPadding 10
actor "Browser / Client" as C
box ForwardProxy
participant "Proxy" as P #Tomato
participant "Ephemeral CA" as CA #lightPink
end box
participant "Origin Server/\ngoogle.com" as S #GreenYellow
== Phase 1: CONNECT Tunnel Setup ==
C -> P: HTTP CONNECT google.com:443
P --> C: 200 Connection Established\n(TCP tunnel open, no TLS yet)
== Phase 2: Client-side TLS Handshake (Proxy acts as server) ==
C -> P: TLS ClientHello (SNI = "bank.com")
activate P
note right of P: GetCertificate()\nSNI = "google.com" extracted.
P -> CA: Request leaf cert for "google.com"
activate CA
note right of CA
1. Check cache
2. Cache miss → GenerateKey(P-256)
3. x509.CreateCertificate(
CN=google.com, SAN=google.com,
NotAfter=+1h,
Issuer=Ephemeral CA
)
4. Store in cache
end note
CA --> P: *tls.Certificate { leaf: google.com }
deactivate CA
P --> C: TLS ServerHello +\nCertificate(CN=google.com, signed by ephemeral CA) +\nServerHelloDone
C -> P: ClientKeyExchange + Finished
P -> C: Finished
note over C,P #Aqua
Left-side TLS established.
Proxy decrypts client traffic.
end note
== Phase 3: Upstream TLS Handshake (Proxy acts as client) ==
P -> S: TCP connect + TLS ClientHello (SNI = "google.com")
activate S
S --> P: TLS ServerHello + Certificate(google.com cert) + ServerHelloDone
note right of P
Proxy validates real cert
against system CA bundle.
Real cert SANs are NOT copied
to the forged cert — only SNI
is used as CN/SAN.
end note
P -> S: ClientKeyExchange + Finished
S --> P: Finished
note over P,S #Aqua
Right-side TLS established.
Proxy can inspect upstream traffic.
end note
deactivate S
== Phase 4: Bidirectional Inspection ==
C -> P: Encrypted HTTP Request (plaintext after decrypt)
note right of P
Proxy reads plaintext:
• Policy check
• DLP, TSS scan
• MCP inspection
end note
P -> S: Re-encrypted HTTP Request
S --> P: Encrypted HTTP Response
P --> C: Re-encrypted HTTP Response
deactivate P
@enduml