@aimarket/warden 0.8.2 → 0.13.0

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.
Files changed (117) hide show
  1. package/CHANGELOG.md +55 -1
  2. package/README-es.md +45 -10
  3. package/README-fr.md +45 -10
  4. package/README-ru.md +47 -10
  5. package/README-zh.md +45 -10
  6. package/README.md +47 -10
  7. package/dist/classifier.d.ts +79 -0
  8. package/dist/classifier.d.ts.map +1 -0
  9. package/dist/classifier.js +360 -0
  10. package/dist/classifier.js.map +1 -0
  11. package/dist/claude-hook.d.ts +53 -0
  12. package/dist/claude-hook.d.ts.map +1 -0
  13. package/dist/claude-hook.js +192 -0
  14. package/dist/claude-hook.js.map +1 -0
  15. package/dist/encoded-text.d.ts +7 -0
  16. package/dist/encoded-text.d.ts.map +1 -0
  17. package/dist/encoded-text.js +63 -0
  18. package/dist/encoded-text.js.map +1 -0
  19. package/dist/fold.d.ts +1 -2
  20. package/dist/fold.d.ts.map +1 -1
  21. package/dist/fold.js +3 -2
  22. package/dist/fold.js.map +1 -1
  23. package/dist/histor.d.ts +104 -0
  24. package/dist/histor.d.ts.map +1 -0
  25. package/dist/histor.js +86 -0
  26. package/dist/histor.js.map +1 -0
  27. package/dist/index.d.ts +6 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +8 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp-client.d.ts +58 -0
  32. package/dist/mcp-client.d.ts.map +1 -0
  33. package/dist/mcp-client.js +451 -0
  34. package/dist/mcp-client.js.map +1 -0
  35. package/dist/mcp-rpc.js +1 -1
  36. package/dist/mcp-server.js +8 -0
  37. package/dist/mcp-server.js.map +1 -1
  38. package/dist/mcp-tools.d.ts.map +1 -1
  39. package/dist/mcp-tools.js +29 -4
  40. package/dist/mcp-tools.js.map +1 -1
  41. package/dist/mtl.d.ts +28 -0
  42. package/dist/mtl.d.ts.map +1 -0
  43. package/dist/mtl.js +77 -0
  44. package/dist/mtl.js.map +1 -0
  45. package/dist/pin-store.d.ts.map +1 -1
  46. package/dist/pin-store.js +1 -0
  47. package/dist/pin-store.js.map +1 -1
  48. package/dist/pinning.d.ts +1 -1
  49. package/dist/pinning.d.ts.map +1 -1
  50. package/dist/pinning.js +12 -4
  51. package/dist/pinning.js.map +1 -1
  52. package/dist/result-screen.d.ts +19 -0
  53. package/dist/result-screen.d.ts.map +1 -0
  54. package/dist/result-screen.js +86 -0
  55. package/dist/result-screen.js.map +1 -0
  56. package/dist/scan-cli.d.ts +3 -0
  57. package/dist/scan-cli.d.ts.map +1 -0
  58. package/dist/scan-cli.js +36 -0
  59. package/dist/scan-cli.js.map +1 -0
  60. package/dist/scan-config.d.ts +72 -0
  61. package/dist/scan-config.d.ts.map +1 -0
  62. package/dist/scan-config.js +239 -0
  63. package/dist/scan-config.js.map +1 -0
  64. package/dist/scan-lock.d.ts +46 -0
  65. package/dist/scan-lock.d.ts.map +1 -0
  66. package/dist/scan-lock.js +113 -0
  67. package/dist/scan-lock.js.map +1 -0
  68. package/dist/scan-report.d.ts +21 -0
  69. package/dist/scan-report.d.ts.map +1 -0
  70. package/dist/scan-report.js +288 -0
  71. package/dist/scan-report.js.map +1 -0
  72. package/dist/scan.d.ts +177 -0
  73. package/dist/scan.d.ts.map +1 -0
  74. package/dist/scan.js +754 -0
  75. package/dist/scan.js.map +1 -0
  76. package/dist/static-scan.d.ts +4 -3
  77. package/dist/static-scan.d.ts.map +1 -1
  78. package/dist/static-scan.js +227 -11
  79. package/dist/static-scan.js.map +1 -1
  80. package/dist/tool-list.d.ts +34 -0
  81. package/dist/tool-list.d.ts.map +1 -0
  82. package/dist/tool-list.js +57 -0
  83. package/dist/tool-list.js.map +1 -0
  84. package/dist/toxic-flow.d.ts +33 -0
  85. package/dist/toxic-flow.d.ts.map +1 -0
  86. package/dist/toxic-flow.js +117 -0
  87. package/dist/toxic-flow.js.map +1 -0
  88. package/dist/types.d.ts +12 -0
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/wrap-cli.d.ts +3 -0
  91. package/dist/wrap-cli.d.ts.map +1 -1
  92. package/dist/wrap-cli.js +17 -6
  93. package/dist/wrap-cli.js.map +1 -1
  94. package/dist/wrap-state.js +2 -2
  95. package/dist/wrap-state.js.map +1 -1
  96. package/dist/wrap.d.ts.map +1 -1
  97. package/dist/wrap.js +22 -35
  98. package/dist/wrap.js.map +1 -1
  99. package/docs/gates.es.md +40 -7
  100. package/docs/gates.fr.md +39 -6
  101. package/docs/gates.md +38 -7
  102. package/docs/gates.ru.md +40 -7
  103. package/docs/gates.zh.md +10 -5
  104. package/docs/scan.es.md +199 -0
  105. package/docs/scan.fr.md +199 -0
  106. package/docs/scan.md +199 -0
  107. package/docs/scan.ru.md +199 -0
  108. package/docs/scan.zh.md +199 -0
  109. package/docs/scanner-comparison.es.md +209 -0
  110. package/docs/scanner-comparison.fr.md +213 -0
  111. package/docs/scanner-comparison.md +200 -0
  112. package/docs/scanner-comparison.ru.md +205 -0
  113. package/docs/scanner-comparison.zh.md +131 -0
  114. package/docs/security-hardening-language-boundary.md +306 -0
  115. package/package.json +10 -5
  116. package/scripts/check-quality-gate.mjs +64 -0
  117. package/scripts/quality-public-key.pem +3 -0
