SECURITY REFERENCEv0.2.0 / 2026-02-20

Threat Model

What mcpwall protects against, what it doesn’t, and the assumptions it makes. This document is intentionally transparent. Security tools that hide their limitations aren’t security tools.

01 / Scope

What mcpwall is

mcpwall is a rule-based request firewall for MCP tool calls. It sits as a transparent stdio proxy between your AI coding tool (Claude Code, Cursor, etc.) and the MCP server. Every JSON-RPC message from the client passes through the policy engine before reaching the server.

Rules are YAML, evaluated top-to-bottom, first match wins. Actions are allow, deny, or ask. No AI, no cloud, no network calls. Deterministic: same input + same rules = same output.

Data flow
Claude Code→ stdin →mcpwall→ stdin →MCP Server
Claude Code← stdout ←mcpwall (log only)← stdout ←MCP Server
Inbound: every request inspected & filtered  |  Outbound: responses inspected, secrets redacted, injection blocked (v0.2.0)

Bidirectional scanning: mcpwall inspects both requests (client → server) and responses (server → client). Outbound rules can redact leaked secrets, block prompt injection patterns, and flag suspicious content.

02 / Trust Boundaries

What mcpwall inspects

BoundaryInspected?Detail
Client → Server (stdin)InspectedEvery JSON-RPC message evaluated against policy rules
Server → Client (stdout)InspectedResponses evaluated against outbound rules. Secrets redacted, injection blocked. (v0.2.0)
Server stderrNot inspectedInherited by child process; passes through to parent stderr
Environment variablesNot inspectedInherited from parent process; spawned server receives full env
Server side effectsNot inspectedFile I/O, network calls, and other actions by the server process itself
Config filesAt load timeValidated with Zod at startup; not re-verified during execution
03 / What mcpwall covers

Attack classes mitigated

The 8 default deny rules and supporting engine features cover these attack classes out of the box. Custom rules can extend coverage further.

Attack classStatusDefault ruleMechanism
SSH key theftCoveredblock-ssh-keysRegex on all argument values: \.ssh/, id_rsa, id_ed25519, id_ecdsa
.env file accessCoveredblock-env-filesRegex: /\.env($|\.)
Credential file accessCoveredblock-credentialsRegex: AWS credentials, .npmrc, Docker config, kube config, .gnupg
Browser data theftCoveredblock-browser-dataRegex: Chrome/Firefox/Safari profile paths, Cookies, Login Data
Destructive commandsCoveredblock-destructive-commandsRegex: rm -rf, mkfs, dd if=, format C:
Pipe-to-shell (curl|bash)Coveredblock-pipe-to-shellRegex: curl/wget/fetch piped to bash/sh/zsh/python/node
Reverse shellsCoveredblock-reverse-shellsRegex: netcat, /dev/tcp/, bash -i, mkfifo, socat
Secret/API key leakageCoveredblock-secret-leakage10 secret patterns (AWS, GitHub, OpenAI, Stripe, etc.) + Shannon entropy threshold
JSON-RPC batch bypassMitigatedn/aEach message in a batch is individually evaluated (C1 fix, v0.1.1)
ReDoS in configMitigatedHeuristic detection of nested quantifiers at config load time
Symlink path traversalMitigatedrealpathSync resolves symlinks for not_under matcher (existing paths only)
Process crash on bad inputMitigatedtry-catch in proxy hot path; fails open (forwards raw line, stays alive)
04 / What mcpwall does NOT cover

Known limitations

These are attack classes that mcpwall does not yet mitigate. Some are planned for future versions; others are out of scope by design.

