In-Memory MITM TLS Proxy
Thenetwork channel inspects all outbound HTTP and HTTPS egress traffic by running an ephemeral, in-memory loopback proxy on 127.0.0.1:<random-port>.
It is completely air-gapped: no external telemetry or third-party validation servers are contacted. All decryption and scanning happen locally in RAM.
1. Ephemeral Root Certificate Authority (CA)
Before spawning your application process,envtrap creates a dedicated 2048-bit RSA Root Certificate Authority in memory:
- RAM-Only Key Material: The Root CA private key is generated with Node’s native
crypto.generateKeyPairSyncand retained exclusively in RAM. It is never written to disk. - Child Process Trust: The public certificate (
ca.crt) is written to a temporary folder with restrictive file permissions (0o600) inos.tmpdir().envtrappointsNODE_EXTRA_CA_CERTSto this file so Node.js trusts it automatically without modifying system settings. - Optional System CA Trust: If run with sufficient permissions (e.g. root/admin or on macOS/Windows),
SystemCaTrustcan register the certificate into OS trust stores (security,certutil,update-ca-certificates) to protect non-Node subprocesses likecurlor Python scripts. - Automated Cleanup: When the application shuts down or receives
SIGINT/SIGTERM, the temporary CA files and OS trust certificates are purged immediately.
2. HTTPS Decryption Flow: The Two-Wire Model
When your application initiates an HTTPS request (e.g.fetch("https://api.stripe.com/v1/charges")), traffic is routed through the proxy via HTTP_PROXY and HTTPS_PROXY:
Step-by-Step Breakdown:
- CONNECT Tunneling: The client asks the proxy to open a raw TCP tunnel to
target-host:443. - On-The-Fly Certificate Minting:
envtrapdynamically generates an X.509 server certificate fortarget-host, signed by the in-memory Root CA. Domain certificates are cached in memory for sub-millisecond reuse. - Local Handshake (Wire #1): The client performs a TLS handshake with
envtrap. Because Node was configured withNODE_EXTRA_CA_CERTS, the client accepts the forged certificate. - Decryption & Inspection:
envtrapdecrypts the incoming TLS packets into plain text to scan headers, URLs, and bodies. - Upstream Forwarding (Wire #2): If clean,
envtrapopens a genuine, external TLS socket to the real remote host, verifies the real server certificate, and relays the payload.
3. Streaming Inspection & Security Gating
TlsInterceptor protects against packet fragmentation, split-secret bypasses, and protocol deadlocks:
A. HTTP Header Pre-Buffering & Early Chunk Gating
HTTP requests often arrive in fragmented TCP packets. If an authorization header containing a secret arrives in Packet 1 and body data in Packet 2, streaming directly upstream would leak the secret before inspection finishes.envtrapbuffers initial chunks inheaderBufferuntil the end-of-headers delimiter\r\n\r\nis matched.- The entire header block is scanned. Only once verified as clean is it transmitted upstream.
B. Dynamic Sliding-Window Overlap
A secret token may straddle two sequential TCP packets (half in Chunk 1, half in Chunk 2):- Adaptive Sizing: The window size is dynamically set to
Math.min(8192, Math.max(200, maxSecretLength))based on the longest secret in your environment. - Low Memory Footprint: No need to buffer multi-gigabyte files in RAM; only a tiny sliding overlap is maintained.
C. Non-HTTP Raw TLS Detection
Non-HTTP TLS traffic (such as PostgreSQL, Redis, or MQTT over TLS) does not emit HTTP headers (\r\n\r\n).
envtrapsniffs the first 4–10 bytes for standard HTTP verbs (GET,POST,PUT, etc.).- If non-HTTP traffic is identified,
envtrapimmediately bypasses HTTP header gating, preventing socket deadlocks.
D. EOF Verification
If an attacker or malicious dependency abruptly drops or closes the socket (tlsSocket.on('end')), any remaining unflushed bytes in memory are scanned for secrets before the upstream connection is torn down.
4. Loopback & Domain Exclusions
To avoid intercepting internal microservices or authorized cloud services:- Automatic Loopback Bypass:
NO_PROXYis automatically populated with: - Domain Exclusions: Domains specified in
exclusions.domains(inenvtrap.json) are automatically appended toNO_PROXY. Connections to these hosts bypass the proxy entirely, allowing raw, unmodified native socket speeds.