@@ -0,0 +1,192 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync } from 'node:fs';
3
+ import { mkdir, readdir, stat, unlink } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { defaultStateDir, readState, writeState } from './state.js';
6
+ import { runScan, parseScanArgs } from './scan.js';
7
+ import { displaySafe } from './sanitize.js';
8
+ /**
9
+ * Claude Code hooks.
10
+ *
11
+ * `hook session-start` scans the MCP servers Claude Code starts for this project
12
+ * (project `.mcp.json`, and the user's and this project's entries in
13
+ * `~/.claude.json`), records the verdicts for the session, and tells both the
14
+ * user and the model which servers were blocked — by server name, finding code
15
+ * and tool name only. A blocked tool's description is never echoed into the
16
+ * model's context: that text is the attack.
17
+ *
18
+ * `hook pre-tool-use` denies a call to an `mcp__<server>__<tool>` tool when the
19
+ * session-start scan blocked that server or that tool. It reads one small file
20
+ * and starts nothing, so it adds no network or process cost to a tool call.
21
+ *
22
+ * What this does not do: catch a server that changes its tools after the
23
+ * session started (use `warden-mcp wrap` for that — it re-checks before every
24
+ * call), or vet servers that plugins and claude.ai connectors provide (they are
25
+ * not in these files; calls to them get no decision unless WARDEN_HOOK_STRICT=1,
26
+ * which asks the user instead).
27
+ */
28
+ export const SESSION_TTL_MS = 14 * 24 * 3600 * 1000;
29
+ const STDIN_BYTES = 1_048_576;
30
+ /** Claude Code's form of a server or tool name inside `mcp__<server>__<tool>`. */
31
+ export function normalizeName(name) {
32
+ return name.replace(/[^a-zA-Z0-9_-]/g, '_');
33
+ }
34
+ /** A tool or server name safe to place in the model's context: short, plain, or withheld. */
35
+ export function contextSafeName(name) {
36
+ return /^[A-Za-z0-9_.:-]{1,64}$/.test(name) ? name : '(name withheld)';
37
+ }
38
+ export function sessionPath(stateDir, sessionId) {
39
+ return join(stateDir, 'claude-code', 'sessions', createHash('sha256').update(sessionId).digest('hex') + '.json');
40
+ }
41
+ async function readStdinJson() {
42
+ const chunks = [];
43
+ let total = 0;
44
+ for await (const chunk of process.stdin) {
45
+ total += chunk.length;
46
+ if (total > STDIN_BYTES)
47
+ throw new Error('hook input too large');
48
+ chunks.push(chunk);
49
+ }
50
+ const value = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}');
51
+ if (!value || typeof value !== 'object' || Array.isArray(value))
52
+ throw new Error('hook input is not an object');
53
+ return value;
54
+ }
55
+ async function pruneOld(dir, now) {
56
+ let names;
57
+ try {
58
+ names = await readdir(dir);
59
+ }
60
+ catch {
61
+ return;
62
+ }
63
+ for (const name of names) {
64
+ if (!name.endsWith('.json'))
65
+ continue;
66
+ try {
67
+ if (now - (await stat(join(dir, name))).mtimeMs > SESSION_TTL_MS)
68
+ await unlink(join(dir, name));
69
+ }
70
+ catch { /* raced */ }
71
+ }
72
+ }
73
+ export function verdictsFrom(report, cwd) {
74
+ return {
75
+ version: 1, scannedAt: report.scannedAt, cwd,
76
+ servers: report.servers.map(s => ({
77
+ key: s.key, normalized: normalizeName(s.key), allow: s.allow, status: s.status,
78
+ codes: [...new Set(s.findings.filter(f => !f.advisory).map(f => f.code))],
79
+ blockedTools: s.blockedTools,
80
+ })),
81
+ };
82
+ }
83
+ export function sessionStartOutput(report) {
84
+ const blocked = report.servers.filter(s => s.allow === false);
85
+ const unchecked = report.servers.filter(s => s.status === 'error');
86
+ const partial = report.servers.filter(s => s.allow !== false && s.blockedTools.length);
87
+ const n = report.summary.servers;
88
+ if (!n)
89
+ return undefined;
90
+ const lines = [];
91
+ for (const s of blocked) {
92
+ const codes = [...new Set(s.findings.filter(f => !f.advisory).map(f => f.code))].slice(0, 6).join(', ');
93
+ lines.push(`- MCP server "${contextSafeName(s.key)}" is BLOCKED by WARDEN (${codes}). Do not use its tools; calls to them will be denied. Tell the user if their task needs it.`);
94
+ }
95
+ for (const s of partial) {
96
+ lines.push(`- MCP server "${contextSafeName(s.key)}": tools ${s.blockedTools.slice(0, 10).map(t => `"${contextSafeName(t)}"`).join(', ')} are blocked by WARDEN; calls to them will be denied.`);
97
+ }
98
+ const user = `WARDEN vetted ${n} MCP server${n === 1 ? '' : 's'}: ${blocked.length} blocked` +
99
+ (partial.length ? `, ${partial.length} with blocked tools` : '') + (unchecked.length ? `, ${unchecked.length} could not be checked` : '') +
100
+ (blocked.length ? ` (${blocked.map(s => displaySafe(s.key, 40)).join(', ')}). Run: warden-mcp scan` : '.');
101
+ const out = { systemMessage: user };
102
+ if (lines.length)
103
+ out.hookSpecificOutput = { hookEventName: 'SessionStart', additionalContext: `WARDEN (MCP firewall) session check:\n${lines.join('\n')}` };
104
+ return out;
105
+ }
106
+ export async function sessionStart(input, env = process.env, deps = {}) {
107
+ const sessionId = typeof input.session_id === 'string' ? input.session_id : '';
108
+ const cwd = typeof input.cwd === 'string' && input.cwd ? input.cwd : process.cwd();
109
+ if (!sessionId)
110
+ throw new Error('hook input has no session_id');
111
+ const stateDir = env.WARDEN_STATE_DIR || defaultStateDir();
112
+ const args = ['--client', 'claude-code', '--cwd', cwd, '--timeout', env.WARDEN_HOOK_TIMEOUT_MS || '20000', '--state-dir', stateDir, '--no-color'];
113
+ if (env.WARDEN_HOOK_NO_LAUNCH === '1')
114
+ args.push('--no-launch');
115
+ if (existsSync(join(cwd, 'warden.lock.json')))
116
+ args.push('--lock', join(cwd, 'warden.lock.json'));
117
+ // Opt-in meaning-based check, configured the same way as for `scan` (key from WARDEN_CLASSIFIER_API_KEY).
118
+ if (env.WARDEN_CLASSIFIER_URL && env.WARDEN_CLASSIFIER_MODEL)
119
+ args.push('--classifier-url', env.WARDEN_CLASSIFIER_URL, '--classifier-model', env.WARDEN_CLASSIFIER_MODEL);
120
+ if (env.WARDEN_CLASSIFIER_URL && env.WARDEN_CLASSIFIER_BLOCKS === '1')
121
+ args.push('--classifier-blocks');
122
+ const opts = await parseScanArgs(args, env);
123
+ const report = await runScan(opts, deps);
124
+ const path = sessionPath(stateDir, sessionId);
125
+ await mkdir(join(stateDir, 'claude-code', 'sessions'), { recursive: true, mode: 0o700 });
126
+ await pruneOld(join(stateDir, 'claude-code', 'sessions'), Date.now());
127
+ await writeState(path, verdictsFrom(report, cwd));
128
+ return sessionStartOutput(report);
129
+ }
130
+ /** The decision for one tool call, given the session's verdicts. Pure; shared with the plugin's script by test. */
131
+ export function decide(toolName, verdicts, strict) {
132
+ if (!toolName.startsWith('mcp__'))
133
+ return undefined;
134
+ if (!verdicts)
135
+ return strict ? { permissionDecision: 'ask', permissionDecisionReason: 'WARDEN has no session-start scan for this session.' } : undefined;
136
+ let best;
137
+ for (const s of verdicts.servers) {
138
+ if (toolName.startsWith(`mcp__${s.normalized}__`) && (!best || s.normalized.length > best.normalized.length))
139
+ best = s;
140
+ }
141
+ if (!best)
142
+ return strict ? { permissionDecision: 'ask', permissionDecisionReason: 'WARDEN did not vet the MCP server behind this tool (it is not in .mcp.json or ~/.claude.json).' } : undefined;
143
+ const tool = toolName.slice(`mcp__${best.normalized}__`.length);
144
+ if (best.allow === false) {
145
+ return { permissionDecision: 'deny', permissionDecisionReason: `WARDEN blocked MCP server "${contextSafeName(best.key)}" at session start (${best.codes.slice(0, 6).join(', ') || 'see warden-mcp scan'}). Review it with: warden-mcp scan` };
146
+ }
147
+ if (best.blockedTools.some(t => normalizeName(t) === tool)) {
148
+ return { permissionDecision: 'deny', permissionDecisionReason: `WARDEN blocked this tool of MCP server "${contextSafeName(best.key)}" at session start. Review it with: warden-mcp scan` };
149
+ }
150
+ if (best.status === 'error' && strict)
151
+ return { permissionDecision: 'ask', permissionDecisionReason: `WARDEN could not check MCP server "${contextSafeName(best.key)}" at session start.` };
152
+ return undefined;
153
+ }
154
+ export async function preToolUse(input, env = process.env) {
155
+ const toolName = typeof input.tool_name === 'string' ? input.tool_name : '';
156
+ if (!toolName.startsWith('mcp__'))
157
+ return undefined;
158
+ const sessionId = typeof input.session_id === 'string' ? input.session_id : '';
159
+ const stateDir = env.WARDEN_STATE_DIR || defaultStateDir();
160
+ let verdicts;
161
+ try {
162
+ verdicts = sessionId ? await readState(sessionPath(stateDir, sessionId)) : undefined;
163
+ }
164
+ catch {
165
+ verdicts = undefined;
166
+ }
167
+ if (verdicts && verdicts.version !== 1)
168
+ verdicts = undefined;
169
+ const decision = decide(toolName, verdicts, env.WARDEN_HOOK_STRICT === '1');
170
+ return decision ? { hookSpecificOutput: { hookEventName: 'PreToolUse', ...decision } } : undefined;
171
+ }
172
+ /** `warden-mcp hook session-start|pre-tool-use` reads the hook JSON on stdin. */
173
+ export async function runHookCli(argv) {
174
+ const event = argv[0];
175
+ if (event !== 'session-start' && event !== 'pre-tool-use') {
176
+ process.stderr.write('Usage: warden-mcp hook session-start|pre-tool-use (Claude Code hook; reads the hook JSON on stdin)\n');
177
+ return 2;
178
+ }
179
+ try {
180
+ const input = await readStdinJson();
181
+ const out = event === 'session-start' ? await sessionStart(input) : await preToolUse(input);
182
+ if (out)
183
+ process.stdout.write(JSON.stringify(out) + '\n');
184
+ return 0;
185
+ }
186
+ catch (err) {
187
+ // A failing hook must not break the session: report on stderr, exit 0, no decision.
188
+ process.stderr.write(`warden hook ${event}: ${displaySafe(err instanceof Error ? err.message : String(err), 500)}\n`);
189
+ return 0;
190
+ }
191
+ }
192
+ //# sourceMappingURL=claude-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-hook.js","sourceRoot":"","sources":["../src/claude-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Preserve the original as a separate scanner pass. Decoding changes a reading,
3
+ * never the tool, its pin, or what gets executed. Invalid encodings remain literal.
4
+ * Replacement cannot grow the input; per-token and aggregate budgets bound work.
5
+ */
6
+ export declare function decodeForScan(text: string): string;
7
+ //# sourceMappingURL=encoded-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoded-text.d.ts","sourceRoot":"","sources":["../src/encoded-text.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiClD"}
@@ -0,0 +1,63 @@
1
+ /** Bounded, non-executing readings of encoded text. No language vocabulary. */
2
+ const MAX_TOKEN = 8192;
3
+ const MAX_DECODED = 65536;
4
+ const MAX_PASSES = 4;
5
+ const ENTITIES = {
6
+ amp: '&', lt: '<', gt: '>', quot: '"', apos: "'", colon: ':', sol: '/',
7
+ bsol: '\\', tab: '\t', newline: '\n', nbsp: ' ',
8
+ };
9
+ const utf8 = new TextDecoder('utf-8', { fatal: true });
10
+ function point(raw, radix, fallback) {
11
+ const n = Number.parseInt(raw, radix);
12
+ return n > 0 && n <= 0x10ffff && !(n >= 0xd800 && n <= 0xdfff) ? String.fromCodePoint(n) : fallback;
13
+ }
14
+ /**
15
+ * Preserve the original as a separate scanner pass. Decoding changes a reading,
16
+ * never the tool, its pin, or what gets executed. Invalid encodings remain literal.
17
+ * Replacement cannot grow the input; per-token and aggregate budgets bound work.
18
+ */
19
+ export function decodeForScan(text) {
20
+ let out = text;
21
+ let budget = MAX_DECODED;
22
+ for (let pass = 0; pass < MAX_PASSES; pass++) {
23
+ const before = out;
24
+ const replace = (whole, decoded) => {
25
+ if (whole.length > MAX_TOKEN || whole.length > budget || decoded.length > whole.length)
26
+ return whole;
27
+ budget -= whole.length;
28
+ return decoded;
29
+ };
30
+ out = out.replace(/&#(?:x([0-9a-f]{1,6})|([0-9]{1,7}));|&(amp|lt|gt|quot|apos|colon|sol|bsol|Tab|NewLine|nbsp);/gi, (whole, hex, decimal, named) => replace(whole, named ? ENTITIES[named.toLowerCase()] ?? whole : point(hex ?? decimal, hex ? 16 : 10, whole)));
31
+ out = out.replace(/(?<!\\)\\{1,8}(?:u\{([0-9a-f]{1,6})\}|u([0-9a-f]{4})|x([0-9a-f]{2}))/gi, (whole, brace, unit, hex) => replace(whole, brace ? point(brace, 16, whole) : String.fromCharCode(Number.parseInt(unit ?? hex, 16))));
32
+ out = out.replace(/(?:%[0-9a-f]{2})+/gi, whole => {
33
+ if (whole.length > MAX_TOKEN || whole.length > budget)
34
+ return whole;
35
+ try {
36
+ return replace(whole, decodeURIComponent(whole));
37
+ }
38
+ catch {
39
+ return whole;
40
+ }
41
+ });
42
+ out = out.replace(/(?<![A-Za-z0-9+/_=-])[A-Za-z0-9+/_-]{24,}={0,2}(?![A-Za-z0-9+/_=-])/g, whole => {
43
+ if (whole.length > MAX_TOKEN || whole.length > budget || whole.replace(/=+$/, '').length % 4 === 1)
44
+ return whole;
45
+ try {
46
+ const buffer = Buffer.from(whole, 'base64url');
47
+ if (buffer.toString('base64url') !== whole.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''))
48
+ return whole;
49
+ const decoded = utf8.decode(buffer);
50
+ if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/.test(decoded) || !/\p{L}[\s\S]*\p{L}/u.test(decoded))
51
+ return whole;
52
+ return replace(whole, decoded);
53
+ }
54
+ catch {
55
+ return whole;
56
+ }
57
+ });
58
+ if (out === before || budget <= 0)
59
+ break;
60
+ }
61
+ return out;
62
+ }
63
+ //# sourceMappingURL=encoded-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoded-text.js","sourceRoot":"","sources":["../src/encoded-text.ts"],"names":[],"mappings":"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"}
package/dist/fold.d.ts CHANGED
@@ -28,8 +28,7 @@
28
28
  * The fold is part of the published ruleset (FOLD_ID is in its digest): the same
