agent-sanitizer 2.14.3 → 2.14.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -8
- package/THREAT-MODEL.md +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,16 +13,16 @@ deterministic transform you can unit-test with equality assertions.
|
|
|
13
13
|
npm install agent-sanitizer
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
**As a Claude Code plugin
|
|
17
|
-
no `node_modules` and no build step:
|
|
16
|
+
**As a Claude Code plugin:**
|
|
18
17
|
|
|
19
18
|
```
|
|
20
19
|
/plugin marketplace add AlexanderMattTurner/agent-sanitizer
|
|
21
20
|
/plugin install agent-sanitizer@agent-sanitizer
|
|
22
21
|
```
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
[What installing entails](#what-installing-entails) covers the footprint of each
|
|
24
|
+
path and how a failure looks; [Using it with Claude
|
|
25
|
+
Code](#using-it-with-claude-code) covers each hook and hand-wiring.
|
|
26
26
|
|
|
27
27
|
## Quick start
|
|
28
28
|
|
|
@@ -93,11 +93,40 @@ owns each message, and any value outside the enum makes `sanitizeText` **throw**
|
|
|
93
93
|
| `filter-flagged` | The filter flagged the output as a possible injection without deleting (content intact) |
|
|
94
94
|
| `filter-error` | The filter reported a non-fatal internal error while scanning (a fatal filter throws) |
|
|
95
95
|
|
|
96
|
+
## What installing entails
|
|
97
|
+
|
|
98
|
+
Installing the plugin puts four hooks on every session, and this is what they
|
|
99
|
+
buy you:
|
|
100
|
+
|
|
101
|
+
1. Your `CLAUDE.md`, `AGENTS.md` and `.claude/` markdown are scanned at session
|
|
102
|
+
start for hidden-Unicode payloads and auto-cleaned where possible.
|
|
103
|
+
2. Prompts carrying payload-capable invisible or ANSI characters are blocked
|
|
104
|
+
before they reach the model; pasted terminal color passes with a note.
|
|
105
|
+
3. Look-alike glyphs in tool inputs are folded to ASCII, so a Cyrillic `а` can't
|
|
106
|
+
walk a command past a deny rule.
|
|
107
|
+
4. Tool output has invisible characters and terminal escapes stripped, hidden
|
|
108
|
+
HTML spliced out with a placeholder, and exfil-shaped URLs flagged.
|
|
109
|
+
5. Secrets in tool output are redacted locally by `detect-secrets` — the engine
|
|
110
|
+
ships with the plugin and provisions itself on first run, no setup from you.
|
|
111
|
+
6. Edits the model composes against the redacted view are re-anchored onto the
|
|
112
|
+
real bytes on disk, and anything ambiguous is denied rather than guessed.
|
|
113
|
+
7. The costs are a few seconds on the first secret-shaped output, ~200 ms on the
|
|
114
|
+
first web page, and the occasional over-redaction of credential-shaped text —
|
|
115
|
+
`AGENT_SANITIZER_OUTPUT_DISABLED=1` opts out of the rewrites.
|
|
116
|
+
|
|
117
|
+
Failure is loud by design: every layer fails closed, so you see suppressed tool
|
|
118
|
+
output (`[output sanitizer unavailable — original output suppressed]`), blocked
|
|
119
|
+
prompts, or permission asks whose reason names the cause. The exception is a
|
|
120
|
+
plugin that never loaded at all — Claude Code reads a crashed hook as "no
|
|
121
|
+
objection", so confirm with `/plugin` rather than reading a quiet session as a
|
|
122
|
+
working one.
|
|
123
|
+
|
|
96
124
|
## Using it with Claude Code
|
|
97
125
|
|
|
98
126
|
The plugin installed above puts four hooks on the tool stream: tool input, tool
|
|
99
127
|
output, user prompts, and a session-start scan of the instruction files. It
|
|
100
|
-
needs only `python3` on PATH, for Layer 4
|
|
128
|
+
needs only `python3` on PATH, for Layer 4 — the plugin ships the engine itself
|
|
129
|
+
(see [What installing entails](#what-installing-entails)).
|
|
101
130
|
|
|
102
131
|
```
|
|
103
132
|
/plugin marketplace add AlexanderMattTurner/agent-sanitizer
|
|
@@ -176,9 +205,11 @@ Beyond the credential-shaped names it infers, the env-bound redaction set unions
|
|
|
176
205
|
variable names whose values a deployment forwards under names of its own
|
|
177
206
|
choosing. A malformed entry throws rather than being dropped.
|
|
178
207
|
|
|
179
|
-
**Layer 4 needs the Python engine
|
|
180
|
-
|
|
181
|
-
|
|
208
|
+
**Layer 4 needs the Python engine.** The plugin ships it and provisions it at
|
|
209
|
+
SessionStart; a hand-wired npm install does not, so install it yourself —
|
|
210
|
+
`pip install 'agent-sanitizer[secrets]'`, version-matched to the npm package.
|
|
211
|
+
Without it `sanitize-output` fails closed: secret-shaped output is suppressed,
|
|
212
|
+
not shown unvetted. Layers 1–3 still run.
|
|
182
213
|
|
|
183
214
|
**Layer 5 (second-model injection filtering) is not included.** These hooks
|
|
184
215
|
never supply the `/output` seam's `filterInjection` callback, so nothing here
|
package/THREAT-MODEL.md
CHANGED
|
@@ -6,7 +6,13 @@ a detect/neutralize layer, not an enforcement boundary: it makes hidden content
|
|
|
6
6
|
visible-or-gone and surfaces exfil-shaped URLs, so the model and the operator
|
|
7
7
|
see the same thing. Egress controls remain your enforcement layer.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Five sanitization layers are documented below — invisible characters/ANSI (1),
|
|
10
|
+
hidden HTML (2), exfil URLs (3), secret redaction (4, an injected redactor) and
|
|
11
|
+
injection filtering (5, an injected filter the caller wires) — plus the entry
|
|
12
|
+
points built on them: confusable folding, instruction-file scanning, the
|
|
13
|
+
user-prompt verdict and edit rehydration. All are independent; use only the ones
|
|
14
|
+
your ingress needs. The README's [entry-point
|
|
15
|
+
table](./README.md#entry-points) maps each to its import.
|
|
10
16
|
|
|
11
17
|
## Layer 1—invisible characters & ANSI (zero-dependency)
|
|
12
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-sanitizer",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.5",
|
|
4
4
|
"description": "Defend an agent against hidden-content injection: strip payload-capable invisible Unicode and ANSI, splice out human-invisible HTML, and flag data-exfil URLs in untrusted text before any model sees it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|