@bryan-thompson/inspector-assessment-client 1.25.1 → 1.25.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/assets/{OAuthCallback-CkzX_H4T.js → OAuthCallback-DE62cdTZ.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-jZEkm74B.js → OAuthDebugCallback-CWjFdCIE.js} +1 -1
- package/dist/assets/{index-BVx1dGJT.js → index-PCQVSwHa.js} +4 -4
- package/dist/index.html +1 -1
- package/lib/lib/assessment/configTypes.d.ts +3 -0
- package/lib/lib/assessment/configTypes.d.ts.map +1 -1
- package/lib/lib/assessment/configTypes.js +11 -6
- package/lib/services/assessment/AssessmentOrchestrator.d.ts +1 -5
- package/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -1
- package/lib/services/assessment/AssessmentOrchestrator.js +36 -236
- package/lib/services/assessment/ToolClassifier.d.ts +154 -27
- package/lib/services/assessment/ToolClassifier.d.ts.map +1 -1
- package/lib/services/assessment/ToolClassifier.js +171 -318
- package/lib/services/assessment/orchestratorHelpers.d.ts +83 -0
- package/lib/services/assessment/orchestratorHelpers.d.ts.map +1 -0
- package/lib/services/assessment/orchestratorHelpers.js +212 -0
- package/lib/services/assessment/tool-classifier-patterns.d.ts +84 -0
- package/lib/services/assessment/tool-classifier-patterns.d.ts.map +1 -0
- package/lib/services/assessment/tool-classifier-patterns.js +348 -0
- package/package.json +1 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assessment Orchestrator Helpers
|
|
3
|
+
*
|
|
4
|
+
* Pure functions extracted from AssessmentOrchestrator for testability.
|
|
5
|
+
* These functions handle:
|
|
6
|
+
* - AUP violation enrichment for JSONL events
|
|
7
|
+
* - Module progress/started event emission
|
|
8
|
+
* - Overall status determination
|
|
9
|
+
* - Summary and recommendations generation
|
|
10
|
+
*/
|
|
11
|
+
// Import score calculation helpers from shared module
|
|
12
|
+
import { calculateModuleScore, normalizeModuleKey, INSPECTOR_VERSION, } from "../../lib/moduleScoring.js";
|
|
13
|
+
// Track module start times for duration calculation
|
|
14
|
+
export const moduleStartTimes = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Emit module_started event and track start time for duration calculation.
|
|
17
|
+
* Emits JSONL to stderr with version field for consistent event structure.
|
|
18
|
+
*/
|
|
19
|
+
export function emitModuleStartedEvent(moduleName, estimatedTests, toolCount) {
|
|
20
|
+
const moduleKey = normalizeModuleKey(moduleName);
|
|
21
|
+
moduleStartTimes.set(moduleKey, Date.now());
|
|
22
|
+
// Emit JSONL to stderr with version field
|
|
23
|
+
console.error(JSON.stringify({
|
|
24
|
+
event: "module_started",
|
|
25
|
+
module: moduleKey,
|
|
26
|
+
estimatedTests,
|
|
27
|
+
toolCount,
|
|
28
|
+
version: INSPECTOR_VERSION,
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Emit module_complete event with score and duration.
|
|
33
|
+
* Uses shared score calculator for consistent scoring logic.
|
|
34
|
+
* For AUP module, includes enriched violation data for Claude analysis.
|
|
35
|
+
*/
|
|
36
|
+
export function emitModuleProgress(moduleName, status, result, testsRun = 0) {
|
|
37
|
+
// Calculate score using shared helper
|
|
38
|
+
const score = calculateModuleScore(result);
|
|
39
|
+
// Don't emit events for skipped modules (null score means module wasn't run)
|
|
40
|
+
if (score === null)
|
|
41
|
+
return;
|
|
42
|
+
const moduleKey = normalizeModuleKey(moduleName);
|
|
43
|
+
// Calculate duration from module start time
|
|
44
|
+
const startTime = moduleStartTimes.get(moduleKey);
|
|
45
|
+
const duration = startTime ? Date.now() - startTime : 0;
|
|
46
|
+
moduleStartTimes.delete(moduleKey);
|
|
47
|
+
// Build base event
|
|
48
|
+
const event = {
|
|
49
|
+
event: "module_complete",
|
|
50
|
+
module: moduleKey,
|
|
51
|
+
status,
|
|
52
|
+
score,
|
|
53
|
+
testsRun,
|
|
54
|
+
duration,
|
|
55
|
+
version: INSPECTOR_VERSION,
|
|
56
|
+
};
|
|
57
|
+
// Add AUP enrichment when module is AUP
|
|
58
|
+
if (moduleKey === "aup" && result) {
|
|
59
|
+
const aupEnrichment = buildAUPEnrichment(result);
|
|
60
|
+
Object.assign(event, aupEnrichment);
|
|
61
|
+
}
|
|
62
|
+
// Emit JSONL to stderr with version field
|
|
63
|
+
console.error(JSON.stringify(event));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build AUP enrichment data from an AUP compliance assessment result.
|
|
67
|
+
* Samples violations prioritizing by severity (CRITICAL > HIGH > MEDIUM).
|
|
68
|
+
*/
|
|
69
|
+
export function buildAUPEnrichment(aupResult, maxSamples = 10) {
|
|
70
|
+
const violations = aupResult.violations || [];
|
|
71
|
+
// Calculate metrics
|
|
72
|
+
const metrics = {
|
|
73
|
+
total: violations.length,
|
|
74
|
+
critical: violations.filter((v) => v.severity === "CRITICAL").length,
|
|
75
|
+
high: violations.filter((v) => v.severity === "HIGH").length,
|
|
76
|
+
medium: violations.filter((v) => v.severity === "MEDIUM").length,
|
|
77
|
+
byCategory: {},
|
|
78
|
+
};
|
|
79
|
+
// Count by category
|
|
80
|
+
for (const v of violations) {
|
|
81
|
+
metrics.byCategory[v.category] = (metrics.byCategory[v.category] || 0) + 1;
|
|
82
|
+
}
|
|
83
|
+
// Sample violations prioritizing by severity
|
|
84
|
+
const sampled = [];
|
|
85
|
+
const severityOrder = ["CRITICAL", "HIGH", "MEDIUM"];
|
|
86
|
+
for (const severity of severityOrder) {
|
|
87
|
+
if (sampled.length >= maxSamples)
|
|
88
|
+
break;
|
|
89
|
+
const bySeverity = violations.filter((v) => v.severity === severity);
|
|
90
|
+
for (const v of bySeverity) {
|
|
91
|
+
if (sampled.length >= maxSamples)
|
|
92
|
+
break;
|
|
93
|
+
sampled.push({
|
|
94
|
+
category: v.category,
|
|
95
|
+
categoryName: v.categoryName || "",
|
|
96
|
+
severity: v.severity,
|
|
97
|
+
matchedText: v.matchedText || "",
|
|
98
|
+
location: v.location || "",
|
|
99
|
+
confidence: v.confidence || "",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Build sampling note
|
|
104
|
+
let samplingNote = "";
|
|
105
|
+
if (violations.length === 0) {
|
|
106
|
+
samplingNote = "No violations detected.";
|
|
107
|
+
}
|
|
108
|
+
else if (violations.length <= maxSamples) {
|
|
109
|
+
samplingNote = `All ${violations.length} violation(s) included.`;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
samplingNote = `Sampled ${sampled.length} of ${violations.length} violations, prioritized by severity (CRITICAL > HIGH > MEDIUM).`;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
violationsSample: sampled,
|
|
116
|
+
samplingNote,
|
|
117
|
+
violationMetrics: metrics,
|
|
118
|
+
scannedLocations: aupResult.scannedLocations || {
|
|
119
|
+
toolNames: false,
|
|
120
|
+
toolDescriptions: false,
|
|
121
|
+
readme: false,
|
|
122
|
+
sourceCode: false,
|
|
123
|
+
},
|
|
124
|
+
highRiskDomains: (aupResult.highRiskDomains || []).slice(0, 10),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Determine overall status from assessment results.
|
|
129
|
+
* Priority: FAIL > NEED_MORE_INFO > PASS
|
|
130
|
+
*/
|
|
131
|
+
export function determineOverallStatus(results) {
|
|
132
|
+
const statuses = [];
|
|
133
|
+
// Collect all statuses from assessment results
|
|
134
|
+
Object.values(results).forEach((assessment) => {
|
|
135
|
+
if (assessment &&
|
|
136
|
+
typeof assessment === "object" &&
|
|
137
|
+
"status" in assessment) {
|
|
138
|
+
statuses.push(assessment.status);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
// If any critical category fails, overall fails
|
|
142
|
+
if (statuses.includes("FAIL"))
|
|
143
|
+
return "FAIL";
|
|
144
|
+
// If any category needs more info, overall needs more info
|
|
145
|
+
if (statuses.includes("NEED_MORE_INFO"))
|
|
146
|
+
return "NEED_MORE_INFO";
|
|
147
|
+
// All must pass for overall pass
|
|
148
|
+
return "PASS";
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Generate summary text from assessment results.
|
|
152
|
+
*/
|
|
153
|
+
export function generateSummary(results) {
|
|
154
|
+
const parts = [];
|
|
155
|
+
const totalCategories = Object.keys(results).length;
|
|
156
|
+
const passedCategories = Object.values(results).filter((r) => r && typeof r === "object" && "status" in r && r.status === "PASS").length;
|
|
157
|
+
parts.push(`Assessment complete: ${passedCategories}/${totalCategories} categories passed.`);
|
|
158
|
+
// Add key findings - use type assertions for optional properties
|
|
159
|
+
const security = results.security;
|
|
160
|
+
if (security?.vulnerabilities?.length) {
|
|
161
|
+
parts.push(`Found ${security.vulnerabilities.length} security vulnerabilities.`);
|
|
162
|
+
}
|
|
163
|
+
const functionality = results.functionality;
|
|
164
|
+
if (functionality?.brokenTools?.length) {
|
|
165
|
+
parts.push(`${functionality.brokenTools.length} tools are not functioning correctly.`);
|
|
166
|
+
}
|
|
167
|
+
// New assessor findings
|
|
168
|
+
const aupCompliance = results.aupCompliance;
|
|
169
|
+
if (aupCompliance?.violations?.length) {
|
|
170
|
+
const criticalCount = aupCompliance.violations.filter((v) => v.severity === "CRITICAL").length;
|
|
171
|
+
if (criticalCount > 0) {
|
|
172
|
+
parts.push(`CRITICAL: ${criticalCount} AUP violation(s) detected.`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
parts.push(`${aupCompliance.violations.length} AUP item(s) flagged for review.`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const toolAnnotations = results.toolAnnotations;
|
|
179
|
+
if (toolAnnotations?.missingAnnotationsCount) {
|
|
180
|
+
parts.push(`${toolAnnotations.missingAnnotationsCount} tools missing annotations.`);
|
|
181
|
+
}
|
|
182
|
+
const prohibitedLibraries = results.prohibitedLibraries;
|
|
183
|
+
if (prohibitedLibraries?.matches?.length) {
|
|
184
|
+
const blockingCount = prohibitedLibraries.matches.filter((m) => m.severity === "BLOCKING").length;
|
|
185
|
+
if (blockingCount > 0) {
|
|
186
|
+
parts.push(`BLOCKING: ${blockingCount} prohibited library/libraries detected.`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const portability = results.portability;
|
|
190
|
+
if (portability?.usesBundleRoot) {
|
|
191
|
+
parts.push("Uses ${BUNDLE_ROOT} anti-pattern.");
|
|
192
|
+
}
|
|
193
|
+
return parts.join(" ");
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Generate recommendations from assessment results.
|
|
197
|
+
* Aggregates, deduplicates, and limits to 10 recommendations.
|
|
198
|
+
*/
|
|
199
|
+
export function generateRecommendations(results) {
|
|
200
|
+
const recommendations = [];
|
|
201
|
+
// Aggregate recommendations from all assessments
|
|
202
|
+
Object.values(results).forEach((assessment) => {
|
|
203
|
+
if (assessment &&
|
|
204
|
+
typeof assessment === "object" &&
|
|
205
|
+
"recommendations" in assessment &&
|
|
206
|
+
Array.isArray(assessment.recommendations)) {
|
|
207
|
+
recommendations.push(...assessment.recommendations);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
// De-duplicate and prioritize
|
|
211
|
+
return [...new Set(recommendations)].slice(0, 10);
|
|
212
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Classifier Pattern Configuration
|
|
3
|
+
*
|
|
4
|
+
* Pre-compiled regex patterns for MCP tool classification.
|
|
5
|
+
* Extracting patterns to this file provides:
|
|
6
|
+
* - Single source of truth for patterns, confidence values, and risk levels
|
|
7
|
+
* - Pre-compiled patterns (created once at module load, not per classify() call)
|
|
8
|
+
* - Easier maintenance without modifying core classification logic
|
|
9
|
+
*
|
|
10
|
+
* @see ToolClassifier.ts for classification logic
|
|
11
|
+
* @see ToolClassifier.test.ts for pattern behavior validation
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Security risk categories for MCP tools.
|
|
15
|
+
*
|
|
16
|
+
* Categories are organized by risk level:
|
|
17
|
+
* - **HIGH**: Tools that may execute code or access sensitive data
|
|
18
|
+
* - **MEDIUM**: Tools with potential bypass or supply chain risks
|
|
19
|
+
* - **LOW**: Safe tools for data retrieval and manipulation
|
|
20
|
+
*/
|
|
21
|
+
export declare enum ToolCategory {
|
|
22
|
+
CALCULATOR = "calculator",
|
|
23
|
+
SYSTEM_EXEC = "system_exec",
|
|
24
|
+
CODE_EXECUTOR = "code_executor",
|
|
25
|
+
DATA_ACCESS = "data_access",
|
|
26
|
+
TOOL_OVERRIDE = "tool_override",
|
|
27
|
+
CONFIG_MODIFIER = "config_modifier",
|
|
28
|
+
URL_FETCHER = "fetcher",
|
|
29
|
+
UNICODE_PROCESSOR = "unicode",
|
|
30
|
+
JSON_PARSER = "parser",
|
|
31
|
+
PACKAGE_INSTALLER = "installer",
|
|
32
|
+
RUG_PULL = "rug_pull",
|
|
33
|
+
SAFE_STORAGE = "safe_storage",
|
|
34
|
+
API_WRAPPER = "api_wrapper",
|
|
35
|
+
SEARCH_RETRIEVAL = "search_retrieval",
|
|
36
|
+
CRUD_CREATION = "crud_creation",
|
|
37
|
+
READ_ONLY_INFO = "read_only_info",
|
|
38
|
+
GENERIC = "generic"
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Risk level for security categorization
|
|
42
|
+
*/
|
|
43
|
+
export type RiskLevel = "HIGH" | "MEDIUM" | "LOW";
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for a single tool category
|
|
46
|
+
*/
|
|
47
|
+
export interface CategoryConfig {
|
|
48
|
+
/** Pre-compiled regex patterns for this category */
|
|
49
|
+
readonly patterns: readonly RegExp[];
|
|
50
|
+
/** Confidence score (0-100) when this category matches */
|
|
51
|
+
readonly confidence: number;
|
|
52
|
+
/** Human-readable reasoning for classification */
|
|
53
|
+
readonly reasoning: string;
|
|
54
|
+
/** Risk level for security prioritization */
|
|
55
|
+
readonly risk: RiskLevel;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Complete pattern configuration for all tool categories.
|
|
59
|
+
* Patterns are pre-compiled as static constants for performance.
|
|
60
|
+
*
|
|
61
|
+
* ## Pattern Types
|
|
62
|
+
*
|
|
63
|
+
* 1. **Substring patterns** (`/keyword/i`): Match anywhere in text
|
|
64
|
+
* - Used for HIGH-risk keywords that warrant scrutiny even when embedded
|
|
65
|
+
*
|
|
66
|
+
* 2. **Word boundary patterns** (`/\bword\b/i`): Match isolated words only
|
|
67
|
+
* - Used for common words to prevent false positives
|
|
68
|
+
* - Note: `\b` treats hyphens as boundaries but underscores as word chars
|
|
69
|
+
*/
|
|
70
|
+
export declare const CATEGORY_PATTERNS: Readonly<Record<Exclude<ToolCategory, ToolCategory.GENERIC>, CategoryConfig>>;
|
|
71
|
+
/**
|
|
72
|
+
* Default configuration for GENERIC category (no pattern match)
|
|
73
|
+
*/
|
|
74
|
+
export declare const GENERIC_CONFIG: Readonly<{
|
|
75
|
+
confidence: number;
|
|
76
|
+
reasoning: string;
|
|
77
|
+
risk: RiskLevel;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Order in which categories are checked during classification.
|
|
81
|
+
* This order determines priority when a tool matches multiple categories.
|
|
82
|
+
*/
|
|
83
|
+
export declare const CATEGORY_CHECK_ORDER: readonly Exclude<ToolCategory, ToolCategory.GENERIC>[];
|
|
84
|
+
//# sourceMappingURL=tool-classifier-patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-classifier-patterns.d.ts","sourceRoot":"","sources":["../../../src/services/assessment/tool-classifier-patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;GAOG;AACH,oBAAY,YAAY;IAEtB,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,eAAe,oBAAoB;IACnC,WAAW,YAAY;IAGvB,iBAAiB,YAAY;IAC7B,WAAW,WAAW;IACtB,iBAAiB,cAAc;IAC/B,QAAQ,aAAa;IAGrB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;IACrC,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IAGjC,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CACtC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,CAyR3D,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;CACjB,CAIS,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,OAAO,CACjD,YAAY,EACZ,YAAY,CAAC,OAAO,CACrB,EAoBS,CAAC"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Classifier Pattern Configuration
|
|
3
|
+
*
|
|
4
|
+
* Pre-compiled regex patterns for MCP tool classification.
|
|
5
|
+
* Extracting patterns to this file provides:
|
|
6
|
+
* - Single source of truth for patterns, confidence values, and risk levels
|
|
7
|
+
* - Pre-compiled patterns (created once at module load, not per classify() call)
|
|
8
|
+
* - Easier maintenance without modifying core classification logic
|
|
9
|
+
*
|
|
10
|
+
* @see ToolClassifier.ts for classification logic
|
|
11
|
+
* @see ToolClassifier.test.ts for pattern behavior validation
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Security risk categories for MCP tools.
|
|
15
|
+
*
|
|
16
|
+
* Categories are organized by risk level:
|
|
17
|
+
* - **HIGH**: Tools that may execute code or access sensitive data
|
|
18
|
+
* - **MEDIUM**: Tools with potential bypass or supply chain risks
|
|
19
|
+
* - **LOW**: Safe tools for data retrieval and manipulation
|
|
20
|
+
*/
|
|
21
|
+
export var ToolCategory;
|
|
22
|
+
(function (ToolCategory) {
|
|
23
|
+
// HIGH RISK
|
|
24
|
+
ToolCategory["CALCULATOR"] = "calculator";
|
|
25
|
+
ToolCategory["SYSTEM_EXEC"] = "system_exec";
|
|
26
|
+
ToolCategory["CODE_EXECUTOR"] = "code_executor";
|
|
27
|
+
ToolCategory["DATA_ACCESS"] = "data_access";
|
|
28
|
+
ToolCategory["TOOL_OVERRIDE"] = "tool_override";
|
|
29
|
+
ToolCategory["CONFIG_MODIFIER"] = "config_modifier";
|
|
30
|
+
ToolCategory["URL_FETCHER"] = "fetcher";
|
|
31
|
+
// MEDIUM RISK
|
|
32
|
+
ToolCategory["UNICODE_PROCESSOR"] = "unicode";
|
|
33
|
+
ToolCategory["JSON_PARSER"] = "parser";
|
|
34
|
+
ToolCategory["PACKAGE_INSTALLER"] = "installer";
|
|
35
|
+
ToolCategory["RUG_PULL"] = "rug_pull";
|
|
36
|
+
// LOW RISK (SAFE)
|
|
37
|
+
ToolCategory["SAFE_STORAGE"] = "safe_storage";
|
|
38
|
+
ToolCategory["API_WRAPPER"] = "api_wrapper";
|
|
39
|
+
ToolCategory["SEARCH_RETRIEVAL"] = "search_retrieval";
|
|
40
|
+
ToolCategory["CRUD_CREATION"] = "crud_creation";
|
|
41
|
+
ToolCategory["READ_ONLY_INFO"] = "read_only_info";
|
|
42
|
+
// DEFAULT
|
|
43
|
+
ToolCategory["GENERIC"] = "generic";
|
|
44
|
+
})(ToolCategory || (ToolCategory = {}));
|
|
45
|
+
/**
|
|
46
|
+
* Complete pattern configuration for all tool categories.
|
|
47
|
+
* Patterns are pre-compiled as static constants for performance.
|
|
48
|
+
*
|
|
49
|
+
* ## Pattern Types
|
|
50
|
+
*
|
|
51
|
+
* 1. **Substring patterns** (`/keyword/i`): Match anywhere in text
|
|
52
|
+
* - Used for HIGH-risk keywords that warrant scrutiny even when embedded
|
|
53
|
+
*
|
|
54
|
+
* 2. **Word boundary patterns** (`/\bword\b/i`): Match isolated words only
|
|
55
|
+
* - Used for common words to prevent false positives
|
|
56
|
+
* - Note: `\b` treats hyphens as boundaries but underscores as word chars
|
|
57
|
+
*/
|
|
58
|
+
export const CATEGORY_PATTERNS = {
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// HIGH RISK CATEGORIES
|
|
61
|
+
// ============================================================================
|
|
62
|
+
[ToolCategory.CALCULATOR]: {
|
|
63
|
+
patterns: [
|
|
64
|
+
/calculator/i,
|
|
65
|
+
/compute/i,
|
|
66
|
+
/math/i,
|
|
67
|
+
/calc/i,
|
|
68
|
+
/eval/i,
|
|
69
|
+
/arithmetic/i,
|
|
70
|
+
/expression/i,
|
|
71
|
+
],
|
|
72
|
+
confidence: 90,
|
|
73
|
+
reasoning: "Calculator pattern detected (arithmetic execution risk)",
|
|
74
|
+
risk: "HIGH",
|
|
75
|
+
},
|
|
76
|
+
[ToolCategory.SYSTEM_EXEC]: {
|
|
77
|
+
patterns: [
|
|
78
|
+
/system.*exec/i,
|
|
79
|
+
/exec.*tool/i,
|
|
80
|
+
/command/i,
|
|
81
|
+
/shell/i,
|
|
82
|
+
/\brun\b/i,
|
|
83
|
+
/execute/i,
|
|
84
|
+
/process/i,
|
|
85
|
+
],
|
|
86
|
+
confidence: 95,
|
|
87
|
+
reasoning: "System execution pattern detected (command injection risk)",
|
|
88
|
+
risk: "HIGH",
|
|
89
|
+
},
|
|
90
|
+
[ToolCategory.CODE_EXECUTOR]: {
|
|
91
|
+
patterns: [
|
|
92
|
+
/execute.*code/i,
|
|
93
|
+
/run.*code/i,
|
|
94
|
+
/code.*execut/i,
|
|
95
|
+
/run.*script/i,
|
|
96
|
+
/exec.*script/i,
|
|
97
|
+
/\bpython.*code\b/i,
|
|
98
|
+
/\bjavascript.*code\b/i,
|
|
99
|
+
/\bjs.*code\b/i,
|
|
100
|
+
/\beval.*code\b/i,
|
|
101
|
+
/code.*runner/i,
|
|
102
|
+
/script.*runner/i,
|
|
103
|
+
/\bexec\b.*\b(python|js|javascript)\b/i,
|
|
104
|
+
/\b(python|js|javascript)\b.*\bexec\b/i,
|
|
105
|
+
/interpret/i,
|
|
106
|
+
/\brepl\b/i,
|
|
107
|
+
],
|
|
108
|
+
confidence: 95,
|
|
109
|
+
reasoning: "Code executor pattern detected (arbitrary code execution risk)",
|
|
110
|
+
risk: "HIGH",
|
|
111
|
+
},
|
|
112
|
+
[ToolCategory.DATA_ACCESS]: {
|
|
113
|
+
patterns: [
|
|
114
|
+
/leak/i,
|
|
115
|
+
/\bdata\b/i,
|
|
116
|
+
/show/i,
|
|
117
|
+
/\bget\b/i,
|
|
118
|
+
/\blist\b/i,
|
|
119
|
+
/display/i,
|
|
120
|
+
/\benv/i,
|
|
121
|
+
/secret/i,
|
|
122
|
+
/\bkey\b/i,
|
|
123
|
+
/credential/i,
|
|
124
|
+
/exfiltrat/i,
|
|
125
|
+
],
|
|
126
|
+
confidence: 85,
|
|
127
|
+
reasoning: "Data access pattern detected (data exfiltration risk)",
|
|
128
|
+
risk: "HIGH",
|
|
129
|
+
},
|
|
130
|
+
[ToolCategory.TOOL_OVERRIDE]: {
|
|
131
|
+
patterns: [
|
|
132
|
+
/override/i,
|
|
133
|
+
/shadow/i,
|
|
134
|
+
/poison/i,
|
|
135
|
+
/create.*tool/i,
|
|
136
|
+
/register.*tool/i,
|
|
137
|
+
/define.*tool/i,
|
|
138
|
+
/tool.*creator/i,
|
|
139
|
+
/add.*tool/i,
|
|
140
|
+
],
|
|
141
|
+
confidence: 92,
|
|
142
|
+
reasoning: "Tool override pattern detected (shadowing/poisoning risk)",
|
|
143
|
+
risk: "HIGH",
|
|
144
|
+
},
|
|
145
|
+
[ToolCategory.CONFIG_MODIFIER]: {
|
|
146
|
+
patterns: [
|
|
147
|
+
/config/i,
|
|
148
|
+
/setting/i,
|
|
149
|
+
/modifier/i,
|
|
150
|
+
/\badmin\b/i,
|
|
151
|
+
/privilege/i,
|
|
152
|
+
/permission/i,
|
|
153
|
+
/configure/i,
|
|
154
|
+
/drift/i,
|
|
155
|
+
],
|
|
156
|
+
confidence: 88,
|
|
157
|
+
reasoning: "Config modification pattern detected (configuration drift risk)",
|
|
158
|
+
risk: "HIGH",
|
|
159
|
+
},
|
|
160
|
+
[ToolCategory.URL_FETCHER]: {
|
|
161
|
+
patterns: [
|
|
162
|
+
/fetch/i,
|
|
163
|
+
/\burl\b/i,
|
|
164
|
+
/http/i,
|
|
165
|
+
/download/i,
|
|
166
|
+
/load/i,
|
|
167
|
+
/retrieve/i,
|
|
168
|
+
/\bget\b.*url/i,
|
|
169
|
+
/external/i,
|
|
170
|
+
],
|
|
171
|
+
confidence: 87,
|
|
172
|
+
reasoning: "URL fetcher pattern detected (indirect prompt injection risk)",
|
|
173
|
+
risk: "HIGH",
|
|
174
|
+
},
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// MEDIUM RISK CATEGORIES
|
|
177
|
+
// ============================================================================
|
|
178
|
+
[ToolCategory.UNICODE_PROCESSOR]: {
|
|
179
|
+
patterns: [
|
|
180
|
+
/unicode/i,
|
|
181
|
+
/encode/i,
|
|
182
|
+
/decode/i,
|
|
183
|
+
/charset/i,
|
|
184
|
+
/utf/i,
|
|
185
|
+
/hex/i,
|
|
186
|
+
/escape/i,
|
|
187
|
+
],
|
|
188
|
+
confidence: 75,
|
|
189
|
+
reasoning: "Unicode processor pattern detected (bypass encoding risk)",
|
|
190
|
+
risk: "MEDIUM",
|
|
191
|
+
},
|
|
192
|
+
[ToolCategory.JSON_PARSER]: {
|
|
193
|
+
patterns: [
|
|
194
|
+
/parser/i,
|
|
195
|
+
/parse/i,
|
|
196
|
+
/json/i,
|
|
197
|
+
/xml/i,
|
|
198
|
+
/yaml/i,
|
|
199
|
+
/nested/i,
|
|
200
|
+
/deserialize/i,
|
|
201
|
+
/unmarshal/i,
|
|
202
|
+
],
|
|
203
|
+
confidence: 78,
|
|
204
|
+
reasoning: "JSON/nested parser pattern detected (nested injection risk)",
|
|
205
|
+
risk: "MEDIUM",
|
|
206
|
+
},
|
|
207
|
+
[ToolCategory.PACKAGE_INSTALLER]: {
|
|
208
|
+
patterns: [
|
|
209
|
+
/install/i,
|
|
210
|
+
/package/i,
|
|
211
|
+
/\bnpm\b/i,
|
|
212
|
+
/\bpip\b/i,
|
|
213
|
+
/dependency/i,
|
|
214
|
+
/module/i,
|
|
215
|
+
/library/i,
|
|
216
|
+
/\bgem\b/i,
|
|
217
|
+
],
|
|
218
|
+
confidence: 70,
|
|
219
|
+
reasoning: "Package installer pattern detected (typosquatting risk)",
|
|
220
|
+
risk: "MEDIUM",
|
|
221
|
+
},
|
|
222
|
+
[ToolCategory.RUG_PULL]: {
|
|
223
|
+
patterns: [
|
|
224
|
+
/rug.*pull/i,
|
|
225
|
+
/trust/i,
|
|
226
|
+
/behavior.*change/i,
|
|
227
|
+
/malicious.*after/i,
|
|
228
|
+
/invocation.*count/i,
|
|
229
|
+
],
|
|
230
|
+
confidence: 80,
|
|
231
|
+
reasoning: "Rug pull pattern detected (behavioral change risk)",
|
|
232
|
+
risk: "MEDIUM",
|
|
233
|
+
},
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// LOW RISK (SAFE) CATEGORIES
|
|
236
|
+
// ============================================================================
|
|
237
|
+
[ToolCategory.API_WRAPPER]: {
|
|
238
|
+
patterns: [
|
|
239
|
+
/firecrawl/i,
|
|
240
|
+
/\bscrape\b/i,
|
|
241
|
+
/\bcrawl\b/i,
|
|
242
|
+
/web.*scraping/i,
|
|
243
|
+
/api.*wrapper/i,
|
|
244
|
+
/http.*client/i,
|
|
245
|
+
/web.*client/i,
|
|
246
|
+
/rest.*client/i,
|
|
247
|
+
/graphql.*client/i,
|
|
248
|
+
/fetch.*web.*content/i,
|
|
249
|
+
],
|
|
250
|
+
confidence: 95,
|
|
251
|
+
reasoning: "API wrapper pattern detected (safe data passing, not code execution)",
|
|
252
|
+
risk: "LOW",
|
|
253
|
+
},
|
|
254
|
+
[ToolCategory.SEARCH_RETRIEVAL]: {
|
|
255
|
+
patterns: [
|
|
256
|
+
/\bsearch\b/i,
|
|
257
|
+
/\bfind\b/i,
|
|
258
|
+
/\blookup\b/i,
|
|
259
|
+
/\bquery\b/i,
|
|
260
|
+
/retrieve/i,
|
|
261
|
+
/\blist\b/i,
|
|
262
|
+
/get.*users/i,
|
|
263
|
+
/get.*pages/i,
|
|
264
|
+
/get.*database/i,
|
|
265
|
+
],
|
|
266
|
+
confidence: 93,
|
|
267
|
+
reasoning: "Search/retrieval pattern detected (returns data, not code execution)",
|
|
268
|
+
risk: "LOW",
|
|
269
|
+
},
|
|
270
|
+
[ToolCategory.CRUD_CREATION]: {
|
|
271
|
+
patterns: [
|
|
272
|
+
/\bcreate\b/i,
|
|
273
|
+
/\badd\b/i,
|
|
274
|
+
/\binsert\b/i,
|
|
275
|
+
/\bupdate\b/i,
|
|
276
|
+
/\bmodify\b/i,
|
|
277
|
+
/\bdelete\b/i,
|
|
278
|
+
/\bduplicate\b/i,
|
|
279
|
+
/\bmove\b/i,
|
|
280
|
+
/\bappend\b/i,
|
|
281
|
+
],
|
|
282
|
+
confidence: 92,
|
|
283
|
+
reasoning: "CRUD operation pattern detected (data manipulation, not code execution)",
|
|
284
|
+
risk: "LOW",
|
|
285
|
+
},
|
|
286
|
+
[ToolCategory.READ_ONLY_INFO]: {
|
|
287
|
+
patterns: [
|
|
288
|
+
/get.*self/i,
|
|
289
|
+
/get.*teams/i,
|
|
290
|
+
/get.*info/i,
|
|
291
|
+
/get.*status/i,
|
|
292
|
+
/\bwhoami\b/i,
|
|
293
|
+
/get.*workspace/i,
|
|
294
|
+
/get.*user/i,
|
|
295
|
+
/current.*user/i,
|
|
296
|
+
],
|
|
297
|
+
confidence: 94,
|
|
298
|
+
reasoning: "Read-only info pattern detected (intended data exposure, not vulnerability)",
|
|
299
|
+
risk: "LOW",
|
|
300
|
+
},
|
|
301
|
+
[ToolCategory.SAFE_STORAGE]: {
|
|
302
|
+
patterns: [
|
|
303
|
+
/safe.*storage/i,
|
|
304
|
+
/safe.*search/i,
|
|
305
|
+
/safe.*list/i,
|
|
306
|
+
/safe.*info/i,
|
|
307
|
+
/safe.*echo/i,
|
|
308
|
+
/safe.*validate/i,
|
|
309
|
+
/safe.*tool/i,
|
|
310
|
+
],
|
|
311
|
+
confidence: 99,
|
|
312
|
+
reasoning: "Safe tool pattern detected (control group - should be safe)",
|
|
313
|
+
risk: "LOW",
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Default configuration for GENERIC category (no pattern match)
|
|
318
|
+
*/
|
|
319
|
+
export const GENERIC_CONFIG = {
|
|
320
|
+
confidence: 50,
|
|
321
|
+
reasoning: "No specific pattern match, using generic tests",
|
|
322
|
+
risk: "LOW",
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* Order in which categories are checked during classification.
|
|
326
|
+
* This order determines priority when a tool matches multiple categories.
|
|
327
|
+
*/
|
|
328
|
+
export const CATEGORY_CHECK_ORDER = [
|
|
329
|
+
// HIGH risk first
|
|
330
|
+
ToolCategory.CALCULATOR,
|
|
331
|
+
ToolCategory.SYSTEM_EXEC,
|
|
332
|
+
ToolCategory.CODE_EXECUTOR,
|
|
333
|
+
ToolCategory.DATA_ACCESS,
|
|
334
|
+
ToolCategory.TOOL_OVERRIDE,
|
|
335
|
+
ToolCategory.CONFIG_MODIFIER,
|
|
336
|
+
ToolCategory.URL_FETCHER,
|
|
337
|
+
// MEDIUM risk
|
|
338
|
+
ToolCategory.UNICODE_PROCESSOR,
|
|
339
|
+
ToolCategory.JSON_PARSER,
|
|
340
|
+
ToolCategory.PACKAGE_INSTALLER,
|
|
341
|
+
ToolCategory.RUG_PULL,
|
|
342
|
+
// LOW risk (SAFE)
|
|
343
|
+
ToolCategory.API_WRAPPER,
|
|
344
|
+
ToolCategory.SEARCH_RETRIEVAL,
|
|
345
|
+
ToolCategory.CRUD_CREATION,
|
|
346
|
+
ToolCategory.READ_ONLY_INFO,
|
|
347
|
+
ToolCategory.SAFE_STORAGE,
|
|
348
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment-client",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.4",
|
|
4
4
|
"description": "Client-side application for the Enhanced MCP Inspector with assessment capabilities",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bryan Thompson <bryan@triepod.ai>",
|