29
29
  * regexes over folded and unfolded text are different scans.
30
30
  */
31
- /** Identity of this fold, carried in the ruleset preimage. Bump on any change below. */
32
- export declare const FOLD_ID = "nfkc+tags-decoded+invisible-stripped+mixed-script-confusables/1";
31
+ export declare const FOLD_ID = "escapes+entities+percent+base64/4x64k+nfkc+tags+invisible+confusables/2";
33
32
  /**
34
33
  * Fold `text` for matching. Never shown to anyone: findings quote the folded span,
35
34
  * and the raw text is what the hidden-character rules and the reader see.
@@ -1 +1 @@
1
- {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,wFAAwF;AACxF,eAAO,MAAM,OAAO,oEAAoE,CAAC;AAuCzF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBhD"}
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,eAAO,MAAM,OAAO,4EAA4E,CAAC;AAuCjG;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBhD"}
package/dist/fold.js CHANGED
@@ -29,7 +29,8 @@
29
29
  * regexes over folded and unfolded text are different scans.
30
30
  */
31
31
  /** Identity of this fold, carried in the ruleset preimage. Bump on any change below. */
32
- export const FOLD_ID = "nfkc+tags-decoded+invisible-stripped+mixed-script-confusables/1";
32
+ import { decodeForScan } from "./encoded-text.js";
33
+ export const FOLD_ID = "escapes+entities+percent+base64/4x64k+nfkc+tags+invisible+confusables/2";
33
34
  /**
34
35
  * Characters with no visible form in running text. Dropped by the fold; the
35
36
  * hidden-character rule reports them from the raw text.
@@ -67,7 +68,7 @@ const CONFUSABLE_RE = new RegExp(`[${Object.keys(CONFUSABLE).join("")}]`, "gu");
67
68
  export function foldForScan(text) {
68
69
  if (!text)
69
70
  return text;
70
- let out = text.normalize("NFKC");
71
+ let out = decodeForScan(text.normalize("NFKC")).normalize("NFKC");
71
72
  out = out.replace(TAG_RE, (ch) => String.fromCharCode((ch.codePointAt(0) ?? 0xe0020) - 0xe0000));
72
73
  out = out.replace(INVISIBLE_RE, "");
73
74
  CONFUSABLE_RE.lastIndex = 0;
package/dist/fold.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * HISTOR — the public transparency log of MCP tool definitions
3
+ * (https://histor.modelmarket.dev, source github.com/alexar76/histor).
4
+ *
5
+ * `scan --histor` asks the log one question per server: is the tool set this
6
+ * machine was served the one the log observes for everyone? The request carries
7
+ * the server's endpoint — or, for a stdio server started from npm or PyPI, the
8
+ * package name (`npm:<name>`, `pypi:<name>`), which the log runs in a sandbox —
9
+ * and the MTL/1 digest of the set, nothing else:
10
+ * no tool description ever leaves the machine, and the log cannot learn what a
11
+ * private server advertises. The answer is signed by the log and says `same`,
12
+ * `different` (you were served something the log never saw: a targeted
13
+ * definition, or a change the crawl has not reached yet), `previously-observed`
14
+ * (a set the log saw earlier: stale or rolled back), or that the server is not
15
+ * listed / not observed.
16
+ */
17
+ export declare const DEFAULT_HISTOR_URL = "https://histor.modelmarket.dev";
18
+ export declare const HISTOR_RESPONSE_BYTES: number;
19
+ export type HistorMatch = 'same' | 'different' | 'previously-observed' | 'not-listed' | 'not-observed' | 'no-digest' | 'undigestible';
20
+ export interface HistorQuery {
21
+ endpoint?: string;
22
+ /** A stdio server's package: `npm:<name>` or `pypi:<name>` (see `historPackage`). */
23
+ package?: string;
24
+ name?: string;
25
+ /** `sha256-<base64>` from {@link mtlToolSetDigest}. */
26
+ toolSetDigest?: string;
27
+ }
28
+ export interface HistorCheck {
29
+ match: HistorMatch | string;
30
+ note?: string;
31
+ checkedAt?: string;
32
+ issuer?: string;
33
+ target?: {
34
+ id?: string;
35
+ name?: string;
36
+ endpoint?: string;
37
+ page?: string;
38
+ badge?: string;
39
+ lastStatus?: string;
40
+ listed?: boolean;
41
+ packageVersion?: string;
42
+ /** What the registry says about the version HISTOR observed, and what changed since the one before. */
43
+ packageSignals?: {
44
+ version?: string;
45
+ previousVersion?: string;
46
+ provenance?: boolean;
47
+ publisher?: string | null;
48
+ previousPublisher?: string;
49
+ installScripts?: string[];
50
+ newDependencies?: string[];
51
+ flags?: string[];
52
+ /** What the package did in HISTOR's gVisor sandbox, per phase. */
53
+ behaviour?: Record<string, PackageBehaviour | unknown>;
54
+ };
55
+ };
56
+ /** The popular package this package's name imitates, for any package asked about. */
57
+ packageLookalike?: {
58
+ of?: string;
59
+ weekly?: number;
60
+ how?: string;
61
+ ownWeekly?: number;
62
+ };
63
+ observed?: {
64
+ toolSetDigest?: string;
65
+ subjectDigest?: string;
66
+ toolCount?: number;
67
+ firstPinned?: string;
68
+ unchangedSince?: string;
69
+ lastObserved?: string;
70
+ observations?: number;
71
+ changes?: number;
72
+ };
73
+ seenBefore?: unknown;
74
+ patternScan?: unknown;
75
+ classifier?: unknown;
76
+ log?: {
77
+ treeSize?: number;
78
+ rootHash?: string;
79
+ timestamp?: string;
80
+ };
81
+ [field: string]: unknown;
82
+ }
83
+ /** One phase of a package's run in HISTOR's sandbox: install scripts, startup, or the canary tool calls. */
84
+ export interface PackageBehaviour {
85
+ exec?: string[];
86
+ network?: string[];
87
+ lookups?: string[];
88
+ decoys?: string[];
89
+ writes?: string[];
90
+ packages?: string[];
91
+ tools?: number;
92
+ }
93
+ export interface HistorOptions {
94
+ timeoutMs?: number;
95
+ fetchImpl?: typeof fetch;
96
+ userAgent?: string;
97
+ }
98
+ export declare class HistorError extends Error {
99
+ }
100
+ /** POST /api/v1/check with endpoint/package/name + digest only. */
101
+ export declare function historCheck(base: string, query: HistorQuery, opts?: HistorOptions): Promise<HistorCheck>;
102
+ /** Read a response body up to `limit` bytes; refuse a longer one. */
103
+ export declare function readBounded(res: Response, limit: number): Promise<string>;
104
+ //# sourceMappingURL=histor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"histor.d.ts","sourceRoot":"","sources":["../src/histor.ts"],"names":[],"mappings":"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"}
package/dist/histor.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * HISTOR — the public transparency log of MCP tool definitions
3
+ * (https://histor.modelmarket.dev, source github.com/alexar76/histor).
4
+ *
5
+ * `scan --histor` asks the log one question per server: is the tool set this
6
+ * machine was served the one the log observes for everyone? The request carries
7
+ * the server's endpoint — or, for a stdio server started from npm or PyPI, the
8
+ * package name (`npm:<name>`, `pypi:<name>`), which the log runs in a sandbox —
9
+ * and the MTL/1 digest of the set, nothing else:
10
+ * no tool description ever leaves the machine, and the log cannot learn what a
11
+ * private server advertises. The answer is signed by the log and says `same`,
12
+ * `different` (you were served something the log never saw: a targeted
13
+ * definition, or a change the crawl has not reached yet), `previously-observed`
14
+ * (a set the log saw earlier: stale or rolled back), or that the server is not
15
+ * listed / not observed.
16
+ */
17
+ export const DEFAULT_HISTOR_URL = 'https://histor.modelmarket.dev';
18
+ export const HISTOR_RESPONSE_BYTES = 256 * 1024;
19
+ export class HistorError extends Error {
20
+ }
21
+ /** POST /api/v1/check with endpoint/package/name + digest only. */
22
+ export async function historCheck(base, query, opts = {}) {
23
+ const root = new URL(base);
24
+ if (root.protocol !== 'https:' && root.protocol !== 'http:')
25
+ throw new HistorError('HISTOR URL must be http(s)');
26
+ if (!query.endpoint && !query.package && !query.name)
27
+ throw new HistorError('a HISTOR check needs an endpoint, a package or a name');
28
+ // Only these fields, ever. `tools` and `contribute` are deliberately not forwarded.
29
+ const body = {};
30
+ if (query.endpoint)
31
+ body.endpoint = query.endpoint;
32
+ else if (query.package)
33
+ body.package = query.package;
34
+ if (query.name)
35
+ body.name = query.name;
36
+ if (query.toolSetDigest)
37
+ body.toolSetDigest = query.toolSetDigest;
38
+ const url = new URL('/api/v1/check', root);
39
+ const controller = new AbortController();
40
+ const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 10_000);
41
+ try {
42
+ const res = await (opts.fetchImpl ?? fetch)(url, {
43
+ method: 'POST', signal: controller.signal, redirect: 'error',
44
+ headers: { 'content-type': 'application/json', accept: 'application/json', 'user-agent': opts.userAgent ?? 'warden-scan' },
45
+ body: JSON.stringify(body),
46
+ });
47
+ const text = await readBounded(res, HISTOR_RESPONSE_BYTES);
48
+ if (!res.ok)
49
+ throw new HistorError(`HISTOR answered HTTP ${res.status}`);
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(text);
53
+ }
54
+ catch {
55
+ throw new HistorError('HISTOR answered non-JSON');
56
+ }
57
+ if (!parsed || typeof parsed !== 'object' || typeof parsed.match !== 'string')
58
+ throw new HistorError('HISTOR answer has no match field');
59
+ return parsed;
60
+ }
61
+ catch (err) {
62
+ if (err instanceof HistorError)
63
+ throw err;
64
+ throw new HistorError(controller.signal.aborted ? 'HISTOR timed out' : `HISTOR did not answer (${err instanceof Error ? err.message : String(err)})`);
65
+ }
66
+ finally {
67
+ clearTimeout(timer);
68
+ }
69
+ }
70
+ /** Read a response body up to `limit` bytes; refuse a longer one. */
71
+ export async function readBounded(res, limit) {
72
+ if (!res.body)
73
+ return '';
74
+ const chunks = [];
75
+ let total = 0;
76
+ for await (const chunk of res.body) {
77
+ total += chunk.byteLength;
78
+ if (total > limit) {
79
+ await res.body.cancel().catch(() => { });
80
+ throw new HistorError(`response exceeds ${limit} bytes`);
81
+ }
82
+ chunks.push(Buffer.from(chunk));
83
+ }
84
+ return Buffer.concat(chunks).toString('utf8');
85
+ }
86
+ //# sourceMappingURL=histor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"histor.js","sourceRoot":"","sources":["../src/histor.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import type { McpServerRef, PinStore, ToolDef, WardenGate, WardenLogger, WardenPolicy, WardenVerdict } from "./types.js";
2
2
  import { ThreatFeed } from "./threat-feed.js";
