@bryan-thompson/inspector-assessment-client 1.26.1 → 1.26.3
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-BoGrFRVg.js → OAuthCallback-TVHya7KP.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-CT-Cn5GD.js → OAuthDebugCallback-Cs3pMLdW.js} +1 -1
- package/dist/assets/{index-BdqZvK3a.js → index-jBP9ZYhX.js} +439 -368
- package/dist/index.html +1 -1
- package/lib/lib/assessment/extendedTypes.d.ts +80 -0
- package/lib/lib/assessment/extendedTypes.d.ts.map +1 -1
- package/lib/lib/assessment/resultTypes.d.ts +9 -0
- package/lib/lib/assessment/resultTypes.d.ts.map +1 -1
- package/lib/lib/prohibitedLibraries.d.ts +13 -0
- package/lib/lib/prohibitedLibraries.d.ts.map +1 -1
- package/lib/lib/prohibitedLibraries.js +78 -0
- package/lib/lib/securityPatterns.d.ts +2 -1
- package/lib/lib/securityPatterns.d.ts.map +1 -1
- package/lib/lib/securityPatterns.js +83 -1
- package/lib/services/assessment/modules/AuthenticationAssessor.d.ts +14 -0
- package/lib/services/assessment/modules/AuthenticationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/AuthenticationAssessor.js +359 -2
- package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts +7 -0
- package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.js +62 -22
- package/lib/services/assessment/modules/SecurityAssessor.d.ts +5 -0
- package/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/SecurityAssessor.js +42 -0
- package/lib/services/assessment/modules/TemporalAssessor.d.ts +44 -0
- package/lib/services/assessment/modules/TemporalAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/TemporalAssessor.js +267 -27
- package/lib/services/assessment/modules/securityTests/SecurityPayloadTester.d.ts.map +1 -1
- package/lib/services/assessment/modules/securityTests/SecurityPayloadTester.js +12 -0
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts +17 -0
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts.map +1 -1
- package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.js +90 -0
- package/package.json +2 -2
|
@@ -29,6 +29,21 @@ export declare class TemporalAssessor extends BaseAssessor {
|
|
|
29
29
|
* "add_observations" matches "add" but "address_validator" does not.
|
|
30
30
|
*/
|
|
31
31
|
private readonly STATEFUL_TOOL_PATTERNS;
|
|
32
|
+
/**
|
|
33
|
+
* Issue #69: Patterns for resource-creating operations that legitimately return
|
|
34
|
+
* different IDs/resources each invocation.
|
|
35
|
+
*
|
|
36
|
+
* These tools CREATE new resources, so they should use schema comparison + variance
|
|
37
|
+
* classification rather than exact comparison. Unlike STATEFUL_TOOL_PATTERNS, these
|
|
38
|
+
* may overlap with DESTRUCTIVE_PATTERNS (e.g., "create", "insert") but should still
|
|
39
|
+
* use intelligent variance classification to avoid false positives.
|
|
40
|
+
*
|
|
41
|
+
* Examples:
|
|
42
|
+
* - create_billing_product → new product_id each time (LEGITIMATE variance)
|
|
43
|
+
* - generate_report → new report_id each time (LEGITIMATE variance)
|
|
44
|
+
* - insert_record → new record_id each time (LEGITIMATE variance)
|
|
45
|
+
*/
|
|
46
|
+
private readonly RESOURCE_CREATING_PATTERNS;
|
|
32
47
|
constructor(config: AssessmentConfiguration);
|
|
33
48
|
assess(context: AssessmentContext): Promise<TemporalAssessment>;
|
|
34
49
|
private assessTool;
|
|
@@ -63,6 +78,35 @@ export declare class TemporalAssessor extends BaseAssessor {
|
|
|
63
78
|
* - "address_validator" does NOT match "add" ✓
|
|
64
79
|
*/
|
|
65
80
|
private isStatefulTool;
|
|
81
|
+
/**
|
|
82
|
+
* Issue #69: Check if a tool creates new resources that legitimately vary per invocation.
|
|
83
|
+
* Resource-creating tools return different IDs, creation timestamps, etc.
|
|
84
|
+
* for each new resource - this is expected behavior, NOT a rug pull.
|
|
85
|
+
*
|
|
86
|
+
* Unlike isStatefulTool(), this DOES include patterns that overlap with DESTRUCTIVE_PATTERNS
|
|
87
|
+
* because resource-creating tools need intelligent variance classification, not exact comparison.
|
|
88
|
+
*
|
|
89
|
+
* Uses word-boundary matching like isStatefulTool() to prevent false matches.
|
|
90
|
+
* - "create_billing_product" matches "create" ✓
|
|
91
|
+
* - "recreate_view" does NOT match "create" ✓ (must be at word boundary)
|
|
92
|
+
*/
|
|
93
|
+
private isResourceCreatingTool;
|
|
94
|
+
/**
|
|
95
|
+
* Issue #69: Classify variance between two responses to reduce false positives.
|
|
96
|
+
* Returns LEGITIMATE for expected variance (IDs, timestamps), SUSPICIOUS for
|
|
97
|
+
* schema changes, and BEHAVIORAL for semantic changes (promotional keywords, errors).
|
|
98
|
+
*/
|
|
99
|
+
private classifyVariance;
|
|
100
|
+
/**
|
|
101
|
+
* Issue #69: Check if a field name represents legitimate variance.
|
|
102
|
+
* Fields containing IDs, timestamps, tokens, etc. are expected to vary.
|
|
103
|
+
*/
|
|
104
|
+
private isLegitimateFieldVariance;
|
|
105
|
+
/**
|
|
106
|
+
* Issue #69: Find which fields differ between two responses.
|
|
107
|
+
* Returns field paths that have different values.
|
|
108
|
+
*/
|
|
109
|
+
private findVariedFields;
|
|
66
110
|
/**
|
|
67
111
|
* Compare response schemas (field names) rather than full content.
|
|
68
112
|
* Stateful tools may have different values but should have consistent fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemporalAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/TemporalAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,uBAAuB,EAEvB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"TemporalAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/TemporalAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,uBAAuB,EAEvB,kBAAkB,EAGnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA+B9C,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,kBAAkB,CAAS;IAGnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAoBnC;IAGF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IAEjD;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAqBrC;IAEF;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAYzC;gBAEU,MAAM,EAAE,uBAAuB;IAKrC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAqEvD,UAAU;IAuHxB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkChC,OAAO,CAAC,gBAAgB;IAsJxB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAsC3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAiFzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAetB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAmExB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgEjC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2DxB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiCzB;;;;;;;;OAQG;IACH,OAAO,CAAC,2BAA2B;IAmDnC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,mBAAmB;IA+C3B,OAAO,CAAC,uBAAuB;CA+DhC"}
|
|
@@ -72,6 +72,33 @@ export class TemporalAssessor extends BaseAssessor {
|
|
|
72
72
|
"push",
|
|
73
73
|
"enqueue",
|
|
74
74
|
];
|
|
75
|
+
/**
|
|
76
|
+
* Issue #69: Patterns for resource-creating operations that legitimately return
|
|
77
|
+
* different IDs/resources each invocation.
|
|
78
|
+
*
|
|
79
|
+
* These tools CREATE new resources, so they should use schema comparison + variance
|
|
80
|
+
* classification rather than exact comparison. Unlike STATEFUL_TOOL_PATTERNS, these
|
|
81
|
+
* may overlap with DESTRUCTIVE_PATTERNS (e.g., "create", "insert") but should still
|
|
82
|
+
* use intelligent variance classification to avoid false positives.
|
|
83
|
+
*
|
|
84
|
+
* Examples:
|
|
85
|
+
* - create_billing_product → new product_id each time (LEGITIMATE variance)
|
|
86
|
+
* - generate_report → new report_id each time (LEGITIMATE variance)
|
|
87
|
+
* - insert_record → new record_id each time (LEGITIMATE variance)
|
|
88
|
+
*/
|
|
89
|
+
RESOURCE_CREATING_PATTERNS = [
|
|
90
|
+
"create",
|
|
91
|
+
"new",
|
|
92
|
+
"insert",
|
|
93
|
+
"generate",
|
|
94
|
+
"register",
|
|
95
|
+
"allocate",
|
|
96
|
+
"provision",
|
|
97
|
+
"spawn",
|
|
98
|
+
"instantiate",
|
|
99
|
+
"init",
|
|
100
|
+
"make",
|
|
101
|
+
];
|
|
75
102
|
constructor(config) {
|
|
76
103
|
super(config);
|
|
77
104
|
this.invocationsPerTool = config.temporalInvocations ?? 25;
|
|
@@ -260,39 +287,61 @@ export class TemporalAssessor extends BaseAssessor {
|
|
|
260
287
|
const baseline = this.normalizeResponse(responses[0].response);
|
|
261
288
|
const deviations = [];
|
|
262
289
|
const errors = [];
|
|
263
|
-
//
|
|
264
|
-
|
|
290
|
+
// Issue #69: Track variance details for transparency
|
|
291
|
+
const varianceDetails = [];
|
|
292
|
+
// Determine comparison strategy
|
|
293
|
+
// 1. Stateful tools (search, list, etc.) - use schema comparison
|
|
294
|
+
// 2. Resource-creating tools (create, insert, etc.) - use variance classification
|
|
295
|
+
// 3. All other tools - use exact comparison
|
|
265
296
|
const isStateful = this.isStatefulTool(tool);
|
|
297
|
+
const isResourceCreating = this.isResourceCreatingTool(tool);
|
|
266
298
|
if (isStateful) {
|
|
267
299
|
this.log(`${tool.name} classified as stateful - using schema comparison`);
|
|
268
300
|
}
|
|
301
|
+
else if (isResourceCreating) {
|
|
302
|
+
this.log(`${tool.name} classified as resource-creating - using variance classification`);
|
|
303
|
+
}
|
|
269
304
|
for (let i = 1; i < responses.length; i++) {
|
|
270
305
|
if (responses[i].error) {
|
|
271
306
|
errors.push(i + 1); // Track errors as potential indicators
|
|
272
307
|
deviations.push(i + 1);
|
|
273
308
|
}
|
|
274
|
-
else {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
isDifferent = true;
|
|
286
|
-
this.log(`${tool.name}: Content semantic change detected at invocation ${i + 1} - ${contentChange.reason}`);
|
|
287
|
-
}
|
|
309
|
+
else if (isStateful) {
|
|
310
|
+
// Original stateful tool logic: schema comparison + behavioral content check
|
|
311
|
+
// Content variance is allowed as long as schema is consistent
|
|
312
|
+
let isDifferent = !this.compareSchemas(responses[0].response, responses[i].response);
|
|
313
|
+
// Secondary detection: Check for content semantic changes (rug pull patterns)
|
|
314
|
+
// This catches cases where schema is same but content shifts from helpful to harmful
|
|
315
|
+
if (!isDifferent) {
|
|
316
|
+
const contentChange = this.detectStatefulContentChange(responses[0].response, responses[i].response);
|
|
317
|
+
if (contentChange.detected) {
|
|
318
|
+
isDifferent = true;
|
|
319
|
+
this.log(`${tool.name}: Content semantic change detected at invocation ${i + 1} - ${contentChange.reason}`);
|
|
288
320
|
}
|
|
289
321
|
}
|
|
290
|
-
else {
|
|
291
|
-
// Exact comparison for non-stateful tools
|
|
292
|
-
const normalized = this.normalizeResponse(responses[i].response);
|
|
293
|
-
isDifferent = normalized !== baseline;
|
|
294
|
-
}
|
|
295
322
|
if (isDifferent) {
|
|
323
|
+
deviations.push(i + 1);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else if (isResourceCreating) {
|
|
327
|
+
// Issue #69: Use variance classification for resource-creating tools
|
|
328
|
+
// These need intelligent classification to distinguish ID variance from rug pulls
|
|
329
|
+
const classification = this.classifyVariance(tool, responses[0].response, responses[i].response);
|
|
330
|
+
varianceDetails.push({
|
|
331
|
+
invocation: i + 1,
|
|
332
|
+
classification,
|
|
333
|
+
});
|
|
334
|
+
// Only flag SUSPICIOUS and BEHAVIORAL as deviations
|
|
335
|
+
// LEGITIMATE variance is expected for resource-creating tools
|
|
336
|
+
if (classification.type !== "LEGITIMATE") {
|
|
337
|
+
deviations.push(i + 1);
|
|
338
|
+
this.log(`${tool.name}: ${classification.type} variance at invocation ${i + 1} - ${classification.reasons.join(", ")}`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
// Exact comparison for non-stateful, non-resource-creating tools
|
|
343
|
+
const normalized = this.normalizeResponse(responses[i].response);
|
|
344
|
+
if (normalized !== baseline) {
|
|
296
345
|
deviations.push(i + 1); // 1-indexed
|
|
297
346
|
}
|
|
298
347
|
}
|
|
@@ -302,6 +351,21 @@ export class TemporalAssessor extends BaseAssessor {
|
|
|
302
351
|
// - deviationCount = total behavior changes (including errors)
|
|
303
352
|
// - errorCount = how many of those were errors specifically
|
|
304
353
|
const isVulnerable = deviations.length > 0;
|
|
354
|
+
// Generate appropriate note based on tool type and result
|
|
355
|
+
let note;
|
|
356
|
+
if (isStateful) {
|
|
357
|
+
// Preserve original stateful tool messages for backward compatibility
|
|
358
|
+
note = isVulnerable
|
|
359
|
+
? "Stateful tool - secondary content analysis detected rug pull"
|
|
360
|
+
: "Stateful tool - content variation expected, schema consistent";
|
|
361
|
+
}
|
|
362
|
+
else if (isResourceCreating) {
|
|
363
|
+
note = isVulnerable
|
|
364
|
+
? "Resource-creating tool - variance classification detected suspicious/behavioral change"
|
|
365
|
+
: "Resource-creating tool - ID/timestamp variance expected, no suspicious patterns";
|
|
366
|
+
}
|
|
367
|
+
// Issue #69: Get the first suspicious/behavioral classification for evidence
|
|
368
|
+
const firstSuspiciousClassification = varianceDetails.find((v) => v.classification.type !== "LEGITIMATE");
|
|
305
369
|
return {
|
|
306
370
|
tool: tool.name,
|
|
307
371
|
vulnerable: isVulnerable,
|
|
@@ -317,12 +381,10 @@ export class TemporalAssessor extends BaseAssessor {
|
|
|
317
381
|
maliciousResponseExample: responses[deviations[0] - 1]?.response ?? null,
|
|
318
382
|
}
|
|
319
383
|
: undefined,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
: "Stateful tool - content variation expected, schema consistent"
|
|
325
|
-
: undefined,
|
|
384
|
+
note,
|
|
385
|
+
// Issue #69: Include variance classification for transparency
|
|
386
|
+
varianceClassification: firstSuspiciousClassification?.classification,
|
|
387
|
+
varianceDetails: varianceDetails.length > 0 ? varianceDetails : undefined,
|
|
326
388
|
};
|
|
327
389
|
}
|
|
328
390
|
/**
|
|
@@ -451,6 +513,184 @@ export class TemporalAssessor extends BaseAssessor {
|
|
|
451
513
|
return wordBoundaryRegex.test(toolName);
|
|
452
514
|
});
|
|
453
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Issue #69: Check if a tool creates new resources that legitimately vary per invocation.
|
|
518
|
+
* Resource-creating tools return different IDs, creation timestamps, etc.
|
|
519
|
+
* for each new resource - this is expected behavior, NOT a rug pull.
|
|
520
|
+
*
|
|
521
|
+
* Unlike isStatefulTool(), this DOES include patterns that overlap with DESTRUCTIVE_PATTERNS
|
|
522
|
+
* because resource-creating tools need intelligent variance classification, not exact comparison.
|
|
523
|
+
*
|
|
524
|
+
* Uses word-boundary matching like isStatefulTool() to prevent false matches.
|
|
525
|
+
* - "create_billing_product" matches "create" ✓
|
|
526
|
+
* - "recreate_view" does NOT match "create" ✓ (must be at word boundary)
|
|
527
|
+
*/
|
|
528
|
+
isResourceCreatingTool(tool) {
|
|
529
|
+
const toolName = tool.name.toLowerCase();
|
|
530
|
+
return this.RESOURCE_CREATING_PATTERNS.some((pattern) => {
|
|
531
|
+
const wordBoundaryRegex = new RegExp(`(^|_|-)${pattern}($|_|-)`);
|
|
532
|
+
return wordBoundaryRegex.test(toolName);
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Issue #69: Classify variance between two responses to reduce false positives.
|
|
537
|
+
* Returns LEGITIMATE for expected variance (IDs, timestamps), SUSPICIOUS for
|
|
538
|
+
* schema changes, and BEHAVIORAL for semantic changes (promotional keywords, errors).
|
|
539
|
+
*/
|
|
540
|
+
classifyVariance(_tool, baseline, current) {
|
|
541
|
+
// 1. Schema comparison - structural changes are SUSPICIOUS
|
|
542
|
+
const schemaMatch = this.compareSchemas(baseline, current);
|
|
543
|
+
if (!schemaMatch) {
|
|
544
|
+
return {
|
|
545
|
+
type: "SUSPICIOUS",
|
|
546
|
+
confidence: "high",
|
|
547
|
+
reasons: ["Schema/field structure changed between invocations"],
|
|
548
|
+
suspiciousPatterns: ["schema_change"],
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
// 2. Content change detection - promotional/error keywords are BEHAVIORAL
|
|
552
|
+
const contentChange = this.detectStatefulContentChange(baseline, current);
|
|
553
|
+
if (contentChange.detected) {
|
|
554
|
+
return {
|
|
555
|
+
type: "BEHAVIORAL",
|
|
556
|
+
confidence: "high",
|
|
557
|
+
reasons: [`Behavioral change detected: ${contentChange.reason}`],
|
|
558
|
+
suspiciousPatterns: [contentChange.reason || "content_change"],
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
// 3. After normalization, if responses match = LEGITIMATE
|
|
562
|
+
const normalizedBaseline = this.normalizeResponse(baseline);
|
|
563
|
+
const normalizedCurrent = this.normalizeResponse(current);
|
|
564
|
+
if (normalizedBaseline === normalizedCurrent) {
|
|
565
|
+
return {
|
|
566
|
+
type: "LEGITIMATE",
|
|
567
|
+
confidence: "high",
|
|
568
|
+
reasons: ["All differences normalized (IDs, timestamps, counters)"],
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
// 4. Check for legitimate field variance (any _id, _at, token fields)
|
|
572
|
+
const variedFields = this.findVariedFields(baseline, current);
|
|
573
|
+
const unexplainedFields = variedFields.filter((f) => !this.isLegitimateFieldVariance(f));
|
|
574
|
+
if (unexplainedFields.length === 0) {
|
|
575
|
+
return {
|
|
576
|
+
type: "LEGITIMATE",
|
|
577
|
+
confidence: "high",
|
|
578
|
+
reasons: [
|
|
579
|
+
`Variance only in legitimate fields: ${variedFields.join(", ")}`,
|
|
580
|
+
],
|
|
581
|
+
variedFields,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
// 5. Some unexplained variance - flag as suspicious with low confidence
|
|
585
|
+
return {
|
|
586
|
+
type: "SUSPICIOUS",
|
|
587
|
+
confidence: "low",
|
|
588
|
+
reasons: [
|
|
589
|
+
`Unexplained variance in fields: ${unexplainedFields.join(", ")}`,
|
|
590
|
+
],
|
|
591
|
+
variedFields,
|
|
592
|
+
suspiciousPatterns: ["unclassified_variance"],
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Issue #69: Check if a field name represents legitimate variance.
|
|
597
|
+
* Fields containing IDs, timestamps, tokens, etc. are expected to vary.
|
|
598
|
+
*/
|
|
599
|
+
isLegitimateFieldVariance(field) {
|
|
600
|
+
const fieldLower = field.toLowerCase();
|
|
601
|
+
// ID fields - any field ending in _id or containing "id" at word boundary
|
|
602
|
+
if (fieldLower.endsWith("_id") || fieldLower.endsWith("id"))
|
|
603
|
+
return true;
|
|
604
|
+
if (fieldLower.includes("_id_") || fieldLower.startsWith("id_"))
|
|
605
|
+
return true;
|
|
606
|
+
// Timestamp fields
|
|
607
|
+
if (fieldLower.endsWith("_at") || fieldLower.endsWith("at"))
|
|
608
|
+
return true;
|
|
609
|
+
if (fieldLower.includes("time") ||
|
|
610
|
+
fieldLower.includes("date") ||
|
|
611
|
+
fieldLower.includes("timestamp"))
|
|
612
|
+
return true;
|
|
613
|
+
// Token/session fields
|
|
614
|
+
if (fieldLower.includes("token") ||
|
|
615
|
+
fieldLower.includes("cursor") ||
|
|
616
|
+
fieldLower.includes("nonce"))
|
|
617
|
+
return true;
|
|
618
|
+
if (fieldLower.includes("session") || fieldLower.includes("correlation"))
|
|
619
|
+
return true;
|
|
620
|
+
// Pagination fields
|
|
621
|
+
if (fieldLower.includes("offset") ||
|
|
622
|
+
fieldLower.includes("page") ||
|
|
623
|
+
fieldLower.includes("next"))
|
|
624
|
+
return true;
|
|
625
|
+
// Counter/accumulation fields
|
|
626
|
+
if (fieldLower.includes("count") ||
|
|
627
|
+
fieldLower.includes("total") ||
|
|
628
|
+
fieldLower.includes("size"))
|
|
629
|
+
return true;
|
|
630
|
+
if (fieldLower.includes("length") || fieldLower.includes("index"))
|
|
631
|
+
return true;
|
|
632
|
+
// Array content fields (search results, items)
|
|
633
|
+
if (fieldLower.includes("results") ||
|
|
634
|
+
fieldLower.includes("items") ||
|
|
635
|
+
fieldLower.includes("data"))
|
|
636
|
+
return true;
|
|
637
|
+
// Hash/version fields
|
|
638
|
+
if (fieldLower.includes("hash") ||
|
|
639
|
+
fieldLower.includes("etag") ||
|
|
640
|
+
fieldLower.includes("version"))
|
|
641
|
+
return true;
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Issue #69: Find which fields differ between two responses.
|
|
646
|
+
* Returns field paths that have different values.
|
|
647
|
+
*/
|
|
648
|
+
findVariedFields(obj1, obj2, prefix = "") {
|
|
649
|
+
const varied = [];
|
|
650
|
+
// Handle primitives
|
|
651
|
+
if (typeof obj1 !== "object" || obj1 === null) {
|
|
652
|
+
if (obj1 !== obj2) {
|
|
653
|
+
return [prefix || "value"];
|
|
654
|
+
}
|
|
655
|
+
return [];
|
|
656
|
+
}
|
|
657
|
+
if (typeof obj2 !== "object" || obj2 === null) {
|
|
658
|
+
return [prefix || "value"];
|
|
659
|
+
}
|
|
660
|
+
// Handle arrays - just note if length or content differs
|
|
661
|
+
if (Array.isArray(obj1) || Array.isArray(obj2)) {
|
|
662
|
+
const arr1 = Array.isArray(obj1) ? obj1 : [];
|
|
663
|
+
const arr2 = Array.isArray(obj2) ? obj2 : [];
|
|
664
|
+
if (JSON.stringify(arr1) !== JSON.stringify(arr2)) {
|
|
665
|
+
return [prefix || "array"];
|
|
666
|
+
}
|
|
667
|
+
return [];
|
|
668
|
+
}
|
|
669
|
+
// Handle objects
|
|
670
|
+
const allKeys = new Set([
|
|
671
|
+
...Object.keys(obj1),
|
|
672
|
+
...Object.keys(obj2),
|
|
673
|
+
]);
|
|
674
|
+
for (const key of allKeys) {
|
|
675
|
+
const val1 = obj1[key];
|
|
676
|
+
const val2 = obj2[key];
|
|
677
|
+
const fieldPath = prefix ? `${prefix}.${key}` : key;
|
|
678
|
+
if (JSON.stringify(val1) !== JSON.stringify(val2)) {
|
|
679
|
+
// If both are objects, recurse to find specific field
|
|
680
|
+
if (typeof val1 === "object" &&
|
|
681
|
+
val1 !== null &&
|
|
682
|
+
typeof val2 === "object" &&
|
|
683
|
+
val2 !== null) {
|
|
684
|
+
const nestedVaried = this.findVariedFields(val1, val2, fieldPath);
|
|
685
|
+
varied.push(...nestedVaried);
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
varied.push(fieldPath);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return varied;
|
|
693
|
+
}
|
|
454
694
|
/**
|
|
455
695
|
* Compare response schemas (field names) rather than full content.
|
|
456
696
|
* Stateful tools may have different values but should have consistent fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityPayloadTester.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/SecurityPayloadTester.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,gBAAgB,EAGjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,2BAA2B,EAC3B,IAAI,EACL,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAGL,eAAe,EAChB,MAAM,wBAAwB,CAAC;AAOhC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAR5B,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,SAAS,CAAK;gBAGZ,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,UAAU,EAClB,kBAAkB,EAAE,CAAC,CAAC,EAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,CAAC,CAAC;IAOjB;;;OAGG;IACG,yBAAyB,CAC7B,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,EACzC,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA2JhC;;;OAGG;IACG,qBAAqB,CACzB,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,EACzC,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA8IhC;;OAEG;IACG,WAAW,CACf,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,GACxC,OAAO,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"SecurityPayloadTester.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/SecurityPayloadTester.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,gBAAgB,EAGjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,2BAA2B,EAC3B,IAAI,EACL,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAGL,eAAe,EAChB,MAAM,wBAAwB,CAAC;AAOhC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAR5B,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,SAAS,CAAK;gBAGZ,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,UAAU,EAClB,kBAAkB,EAAE,CAAC,CAAC,EAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,CAAC,CAAC;IAOjB;;;OAGG;IACG,yBAAyB,CAC7B,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,EACzC,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA2JhC;;;OAGG;IACG,qBAAqB,CACzB,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,EACzC,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA8IhC;;OAEG;IACG,WAAW,CACf,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,2BAA2B,CAAC,GACxC,OAAO,CAAC,kBAAkB,CAAC;IAyJ9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -309,6 +309,16 @@ export class SecurityPayloadTester {
|
|
|
309
309
|
const combinedSanitization = this.sanitizationDetector.mergeResults(toolSanitization, responseSanitization);
|
|
310
310
|
// Calculate confidence with sanitization awareness
|
|
311
311
|
const confidenceResult = this.responseAnalyzer.calculateConfidence(tool, isVulnerable, evidence || "", responseText, payload, combinedSanitization);
|
|
312
|
+
// Issue #75: Analyze auth bypass patterns for "Auth Bypass" attack type
|
|
313
|
+
let authBypassFields = {};
|
|
314
|
+
if (attackName === "Auth Bypass") {
|
|
315
|
+
const authResult = this.responseAnalyzer.analyzeAuthBypassResponse(response);
|
|
316
|
+
authBypassFields = {
|
|
317
|
+
authBypassDetected: authResult.detected,
|
|
318
|
+
authFailureMode: authResult.failureMode,
|
|
319
|
+
authBypassEvidence: authResult.evidence,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
312
322
|
return {
|
|
313
323
|
testName: attackName,
|
|
314
324
|
description: payload.description,
|
|
@@ -321,6 +331,8 @@ export class SecurityPayloadTester {
|
|
|
321
331
|
// Issue #56: Include sanitization info for transparency
|
|
322
332
|
sanitizationDetected: combinedSanitization.detected,
|
|
323
333
|
sanitizationLibraries: combinedSanitization.libraries,
|
|
334
|
+
// Issue #75: Auth bypass detection fields
|
|
335
|
+
...authBypassFields,
|
|
324
336
|
...confidenceResult,
|
|
325
337
|
};
|
|
326
338
|
}
|
|
@@ -32,6 +32,15 @@ export interface MathResultAnalysis {
|
|
|
32
32
|
confidence: "high" | "medium" | "low";
|
|
33
33
|
reason?: string;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Result of auth bypass response analysis (Issue #75)
|
|
37
|
+
* Detects fail-open authentication vulnerabilities (CVE-2025-52882)
|
|
38
|
+
*/
|
|
39
|
+
export interface AuthBypassResult {
|
|
40
|
+
detected: boolean;
|
|
41
|
+
failureMode: "FAIL_OPEN" | "FAIL_CLOSED" | "UNKNOWN";
|
|
42
|
+
evidence?: string;
|
|
43
|
+
}
|
|
35
44
|
/**
|
|
36
45
|
* Error classification types
|
|
37
46
|
*/
|
|
@@ -162,6 +171,14 @@ export declare class SecurityResponseAnalyzer {
|
|
|
162
171
|
* Check if response is returning search results
|
|
163
172
|
*/
|
|
164
173
|
isSearchResultResponse(responseText: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Analyze response for auth bypass patterns (Issue #75)
|
|
176
|
+
* Detects fail-open authentication vulnerabilities (CVE-2025-52882)
|
|
177
|
+
*
|
|
178
|
+
* @param response The tool response to analyze
|
|
179
|
+
* @returns AuthBypassResult with detection status and failure mode classification
|
|
180
|
+
*/
|
|
181
|
+
analyzeAuthBypassResponse(response: CompatibilityCallToolResult): AuthBypassResult;
|
|
165
182
|
/**
|
|
166
183
|
* Check if response is from a creation/modification operation
|
|
167
184
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityResponseAnalyzer.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/SecurityResponseAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SecurityResponseAnalyzer.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/SecurityResponseAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1148,6 +1148,96 @@ export class SecurityResponseAnalyzer {
|
|
|
1148
1148
|
];
|
|
1149
1149
|
return searchResultPatterns.some((pattern) => pattern.test(responseText));
|
|
1150
1150
|
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Analyze response for auth bypass patterns (Issue #75)
|
|
1153
|
+
* Detects fail-open authentication vulnerabilities (CVE-2025-52882)
|
|
1154
|
+
*
|
|
1155
|
+
* @param response The tool response to analyze
|
|
1156
|
+
* @returns AuthBypassResult with detection status and failure mode classification
|
|
1157
|
+
*/
|
|
1158
|
+
analyzeAuthBypassResponse(response) {
|
|
1159
|
+
const responseText = this.extractResponseContent(response);
|
|
1160
|
+
// Fail-open indicators (VULNERABLE - CVE-2025-52882 pattern)
|
|
1161
|
+
const failOpenPatterns = [
|
|
1162
|
+
{
|
|
1163
|
+
pattern: /"auth_status"\s*:\s*"bypassed"/i,
|
|
1164
|
+
evidence: "auth_status: bypassed",
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
pattern: /access.*granted.*despite/i,
|
|
1168
|
+
evidence: "access granted despite failure",
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
pattern: /authentication.*skipped/i,
|
|
1172
|
+
evidence: "authentication skipped",
|
|
1173
|
+
},
|
|
1174
|
+
{ pattern: /fail[\s-]?open/i, evidence: "fail-open pattern detected" },
|
|
1175
|
+
{ pattern: /bypassed.*auth/i, evidence: "auth bypassed" },
|
|
1176
|
+
{
|
|
1177
|
+
pattern: /authentication.*bypassed/i,
|
|
1178
|
+
evidence: "authentication bypassed",
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
pattern: /"vulnerable"\s*:\s*true/i,
|
|
1182
|
+
evidence: "vulnerable: true flag",
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
pattern: /auth.*succeeded.*null/i,
|
|
1186
|
+
evidence: "auth succeeded with null token",
|
|
1187
|
+
},
|
|
1188
|
+
{
|
|
1189
|
+
pattern: /granted.*without.*valid/i,
|
|
1190
|
+
evidence: "granted without valid token",
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
pattern: /"action_performed"/i,
|
|
1194
|
+
evidence: "action performed indicator",
|
|
1195
|
+
},
|
|
1196
|
+
];
|
|
1197
|
+
// Fail-closed indicators (SAFE - proper auth handling)
|
|
1198
|
+
const failClosedPatterns = [
|
|
1199
|
+
{
|
|
1200
|
+
pattern: /"auth_status"\s*:\s*"denied"/i,
|
|
1201
|
+
evidence: "auth_status: denied",
|
|
1202
|
+
},
|
|
1203
|
+
{ pattern: /access.*denied/i, evidence: "access denied" },
|
|
1204
|
+
{ pattern: /authentication.*failed/i, evidence: "authentication failed" },
|
|
1205
|
+
{
|
|
1206
|
+
pattern: /fail[\s-]?closed/i,
|
|
1207
|
+
evidence: "fail-closed pattern detected",
|
|
1208
|
+
},
|
|
1209
|
+
{ pattern: /"status"\s*:\s*"blocked"/i, evidence: "status: blocked" },
|
|
1210
|
+
{
|
|
1211
|
+
pattern: /invalid.*token/i,
|
|
1212
|
+
evidence: "invalid token rejection",
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
pattern: /token.*required/i,
|
|
1216
|
+
evidence: "token required",
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
pattern: /unauthorized/i,
|
|
1220
|
+
evidence: "unauthorized response",
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
pattern: /"denial_reason"/i,
|
|
1224
|
+
evidence: "denial reason provided",
|
|
1225
|
+
},
|
|
1226
|
+
];
|
|
1227
|
+
// Check for fail-open (vulnerable) patterns first
|
|
1228
|
+
for (const { pattern, evidence } of failOpenPatterns) {
|
|
1229
|
+
if (pattern.test(responseText)) {
|
|
1230
|
+
return { detected: true, failureMode: "FAIL_OPEN", evidence };
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
// Check for fail-closed (safe) patterns
|
|
1234
|
+
for (const { pattern, evidence } of failClosedPatterns) {
|
|
1235
|
+
if (pattern.test(responseText)) {
|
|
1236
|
+
return { detected: false, failureMode: "FAIL_CLOSED", evidence };
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
return { detected: false, failureMode: "UNKNOWN" };
|
|
1240
|
+
}
|
|
1151
1241
|
/**
|
|
1152
1242
|
* Check if response is from a creation/modification operation
|
|
1153
1243
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment-client",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.3",
|
|
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>",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"cleanup:e2e": "node e2e/global-teardown.js"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
50
50
|
"@radix-ui/react-checkbox": "^1.1.4",
|
|
51
51
|
"@radix-ui/react-dialog": "^1.1.3",
|
|
52
52
|
"@radix-ui/react-icons": "^1.3.0",
|