agent-sanitizer 2.55.0 → 2.56.1
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
CHANGED
|
@@ -164,7 +164,12 @@ buy you:
|
|
|
164
164
|
3. Look-alike glyphs in tool inputs are folded to ASCII, so a Cyrillic `а` can't
|
|
165
165
|
walk a command past a deny rule.
|
|
166
166
|
4. Tool output has invisible characters and terminal escapes stripped, hidden
|
|
167
|
-
HTML spliced out with a placeholder, and exfil-shaped URLs flagged.
|
|
167
|
+
HTML spliced out with a placeholder, and exfil-shaped URLs flagged. A hex
|
|
168
|
+
value one digest wide is exempt under a generic query or fragment parameter
|
|
169
|
+
name, because a commit or blob id in a link is ordinary — under a name that
|
|
170
|
+
already says credential it still flags, and a path segment never reaches the
|
|
171
|
+
exemption at all. `AGENT_SANITIZER_FLAG_DIGEST_VALUES=1` turns it off for a
|
|
172
|
+
consumer that reads such a value as a leak.
|
|
168
173
|
5. With `AGENT_SANITIZER_SECRETS_ENABLED=1` set, secrets in tool output are
|
|
169
174
|
redacted locally by `detect-secrets` — the engine ships with the plugin and
|
|
170
175
|
provisions itself on first run, no further setup from you.
|
|
@@ -238,6 +238,24 @@ export function secretsEnabled(env = process.env) {
|
|
|
238
238
|
return env[SECRETS_ENABLED_ENV] === "1";
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
// Layer 3's digest exemption, which lets a URL carry an exact-digest-length hex
|
|
242
|
+
// value without being read as a payload. A consumer that treats a digest in a
|
|
243
|
+
// URL as exfil — a monitor reading tool output for a leaked commit or blob id —
|
|
244
|
+
// turns the exemption off here. `checkExfilUrl` takes the same option directly;
|
|
245
|
+
// this is the switch for the hook path, which composes its own seam options.
|
|
246
|
+
export const FLAG_DIGEST_VALUES_ENV = "AGENT_SANITIZER_FLAG_DIGEST_VALUES";
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* True when the operator opted into flagging digest-shaped URL values. `=== "1"`
|
|
250
|
+
* for the reason {@link secretsEnabled} gives: a typo fails toward the default,
|
|
251
|
+
* which is the exemption the precision rule prefers.
|
|
252
|
+
* @param {NodeJS.ProcessEnv | Record<string, string | undefined>} [env]
|
|
253
|
+
* @returns {boolean}
|
|
254
|
+
*/
|
|
255
|
+
export function digestFlaggingEnabled(env = process.env) {
|
|
256
|
+
return env[FLAG_DIGEST_VALUES_ENV] === "1";
|
|
257
|
+
}
|
|
258
|
+
|
|
241
259
|
/**
|
|
242
260
|
* The env-bound redaction set: the UNION of the inference keys, the curated host
|
|
243
261
|
* credentials, any credential-shaped var present in the environment, the
|
|
@@ -49,7 +49,7 @@ import { registerFaultPolicy, hookFaultOutcome } from "./lib/hook-fault.mjs";
|
|
|
49
49
|
import { controlPlane, runJudgeCli } from "./lib/control-plane.mjs";
|
|
50
50
|
import { bestEffortTrace, trace, TraceEvent } from "./lib/trace.mjs";
|
|
51
51
|
import { hasEnvBoundSecret } from "./lib/secret-annotate.mjs";
|
|
52
|
-
import { secretsEnabled } from "./lib/env-config.mjs";
|
|
52
|
+
import { digestFlaggingEnabled, secretsEnabled } from "./lib/env-config.mjs";
|
|
53
53
|
import {
|
|
54
54
|
persistReveal,
|
|
55
55
|
persistSpan,
|
|
@@ -267,6 +267,10 @@ export async function sanitizeText(
|
|
|
267
267
|
const seamOptions = {
|
|
268
268
|
html,
|
|
269
269
|
exfilScan: webIngress,
|
|
270
|
+
// Widens Layer 3 only, and only where the operator asked: without it the
|
|
271
|
+
// option the seam already accepts is unreachable from this entry, so a hook
|
|
272
|
+
// consumer that needs a digest in a URL flagged has no way to ask for it.
|
|
273
|
+
flagDigestValues: digestFlaggingEnabled(),
|
|
270
274
|
sgrCarveOut: !webIngress,
|
|
271
275
|
deadline,
|
|
272
276
|
// Layer 4 — OPT-IN (secretsEnabled): with the knob unset the seam gets no
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-sanitizer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.56.1",
|
|
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": {
|
|
@@ -67,6 +67,14 @@ export function extraSecretVars(env?: Record<string, string | undefined>): strin
|
|
|
67
67
|
* @returns {boolean}
|
|
68
68
|
*/
|
|
69
69
|
export function secretsEnabled(env?: NodeJS.ProcessEnv | Record<string, string | undefined>): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* True when the operator opted into flagging digest-shaped URL values. `=== "1"`
|
|
72
|
+
* for the reason {@link secretsEnabled} gives: a typo fails toward the default,
|
|
73
|
+
* which is the exemption the precision rule prefers.
|
|
74
|
+
* @param {NodeJS.ProcessEnv | Record<string, string | undefined>} [env]
|
|
75
|
+
* @returns {boolean}
|
|
76
|
+
*/
|
|
77
|
+
export function digestFlaggingEnabled(env?: NodeJS.ProcessEnv | Record<string, string | undefined>): boolean;
|
|
70
78
|
/**
|
|
71
79
|
* The env-bound redaction set: the UNION of the inference keys, the curated host
|
|
72
80
|
* credentials, any credential-shaped var present in the environment, the
|
|
@@ -79,3 +87,4 @@ export function secretsEnabled(env?: NodeJS.ProcessEnv | Record<string, string |
|
|
|
79
87
|
*/
|
|
80
88
|
export function envBoundSecretVars(env?: Record<string, string | undefined>): string[];
|
|
81
89
|
export const SECRETS_ENABLED_ENV: "AGENT_SANITIZER_SECRETS_ENABLED";
|
|
90
|
+
export const FLAG_DIGEST_VALUES_ENV: "AGENT_SANITIZER_FLAG_DIGEST_VALUES";
|