3
+ import { type ClassifierInspection } from "./classifier.js";
3
4
  export { StaticScanGate, staticScanRuleset, staticScanRulesetRef, STATIC_SCAN_RULESET_VERSION, } from "./static-scan.js";
5
+ export { inspectTools } from "./classifier.js";
6
+ export type { ClassifierOptions, ClassifierInspection, ClassifierFinding } from "./classifier.js";
4
7
  export { PinningGate, canonicalToolsHash, tryCanonicalToolsHash, pinToolsHash, RFC8785_PIN_PREFIX, serverIdentityHash, UNCANONICAL_TOOLS_HASH } from "./pinning.js";
5
8
  export { FilePinStore } from "./pin-store.js";
6
9
  export { OriginGate } from "./origin.js";
@@ -21,6 +24,8 @@ export interface WardenInit {
21
24
  log?: WardenLogger;
22
25
  }
23
26
  export interface WardenCreateDeps {
27
+ /** Local complete inspection; clears only readable BASE64_BLOB / structured quotation ambiguity on identical tools. */
28
+ semanticReview?: ClassifierInspection;
24
29
  store: PinStore;
25
30
  policy: WardenPolicy;
26
31
  /**
@@ -96,7 +101,7 @@ export declare class Warden {
96
101
  * Record the user's approval: pin the current tool defs so future drift is
97
102
  * detected. Idempotent — re-approving just refreshes the snapshot.
98
103
  */
99
- approve(server: McpServerRef, tools: ToolDef[]): Promise<void>;
104
+ approve(server: McpServerRef, tools: ToolDef[], approvalMode?: "operator" | "automatic"): Promise<void>;
100
105
  /**
101
106
  * A tool is blocked if a finding naming it reaches the block threshold.
102
107
  * Sensitive tools (per policy) stay allowed but are surfaced as flagged so the
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EAER,OAAO,EAEP,UAAU,EAEV,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,UAAU,EAAc,MAAM,kBAAkB,CAAC;AAK1D,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACpK,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACvG,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,cAAc,YAAY,CAAC;AAU3B,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,kEAAkE;IAClE,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,EAAE,UAAU;IAM5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IAWvB,yEAAyE;IACzE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM;IAU7C;;;;OAIG;IACG,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAUvD,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAqDzE;;;;;;;;;;;;;;OAcG;YACW,OAAO;IAiCrB;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpE;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,cAAc;CAGvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}