Attack classSeverityStatusDetail
Response-side attacksHIGHCoveredServer responses scanned for secrets (redacted) and prompt injection patterns (blocked). Zero-width characters and large responses flagged. Added in v0.2.0.
Base64/URL encoding bypassHIGHNot coveredSecret patterns and command regexes only match literal strings. Base64-encoded secrets or URL-encoded commands bypass rules.
Rate limiting / DoSHIGHNot coveredNo throttling on tool call volume. A runaway agent can make unlimited calls. Planned for v0.4.0.
Tool description poisoningMEDIUMNot coveredmcpwall does not inspect or validate tool metadata from tools/list responses. Rug pull detection planned for v0.3.0.
Prompt injectionMEDIUMNot coveredSemantic attacks that manipulate the LLM into making dangerous tool calls. mcpwall sees the resulting call, not the manipulation — it may still catch the dangerous arguments.
Unicode/homograph tricksMEDIUMNot coveredZero-width characters, combining characters, or homoglyph substitutions may bypass regex patterns.
Shell metacharacter bypassMEDIUMPartialPipe (|) detected in rule 6. Semicolons (;), &&, ||, backticks, and $() not explicitly covered by default rules.
DNS exfiltrationMEDIUMNot coveredSecrets encoded in DNS subdomains (e.g., exfil-data.attacker.com) are not detected. No DNS-level inspection.
Environment variable leakageMEDIUMOut of scopeSpawned server inherits the full environment from mcpwall’s process. Env sanitization is the user’s responsibility.
Deep nesting stack overflowLOWPartialRecursive argument scanning has no max-depth limit. Deeply nested objects could exhaust the stack. 10MB line buffer limits total size.
Config tampering (TOCTOU)LOWNot coveredConfig loaded once at startup, not re-verified. Filesystem permissions are the user’s responsibility.
Log tamperingLOWNot coveredJSONL audit logs have no signing or integrity verification. An attacker with filesystem access can modify them.
Timing side-channelsLOWNot coveredRule evaluation is not constant-time. An attacker could theoretically infer rule matches from response latency. Low practical risk.
05 / Default Rules

The 8 built-in deny rules

These rules ship with mcpwall and apply automatically. No configuration needed. They match against tools/call requests and scan all argument values recursively using the _any_value matcher.

DENY
block-ssh-keys
Blocks any tool call where an argument value matches \.ssh/, id_rsa, id_ed25519, or id_ecdsa.
DENY
block-env-files
Blocks access to .env files and variants (.env.local, .env.production, etc.).
DENY
block-credentials
Blocks access to .aws/credentials, .npmrc, .docker/config.json, .kube/config, and .gnupg/.
DENY
block-browser-data
Blocks access to Chrome, Firefox, and Safari profile directories, cookies, and login data stores.
DENY
block-destructive-commands
Blocks rm -rf, rm -f, rmdir /, mkfs, dd if=, and format [drive]: patterns.
DENY
block-pipe-to-shell
Blocks curl/wget/fetch piped to bash/sh/zsh/python/node.
DENY
block-reverse-shells
Blocks netcat listeners, /dev/tcp/, bash -i redirects, mkfifo, and socat patterns.
DENY
block-secret-leakage
Scans all argument values for 10 secret patterns: AWS keys, GitHub tokens, OpenAI/Anthropic/Stripe keys, private key headers, JWTs, Slack tokens, and database URLs. Uses Shannon entropy thresholds to reduce false positives.
06 / Assumptions

What must be true

mcpwall’s security guarantees depend on these assumptions holding. If any are violated, the threat model changes.

RUNTIME
Node.js is trusted
mcpwall runs on Node.js. If the runtime has exploitable vulnerabilities, all bets are off.
FILESYSTEM
Config files are user-owned
YAML config and rules files must be owned and readable only by the user. mcpwall does not verify file permissions.
TRANSPORT
stdio carries valid JSON-RPC
Messages are newline-delimited JSON-RPC 2.0 over stdin/stdout. Non-stdio transports (HTTP/SSE) are not yet supported.
PROCESS
Server is the intended binary
mcpwall spawns whatever command you configure. If the command has been replaced with an attacker-controlled binary, mcpwall cannot detect this.
CONFIG
Config not modified during run
Rules are loaded once at startup. Config changes require a restart. There is no hot-reload or runtime integrity check.
PATTERNS
User regexes are safe
Custom regex patterns in user config are validated for basic ReDoS risk but not exhaustively analyzed. Users are responsible for their own patterns.
07 / Component Analysis

