Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Known gaps

Detection is regex-based and only ever sees request and response bodies. These are the gaps that follow from that, written down so they are decisions you make rather than surprises you discover.

If you find one that isn’t here, please open an issue. See SECURITY.md for the smaller set of findings that go through private reporting instead.

Your folder name

The most important one, and the one redaction cannot fix.

Claude Code puts its working directory, and a project-memory directory name derived from it, into the system field of every request. That field is deliberately never scanned: it is Anthropic’s own prompt boilerplate, and blanket-scanning it does more harm than good.

So a folder called acme-bank-pentest sends “acme bank” to the model on every single request, bypassing every block and allow rule no matter how thorough rules.json is. The redaction engine never sees that text.

There is no fix in the tool. There is nothing to tokenize against, because the path is not part of the body the proxy edits. Name engagement folders after an engagement code, never after the client.

redactproxy checks for this. If your working directory matches one of your own block entries, the wizard warns when you set up and the proxy warns at startup and on every rule reload:

level=WARN msg="current directory matches a block-list pattern and WILL be sent
to the upstream API unredacted..." cwd=/home/you/acme-bank-pentest

That check only fires when the folder name matches a rule you already added. It cannot catch a client name you never told it about.

Encoded data

A config file piped through base64, an xxd dump, Terraform state, a gzipped blob: all of it goes straight through. Encoded text does not look like a domain, an email, or a credential to a regex.

Decode it locally and look at it first. The CLAUDE.md note tells Claude to decode to a file with Bash and read the file back, so the decoded content gets a normal pass through redaction instead of arriving unprotected in Claude’s own output. See Configuring Claude Code.

Names and prose

Only recognizable shapes get detected. Client names, trading names, product names, codenames, employee names in prose: none of them have a shape. Add them with rules block, which is what the wizard’s first prompt is for.

This is the gap with the widest blast radius after the folder name, because a company name appears in URL paths, ticket references, code comments, commit messages and file names, none of which any detector can recognize.

Bare apex domains on file-extension TLDs

.do, .ai, .rs, .sh, .py and friends are not detected as bare apex domains, because main.rs and logo.ai are far more often filenames, and a detector that fires on those costs more than one that misses an edge case.

Add the client’s apex domain with rules block --domain when it sits on one of those. Subdomains and URLs on such a TLD are still detected normally; it is specifically the bare apex form that is excluded.

thinking blocks

Thinking content is signed by the API. The text and its signature together are a cryptographic proof the API validates on replay, so any edit invalidates it and the next request fails.

That means thinking blocks pass through unmodified in both directions. If a real value reaches the model some other way, the model can restate it in a thinking block, and that restatement is permanent for the life of the conversation. Start a new conversation if that happens.

HTTP headers

Forwarded verbatim, never inspected. This is what makes credential passthrough work, and it means anything carried in a header is not redacted.

Claude Code’s transcripts and your scrollback

Claude Code stores the real values you saw on screen, because detokenization happens before the response reaches it. Same for terminal scrollback. The proxy controls what reaches the provider, not what stays on your machine.

Handle those under the same rules as the rest of the engagement data.

Claude Code’s non-proxied traffic

Feature flags, token refresh, and several tools do not go through ANTHROPIC_BASE_URL at all. The wizard’s settings hardening closes what configuration can close: the Artifact tool (a confirmed leak path publishing unredacted to claude.ai), Remote Control, and the WebFetch preflight that sends target hostnames to Anthropic directly.

If you didn’t run the wizard, the proxy warns at startup and lists exactly what is missing. See Configuring Claude Code.

Over-redaction

The opposite failure, and mostly harmless. The proxy inspects text with no notion of code structure, so something merely domain-shaped (table.style, where .style is a real suffix) can get tokenized.

Operationally this costs nothing: the real value is substituted back before anything executes, on every response rather than just the first, so commands run correctly regardless. Fix it permanently with rules allow, and drop the mapping already minted with tokens remove.

Detection is best-effort, not a guarantee

The detector set covers the shapes that show up in pentest work and is tested against a realistic corpus (nmap, whois, dig, gobuster, Metasploit output) plus a false-positive trap corpus. It is not a proof of coverage.

Two things nobody has built yet, if you want the gaps closed: a local NER model for prose-shaped PII, and more Windows/AD artifacts (UNC paths, domain\username, LDAP DN components). See CONTRIBUTING.md.

Where rules do and don’t reach back

Rule changes only affect text tokenized from that point on. Adding a block rule does not scrub a value that already reached the model earlier in the same conversation. Start a fresh conversation if that matters.

Disabling a category likewise only gates future detection. Anything already tokenized keeps detokenizing correctly.