@panguard-ai/panguard-mcp-proxy 1.8.3 → 1.8.4
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/dist/evaluator.js +22 -8
- package/package.json +5 -5
package/dist/evaluator.js
CHANGED
|
@@ -207,18 +207,32 @@ export class ProxyEvaluator {
|
|
|
207
207
|
durationMs,
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
//
|
|
210
|
+
// FALSE-POSITIVE CONTROL POINT (this is a SYNCHRONOUS per-tool-call gate).
|
|
211
|
+
// 1. Hard-DENY on a trusted match (shouldHardDeny: critical, or high+stable).
|
|
212
|
+
// 2. Otherwise surface an 'ask' advisory ONLY for a high-severity match —
|
|
213
|
+
// something serious enough to warrant a per-call heads-up even if
|
|
214
|
+
// unproven.
|
|
215
|
+
// 3. Medium/low matches are demoted to a SILENT allow here. The engine
|
|
216
|
+
// runs full 'hunt' detection, and many broad rules (e.g. keyword-
|
|
217
|
+
// presence rules that fire on any `curl`/`rm`/`env`, severity=medium,
|
|
218
|
+
// condition:any) would otherwise spam an advisory on routine tool calls
|
|
219
|
+
// — the dominant false-positive source. Their matches are still
|
|
220
|
+
// returned in matchedRules and the async daemon path keeps them for
|
|
221
|
+
// offline review; we just do not raise a per-call advisory/block on an
|
|
222
|
+
// unactionable low-severity broad match. Real attacks are
|
|
223
|
+
// critical/high-stable and hard-deny at step 1, so are unaffected.
|
|
214
224
|
const blockMatch = matches.find((m) => shouldHardDeny(m.rule));
|
|
215
|
-
const
|
|
216
|
-
|
|
225
|
+
const askMatch = blockMatch ??
|
|
226
|
+
matches.find((m) => m.rule.severity === 'high' || m.rule.severity === 'critical');
|
|
227
|
+
const outcome = blockMatch ? 'deny' : askMatch ? 'ask' : 'allow';
|
|
228
|
+
const topMatch = blockMatch ?? askMatch ?? matches[0];
|
|
217
229
|
return {
|
|
218
230
|
outcome,
|
|
219
|
-
reason:
|
|
231
|
+
reason: outcome === 'allow'
|
|
232
|
+
? `No actionable threat (low-severity match suppressed: ${topMatch.rule.title}, ${topMatch.rule.severity})`
|
|
233
|
+
: `${topMatch.rule.title} (${topMatch.rule.severity})`,
|
|
220
234
|
matchedRules: matches.map((m) => m.rule.id),
|
|
221
|
-
confidence: topMatch.confidence,
|
|
235
|
+
confidence: outcome === 'allow' ? 0 : topMatch.confidence,
|
|
222
236
|
durationMs,
|
|
223
237
|
};
|
|
224
238
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@panguard-ai/panguard-mcp-proxy",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"description": "MCP Proxy — runtime interception for AI agent tool calls using ATR rules",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
23
23
|
"agent-threat-rules": "^3.5.6",
|
|
24
|
-
"@panguard-ai/
|
|
25
|
-
"@panguard-ai/
|
|
26
|
-
"@panguard-ai/
|
|
24
|
+
"@panguard-ai/containment": "0.1.0",
|
|
25
|
+
"@panguard-ai/atr": "1.8.4",
|
|
26
|
+
"@panguard-ai/panguard-guard": "1.8.4"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@panguard-ai/atr": "1.8.
|
|
29
|
+
"@panguard-ai/atr": "1.8.4"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"dist",
|