Module-by-module

policy.ts — Policy Engine

Evaluates rules top-to-bottom, first match wins. Supports glob, regex, not_under, and _any_value matchers. Recursive scanning walks all argument values including arrays and nested objects.

Limitation: Recursive scanning (deepMatchAny) has no max-depth limit. Extremely deep nesting could cause a stack overflow. The 10MB line buffer limits total message size but not depth.

secrets.ts — Secret Scanner

10 built-in patterns (AWS, GitHub, OpenAI, Anthropic, Stripe, private keys, JWT, Slack, database URLs). Pre-compiled regexes with optional Shannon entropy threshold to reduce false positives.

Limitation: Pattern-based only. Custom API key formats not matching built-in patterns will not be detected unless added by the user. No base64/URL decoding before matching.

parser.ts — JSON-RPC Parser

Line-buffered parser with 10MB max line limit. Handles both single messages and JSON-RPC batch arrays. Each batch item validated individually (jsonrpc: "2.0" check).

Limitation: Oversized lines are discarded with a stderr warning. Incomplete JSON is silently forwarded (tolerant of non-JSON-RPC traffic).

proxy.ts — Stdio Proxy

Spawns the MCP server as a child process. Inbound path: evaluate each message, deny or forward. Outbound path: log and forward (no filtering). Batch handling evaluates each message individually; denied messages return JSON-RPC errors.

Limitation: On parsing/evaluation errors, the raw line is forwarded to maintain the connection. Signal handling forwards SIGINT/SIGTERM to child with SIGKILL escalation after 5 seconds.

logger.ts — Audit Logger

Writes structured JSONL entries to daily-rotated files + stderr. Arguments for denied calls are redacted ([REDACTED]) to prevent secret leakage in logs.

Safeguard: No log signing or integrity verification. No size-based rotation (daily only). Write errors degrade gracefully to stderr-only logging.

config/loader.ts — Config Loader

Loads YAML config with Zod validation. Merges project config over global config (project rules take priority). Variable substitution for ${HOME}, ${PROJECT_DIR}, ~/.

Safeguard: Falls back to hardcoded default rules if files not found. ReDoS detection applied to all regex patterns at load time. Variable substitution is simple text replacement (no eval).

08 / Defense in Depth

Where mcpwall fits

mcpwall is one layer in a defense-in-depth strategy. It is not a complete security solution on its own. We recommend combining it with:

LAYER 1
Install-time scanning
Tools like mcp-scan check tool descriptions for suspicious content before you use a server.
LAYER 2
Runtime firewall (mcpwall)
Enforces policy on every tool call as it happens. Catches what scanners miss: runtime arguments, secrets in transit, dangerous commands.
LAYER 3
Container isolation
Run MCP servers in containers or sandboxes to limit blast radius if a server is compromised.
09 / Planned Mitigations

What’s coming

FeatureVersionAddresses
Response inspection Shippedv0.2.0Outbound rules scan responses for secrets (redact), prompt injection (block), zero-width chars, and large payloads (flag)
Tool integrity / rug pull detectionv0.3.0Hash tool descriptions at first use, detect changes on subsequent calls
HTTP/SSE proxy modev0.3-0.4Support remote MCP servers over HTTP/SSE, not just stdio
Rate limitingv0.4.0Throttle excessive tool calls within configurable time windows
10 / Security Reporting

Found something?

If you find a security vulnerability in mcpwall, please report it responsibly. Email info@behrens-ai.de or open a security advisory on GitHub.

This threat model is maintained alongside the codebase and updated with each release. The source is at github.com/behrensd/mcpwall.