agentic-qe 3.8.4 → 3.8.5
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/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +12 -0
- package/dist/cli/bundle.js +694 -694
- package/dist/cli/commands/hooks-handlers/command-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/command-hooks.js +253 -0
- package/dist/cli/commands/hooks-handlers/editing-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/editing-hooks.js +161 -0
- package/dist/cli/commands/hooks-handlers/hooks-dream-learning.d.ts +57 -0
- package/dist/cli/commands/hooks-handlers/hooks-dream-learning.js +263 -0
- package/dist/cli/commands/hooks-handlers/hooks-shared.d.ts +52 -0
- package/dist/cli/commands/hooks-handlers/hooks-shared.js +223 -0
- package/dist/cli/commands/hooks-handlers/routing-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/routing-hooks.js +107 -0
- package/dist/cli/commands/hooks-handlers/session-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/session-hooks.js +171 -0
- package/dist/cli/commands/hooks-handlers/stats-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/stats-hooks.js +248 -0
- package/dist/cli/commands/hooks-handlers/task-hooks.d.ts +12 -0
- package/dist/cli/commands/hooks-handlers/task-hooks.js +152 -0
- package/dist/cli/commands/hooks.d.ts +3 -23
- package/dist/cli/commands/hooks.js +16 -1459
- package/dist/domains/base-domain-coordinator.d.ts +0 -15
- package/dist/domains/base-domain-coordinator.js +7 -5
- package/dist/domains/chaos-resilience/coordinator.d.ts +0 -4
- package/dist/domains/chaos-resilience/coordinator.js +24 -22
- package/dist/domains/chaos-resilience/services/chaos-engineer.d.ts +0 -4
- package/dist/domains/chaos-resilience/services/chaos-engineer.js +47 -45
- package/dist/domains/chaos-resilience/services/performance-profiler.d.ts +0 -4
- package/dist/domains/chaos-resilience/services/performance-profiler.js +10 -8
- package/dist/domains/code-intelligence/coordinator-consensus.d.ts +0 -3
- package/dist/domains/code-intelligence/coordinator-consensus.js +8 -6
- package/dist/domains/code-intelligence/coordinator-gnn.d.ts +0 -3
- package/dist/domains/code-intelligence/coordinator-gnn.js +8 -6
- package/dist/domains/code-intelligence/coordinator-hypergraph.d.ts +0 -3
- package/dist/domains/code-intelligence/coordinator-hypergraph.js +13 -11
- package/dist/domains/code-intelligence/coordinator.d.ts +0 -3
- package/dist/domains/code-intelligence/coordinator.js +21 -19
- package/dist/domains/code-intelligence/services/c4-model/index.d.ts +0 -3
- package/dist/domains/code-intelligence/services/c4-model/index.js +5 -3
- package/dist/domains/code-intelligence/services/knowledge-graph.d.ts +0 -6
- package/dist/domains/code-intelligence/services/knowledge-graph.js +4 -2
- package/dist/domains/code-intelligence/services/product-factors-bridge.d.ts +0 -5
- package/dist/domains/code-intelligence/services/product-factors-bridge.js +9 -7
- package/dist/domains/contract-testing/coordinator.d.ts +0 -6
- package/dist/domains/contract-testing/coordinator.js +25 -23
- package/dist/domains/contract-testing/services/contract-validator.d.ts +0 -4
- package/dist/domains/contract-testing/services/contract-validator.js +4 -2
- package/dist/domains/contract-testing/services/schema-validator.js +1 -1
- package/dist/domains/coverage-analysis/coordinator.js +13 -11
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +4 -2
- package/dist/domains/coverage-analysis/services/gap-detector.js +3 -1
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts +0 -15
- package/dist/domains/coverage-analysis/services/hnsw-index.js +3 -1
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts +0 -26
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js +3 -1
- package/dist/domains/defect-intelligence/coordinator.d.ts +1 -10
- package/dist/domains/defect-intelligence/coordinator.js +5 -3
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.d.ts +0 -6
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.js +3 -1
- package/dist/domains/defect-intelligence/services/defect-predictor.d.ts +0 -6
- package/dist/domains/defect-intelligence/services/defect-predictor.js +5 -3
- package/dist/domains/defect-intelligence/services/pattern-learner.d.ts +0 -4
- package/dist/domains/defect-intelligence/services/pattern-learner.js +3 -1
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts +0 -6
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +3 -1
- package/dist/domains/enterprise-integration/coordinator.js +6 -4
- package/dist/domains/learning-optimization/coordinator-consensus.d.ts +0 -3
- package/dist/domains/learning-optimization/coordinator-consensus.js +8 -6
- package/dist/domains/learning-optimization/coordinator.d.ts +0 -3
- package/dist/domains/learning-optimization/coordinator.js +15 -13
- package/dist/domains/learning-optimization/services/learning-coordinator.d.ts +0 -4
- package/dist/domains/learning-optimization/services/learning-coordinator.js +4 -2
- package/dist/domains/quality-assessment/coordinator-claim-verifier.d.ts +0 -3
- package/dist/domains/quality-assessment/coordinator-claim-verifier.js +6 -4
- package/dist/domains/quality-assessment/coordinator-gate-evaluation.d.ts +0 -4
- package/dist/domains/quality-assessment/coordinator-gate-evaluation.js +9 -7
- package/dist/domains/quality-assessment/coordinator-rl-integration.d.ts +0 -3
- package/dist/domains/quality-assessment/coordinator-rl-integration.js +10 -8
- package/dist/domains/quality-assessment/coordinator.d.ts +0 -15
- package/dist/domains/quality-assessment/coordinator.js +14 -12
- package/dist/domains/quality-assessment/services/deployment-advisor.d.ts +0 -10
- package/dist/domains/quality-assessment/services/deployment-advisor.js +4 -2
- package/dist/domains/quality-assessment/services/quality-analyzer.d.ts +0 -6
- package/dist/domains/quality-assessment/services/quality-analyzer.js +4 -2
- package/dist/domains/requirements-validation/coordinator.d.ts +0 -3
- package/dist/domains/requirements-validation/coordinator.js +15 -13
- package/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.d.ts +0 -5
- package/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.js +15 -13
- package/dist/domains/requirements-validation/services/product-factors-assessment/product-factors-service.d.ts +0 -6
- package/dist/domains/requirements-validation/services/product-factors-assessment/product-factors-service.js +9 -7
- package/dist/domains/requirements-validation/services/requirements-validator.d.ts +0 -6
- package/dist/domains/requirements-validation/services/requirements-validator.js +4 -2
- package/dist/domains/security-compliance/coordinator.js +24 -22
- package/dist/domains/security-compliance/services/scanners/dast-scanner.d.ts +0 -21
- package/dist/domains/security-compliance/services/scanners/dast-scanner.js +4 -2
- package/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts +0 -4
- package/dist/domains/security-compliance/services/scanners/sast-scanner.js +3 -1
- package/dist/domains/security-compliance/services/security-auditor-dast.d.ts +0 -4
- package/dist/domains/security-compliance/services/security-auditor-dast.js +3 -1
- package/dist/domains/security-compliance/services/security-auditor-sast.d.ts +0 -3
- package/dist/domains/security-compliance/services/security-auditor-sast.js +3 -1
- package/dist/domains/security-compliance/services/security-auditor-secrets.d.ts +0 -3
- package/dist/domains/security-compliance/services/security-auditor-secrets.js +3 -1
- package/dist/domains/security-compliance/services/security-auditor.js +11 -9
- package/dist/domains/test-execution/coordinator.js +11 -9
- package/dist/domains/test-execution/services/auth-state-manager.d.ts +0 -3
- package/dist/domains/test-execution/services/auth-state-manager.js +4 -2
- package/dist/domains/test-execution/services/e2e/e2e-coordinator.d.ts +0 -14
- package/dist/domains/test-execution/services/e2e/e2e-coordinator.js +3 -1
- package/dist/domains/test-execution/services/flaky-detector.js +4 -2
- package/dist/domains/test-execution/services/retry-handler.js +3 -1
- package/dist/domains/test-execution/services/test-executor.js +3 -1
- package/dist/domains/test-generation/coordinator.d.ts +0 -17
- package/dist/domains/test-generation/coordinator.js +33 -31
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts +0 -5
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js +3 -1
- package/dist/domains/test-generation/services/code-transform-integration.d.ts +0 -7
- package/dist/domains/test-generation/services/code-transform-integration.js +3 -1
- package/dist/domains/test-generation/services/coherence-gate-service.d.ts +0 -3
- package/dist/domains/test-generation/services/coherence-gate-service.js +3 -1
- package/dist/domains/test-generation/services/test-generator.d.ts +0 -8
- package/dist/domains/test-generation/services/test-generator.js +5 -3
- package/dist/domains/visual-accessibility/coordinator.d.ts +0 -3
- package/dist/domains/visual-accessibility/coordinator.js +14 -12
- package/dist/domains/visual-accessibility/services/accessibility-tester-browser.d.ts +0 -3
- package/dist/domains/visual-accessibility/services/accessibility-tester-browser.js +52 -50
- package/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +0 -4
- package/dist/domains/visual-accessibility/services/accessibility-tester.js +8 -6
- package/dist/domains/visual-accessibility/services/axe-core-integration.d.ts +0 -3
- package/dist/domains/visual-accessibility/services/axe-core-integration.js +20 -18
- package/dist/domains/visual-accessibility/services/browser-security-scanner.d.ts +0 -4
- package/dist/domains/visual-accessibility/services/browser-security-scanner.js +6 -4
- package/dist/domains/visual-accessibility/services/browser-swarm-coordinator.d.ts +0 -30
- package/dist/domains/visual-accessibility/services/browser-swarm-coordinator.js +5 -3
- package/dist/domains/visual-accessibility/services/viewport-capture.d.ts +0 -27
- package/dist/domains/visual-accessibility/services/viewport-capture.js +6 -4
- package/dist/domains/visual-accessibility/services/visual-regression.d.ts +0 -26
- package/dist/domains/visual-accessibility/services/visual-regression.js +4 -2
- package/dist/domains/visual-accessibility/services/visual-tester.d.ts +0 -4
- package/dist/domains/visual-accessibility/services/visual-tester.js +4 -2
- package/dist/governance/deterministic-gateway-integration.js +1 -1
- package/dist/mcp/bundle.js +335 -335
- package/dist/mcp/security/validators/command-validator.d.ts +1 -40
- package/dist/mcp/security/validators/command-validator.js +2 -122
- package/dist/mcp/security/validators/crypto-validator.d.ts +1 -39
- package/dist/mcp/security/validators/crypto-validator.js +2 -71
- package/dist/mcp/security/validators/input-sanitizer.d.ts +1 -55
- package/dist/mcp/security/validators/input-sanitizer.js +2 -156
- package/dist/mcp/security/validators/interfaces.d.ts +1 -163
- package/dist/mcp/security/validators/interfaces.js +2 -5
- package/dist/mcp/security/validators/path-traversal-validator.d.ts +1 -49
- package/dist/mcp/security/validators/path-traversal-validator.js +2 -241
- package/dist/mcp/security/validators/regex-safety-validator.d.ts +1 -49
- package/dist/mcp/security/validators/regex-safety-validator.js +2 -182
- package/dist/mcp/security/validators/validation-orchestrator.d.ts +1 -65
- package/dist/mcp/security/validators/validation-orchestrator.js +2 -145
- package/dist/shared/io/file-reader.js +1 -1
- package/dist/shared/security/command-validator.d.ts +44 -0
- package/dist/shared/security/command-validator.js +126 -0
- package/dist/shared/security/crypto-validator.d.ts +43 -0
- package/dist/shared/security/crypto-validator.js +75 -0
- package/dist/shared/security/index.d.ts +7 -0
- package/dist/shared/security/index.js +15 -0
- package/dist/shared/security/input-sanitizer.d.ts +59 -0
- package/dist/shared/security/input-sanitizer.js +160 -0
- package/dist/shared/security/path-traversal-validator.d.ts +53 -0
- package/dist/shared/security/path-traversal-validator.js +245 -0
- package/dist/shared/security/regex-safety-validator.d.ts +53 -0
- package/dist/shared/security/regex-safety-validator.js +186 -0
- package/dist/shared/security/validation-orchestrator.d.ts +69 -0
- package/dist/shared/security/validation-orchestrator.js +149 -0
- package/dist/shared/security/validators-interfaces.d.ts +167 -0
- package/dist/shared/security/validators-interfaces.js +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - MCP Security: Input Sanitizer
|
|
3
|
+
* Implements the Strategy Pattern for input sanitization
|
|
4
|
+
*
|
|
5
|
+
* Moved from src/mcp/security/validators/input-sanitizer.ts to shared/security
|
|
6
|
+
* for cross-domain reuse without DDD boundary violations.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* HTML escape characters mapping
|
|
13
|
+
*/
|
|
14
|
+
export const HTML_ESCAPE_MAP = {
|
|
15
|
+
'&': '&',
|
|
16
|
+
'<': '<',
|
|
17
|
+
'>': '>',
|
|
18
|
+
'"': '"',
|
|
19
|
+
"'": ''',
|
|
20
|
+
'/': '/',
|
|
21
|
+
'`': '`',
|
|
22
|
+
'=': '=',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* SQL injection patterns to detect and remove
|
|
26
|
+
*/
|
|
27
|
+
export const SQL_INJECTION_PATTERNS = [
|
|
28
|
+
/('|")\s*;\s*--/i,
|
|
29
|
+
/'\s*OR\s+'1'\s*=\s*'1/i,
|
|
30
|
+
/"\s*OR\s+"1"\s*=\s*"1/i,
|
|
31
|
+
/UNION\s+SELECT/i,
|
|
32
|
+
/INSERT\s+INTO/i,
|
|
33
|
+
/DROP\s+TABLE/i,
|
|
34
|
+
/DELETE\s+FROM/i,
|
|
35
|
+
/UPDATE\s+.*\s+SET/i,
|
|
36
|
+
/EXEC(\s+|\()sp_/i,
|
|
37
|
+
/xp_cmdshell/i,
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Shell metacharacters (excludes parentheses which are common in normal text)
|
|
41
|
+
*/
|
|
42
|
+
export const SHELL_METACHARACTERS = /[|;&$`<>{}[\]!#*?~]/g;
|
|
43
|
+
/**
|
|
44
|
+
* Dangerous control characters that should be stripped:
|
|
45
|
+
* - Null byte (\x00): String termination attacks, filter bypass
|
|
46
|
+
* - Backspace (\x08): Log manipulation
|
|
47
|
+
* - Bell (\x07): Terminal escape attacks
|
|
48
|
+
* - Vertical tab (\x0B): Filter bypass
|
|
49
|
+
* - Form feed (\x0C): Filter bypass
|
|
50
|
+
* - Escape (\x1B): Terminal escape sequences (ANSI attacks)
|
|
51
|
+
* - Delete (\x7F): Buffer manipulation
|
|
52
|
+
*/
|
|
53
|
+
export const DANGEROUS_CONTROL_CHARS = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Input Sanitizer Implementation
|
|
56
|
+
// ============================================================================
|
|
57
|
+
/**
|
|
58
|
+
* Input Sanitizer Strategy
|
|
59
|
+
* Sanitizes user input to prevent XSS, SQL injection, and command injection
|
|
60
|
+
*/
|
|
61
|
+
export class InputSanitizer {
|
|
62
|
+
name = 'input-sanitization';
|
|
63
|
+
/**
|
|
64
|
+
* Get the primary risk level this sanitizer addresses
|
|
65
|
+
*/
|
|
66
|
+
getRiskLevel() {
|
|
67
|
+
return 'high';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Sanitize input string with configurable options
|
|
71
|
+
*/
|
|
72
|
+
sanitize(input, options = {}) {
|
|
73
|
+
const { maxLength = 10000, allowedChars, stripHtml = true, stripSql = true, escapeShell = true, trim = true, stripControlChars = true, } = options;
|
|
74
|
+
let result = input;
|
|
75
|
+
// Strip dangerous control characters first (null bytes, escape sequences, etc.)
|
|
76
|
+
// This must happen early to prevent bypass of later sanitization steps
|
|
77
|
+
if (stripControlChars) {
|
|
78
|
+
result = result.replace(DANGEROUS_CONTROL_CHARS, '');
|
|
79
|
+
}
|
|
80
|
+
// Trim
|
|
81
|
+
if (trim) {
|
|
82
|
+
result = result.trim();
|
|
83
|
+
}
|
|
84
|
+
// Max length
|
|
85
|
+
if (result.length > maxLength) {
|
|
86
|
+
result = result.substring(0, maxLength);
|
|
87
|
+
}
|
|
88
|
+
// Strip HTML
|
|
89
|
+
if (stripHtml) {
|
|
90
|
+
result = this.stripHtmlTags(result);
|
|
91
|
+
}
|
|
92
|
+
// Strip SQL injection attempts
|
|
93
|
+
if (stripSql) {
|
|
94
|
+
for (const pattern of SQL_INJECTION_PATTERNS) {
|
|
95
|
+
result = result.replace(pattern, '');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Escape shell metacharacters
|
|
99
|
+
if (escapeShell) {
|
|
100
|
+
result = result.replace(SHELL_METACHARACTERS, '');
|
|
101
|
+
}
|
|
102
|
+
// Filter to allowed characters
|
|
103
|
+
if (allowedChars) {
|
|
104
|
+
// Filter character by character to respect the provided regex
|
|
105
|
+
result = result.split('').filter(char => allowedChars.test(char)).join('');
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Escape HTML special characters
|
|
111
|
+
*/
|
|
112
|
+
escapeHtml(str) {
|
|
113
|
+
return str.replace(/[&<>"'`=/]/g, char => HTML_ESCAPE_MAP[char] || char);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Strip HTML tags from a string
|
|
117
|
+
* Handles both complete tags and incomplete/malformed tags to prevent XSS
|
|
118
|
+
*/
|
|
119
|
+
stripHtmlTags(str) {
|
|
120
|
+
// Limit input length to prevent ReDoS
|
|
121
|
+
const MAX_LENGTH = 100000;
|
|
122
|
+
if (str.length > MAX_LENGTH) {
|
|
123
|
+
str = str.slice(0, MAX_LENGTH);
|
|
124
|
+
}
|
|
125
|
+
let result = str;
|
|
126
|
+
let prevLength;
|
|
127
|
+
// Loop until no more changes (handles nested/malformed tags like <script<script>>)
|
|
128
|
+
do {
|
|
129
|
+
prevLength = result.length;
|
|
130
|
+
// Remove complete HTML tags using a non-backtracking approach
|
|
131
|
+
// Process character by character to avoid regex backtracking
|
|
132
|
+
let cleaned = '';
|
|
133
|
+
let inTag = false;
|
|
134
|
+
for (let i = 0; i < result.length; i++) {
|
|
135
|
+
const char = result[i];
|
|
136
|
+
if (char === '<') {
|
|
137
|
+
inTag = true;
|
|
138
|
+
}
|
|
139
|
+
else if (char === '>' && inTag) {
|
|
140
|
+
inTag = false;
|
|
141
|
+
}
|
|
142
|
+
else if (!inTag) {
|
|
143
|
+
cleaned += char;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
result = cleaned;
|
|
147
|
+
} while (result.length < prevLength && result.length > 0);
|
|
148
|
+
// Encode any remaining angle brackets
|
|
149
|
+
result = result.replace(/</g, '<').replace(/>/g, '>');
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Standalone Functions (for backward compatibility)
|
|
155
|
+
// ============================================================================
|
|
156
|
+
const defaultSanitizer = new InputSanitizer();
|
|
157
|
+
export const sanitizeInput = (input, options) => defaultSanitizer.sanitize(input, options);
|
|
158
|
+
export const escapeHtml = (str) => defaultSanitizer.escapeHtml(str);
|
|
159
|
+
export const stripHtmlTags = (str) => defaultSanitizer.stripHtmlTags(str);
|
|
160
|
+
//# sourceMappingURL=input-sanitizer.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - MCP Security: Path Traversal Validator
|
|
3
|
+
* Implements the Strategy Pattern for path traversal protection
|
|
4
|
+
*
|
|
5
|
+
* Moved from src/mcp/security/validators/path-traversal-validator.ts to shared/security
|
|
6
|
+
* for cross-domain reuse without DDD boundary violations.
|
|
7
|
+
*/
|
|
8
|
+
import { IPathValidationStrategy, PathValidationOptions, PathValidationResult, RiskLevel } from './validators-interfaces.js';
|
|
9
|
+
/**
|
|
10
|
+
* Path traversal patterns to detect
|
|
11
|
+
*/
|
|
12
|
+
export declare const PATH_TRAVERSAL_PATTERNS: RegExp[];
|
|
13
|
+
/**
|
|
14
|
+
* Dangerous path components (system directories)
|
|
15
|
+
*/
|
|
16
|
+
export declare const DANGEROUS_PATH_COMPONENTS: RegExp[];
|
|
17
|
+
/**
|
|
18
|
+
* Path Traversal Validator Strategy
|
|
19
|
+
* Validates file paths to prevent directory traversal attacks
|
|
20
|
+
*/
|
|
21
|
+
export declare class PathTraversalValidator implements IPathValidationStrategy {
|
|
22
|
+
readonly name = "path-traversal";
|
|
23
|
+
/**
|
|
24
|
+
* Get the primary risk level this validator addresses
|
|
25
|
+
*/
|
|
26
|
+
getRiskLevel(): RiskLevel;
|
|
27
|
+
/**
|
|
28
|
+
* Validate a file path against traversal attacks
|
|
29
|
+
*/
|
|
30
|
+
validate(path: string, options?: PathValidationOptions): PathValidationResult;
|
|
31
|
+
/**
|
|
32
|
+
* Normalize a path by resolving . and .. components
|
|
33
|
+
*/
|
|
34
|
+
normalizePath(path: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Safely join path components (strips leading/trailing slashes from all parts)
|
|
37
|
+
*/
|
|
38
|
+
joinPaths(...paths: string[]): string;
|
|
39
|
+
/**
|
|
40
|
+
* Join paths preserving absolute path from first component
|
|
41
|
+
*/
|
|
42
|
+
joinPathsAbsolute(...paths: string[]): string;
|
|
43
|
+
/**
|
|
44
|
+
* Get file extension from path
|
|
45
|
+
*/
|
|
46
|
+
getExtension(path: string): string | null;
|
|
47
|
+
}
|
|
48
|
+
export declare const validatePath: (path: string, options?: PathValidationOptions) => PathValidationResult;
|
|
49
|
+
export declare const normalizePath: (path: string) => string;
|
|
50
|
+
export declare const joinPaths: (...paths: string[]) => string;
|
|
51
|
+
export declare const joinPathsAbsolute: (...paths: string[]) => string;
|
|
52
|
+
export declare const getExtension: (path: string) => string | null;
|
|
53
|
+
//# sourceMappingURL=path-traversal-validator.d.ts.map
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - MCP Security: Path Traversal Validator
|
|
3
|
+
* Implements the Strategy Pattern for path traversal protection
|
|
4
|
+
*
|
|
5
|
+
* Moved from src/mcp/security/validators/path-traversal-validator.ts to shared/security
|
|
6
|
+
* for cross-domain reuse without DDD boundary violations.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Path traversal patterns to detect
|
|
13
|
+
*/
|
|
14
|
+
export const PATH_TRAVERSAL_PATTERNS = [
|
|
15
|
+
/\.\./, // Basic traversal
|
|
16
|
+
/%2e%2e/i, // URL encoded ..
|
|
17
|
+
/%252e%252e/i, // Double URL encoded
|
|
18
|
+
/\.\.%2f/i, // Mixed encoding
|
|
19
|
+
/%2f\.\./i, // Forward slash + ..
|
|
20
|
+
/\.\.%5c/i, // Backslash + ..
|
|
21
|
+
/\.\.\\/, // Windows backslash traversal
|
|
22
|
+
/%c0%ae/i, // UTF-8 overlong encoding
|
|
23
|
+
/%c0%2f/i, // UTF-8 overlong /
|
|
24
|
+
/%c1%9c/i, // UTF-8 overlong \
|
|
25
|
+
/\0/, // Null byte injection
|
|
26
|
+
/%00/i, // URL encoded null
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Dangerous path components (system directories)
|
|
30
|
+
*/
|
|
31
|
+
export const DANGEROUS_PATH_COMPONENTS = [
|
|
32
|
+
/^\/etc\//i,
|
|
33
|
+
/^\/proc\//i,
|
|
34
|
+
/^\/sys\//i,
|
|
35
|
+
/^\/dev\//i,
|
|
36
|
+
/^\/root\//i,
|
|
37
|
+
/^\/home\/.+\/\./i,
|
|
38
|
+
/^[A-Z]:\\Windows/i,
|
|
39
|
+
/^[A-Z]:\\System/i,
|
|
40
|
+
/^[A-Z]:\\Users\\.+\\AppData/i,
|
|
41
|
+
];
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Path Traversal Validator Implementation
|
|
44
|
+
// ============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Path Traversal Validator Strategy
|
|
47
|
+
* Validates file paths to prevent directory traversal attacks
|
|
48
|
+
*/
|
|
49
|
+
export class PathTraversalValidator {
|
|
50
|
+
name = 'path-traversal';
|
|
51
|
+
/**
|
|
52
|
+
* Get the primary risk level this validator addresses
|
|
53
|
+
*/
|
|
54
|
+
getRiskLevel() {
|
|
55
|
+
return 'critical';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validate a file path against traversal attacks
|
|
59
|
+
*/
|
|
60
|
+
validate(path, options = {}) {
|
|
61
|
+
const { basePath = '', allowAbsolute = false, allowedExtensions = [], deniedExtensions = ['.exe', '.bat', '.cmd', '.sh', '.ps1', '.dll', '.so'], maxDepth = 10, maxLength = 4096, } = options;
|
|
62
|
+
// Check length
|
|
63
|
+
if (path.length > maxLength) {
|
|
64
|
+
return {
|
|
65
|
+
valid: false,
|
|
66
|
+
error: `Path exceeds maximum length of ${maxLength}`,
|
|
67
|
+
riskLevel: 'medium',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Check for traversal patterns
|
|
71
|
+
for (const pattern of PATH_TRAVERSAL_PATTERNS) {
|
|
72
|
+
if (pattern.test(path)) {
|
|
73
|
+
return {
|
|
74
|
+
valid: false,
|
|
75
|
+
error: 'Path traversal attempt detected',
|
|
76
|
+
riskLevel: 'critical',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Check for absolute paths
|
|
81
|
+
if (!allowAbsolute && (path.startsWith('/') || /^[A-Z]:/i.test(path))) {
|
|
82
|
+
return {
|
|
83
|
+
valid: false,
|
|
84
|
+
error: 'Absolute paths are not allowed',
|
|
85
|
+
riskLevel: 'high',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Check for dangerous path components
|
|
89
|
+
for (const pattern of DANGEROUS_PATH_COMPONENTS) {
|
|
90
|
+
if (pattern.test(path)) {
|
|
91
|
+
return {
|
|
92
|
+
valid: false,
|
|
93
|
+
error: 'Access to system paths is not allowed',
|
|
94
|
+
riskLevel: 'critical',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Normalize the path
|
|
99
|
+
const normalizedPath = this.normalizePath(path);
|
|
100
|
+
// Re-check for traversal after normalization
|
|
101
|
+
if (normalizedPath.includes('..')) {
|
|
102
|
+
return {
|
|
103
|
+
valid: false,
|
|
104
|
+
error: 'Path traversal detected after normalization',
|
|
105
|
+
riskLevel: 'critical',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Check depth
|
|
109
|
+
const depth = normalizedPath.split('/').filter(Boolean).length;
|
|
110
|
+
if (depth > maxDepth) {
|
|
111
|
+
return {
|
|
112
|
+
valid: false,
|
|
113
|
+
error: `Path depth exceeds maximum of ${maxDepth}`,
|
|
114
|
+
riskLevel: 'low',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Check extension
|
|
118
|
+
const ext = this.getExtension(normalizedPath);
|
|
119
|
+
if (ext) {
|
|
120
|
+
const extWithDot = `.${ext.toLowerCase()}`;
|
|
121
|
+
const extWithoutDot = ext.toLowerCase();
|
|
122
|
+
// Check denied extensions (support both .exe and exe formats)
|
|
123
|
+
if (deniedExtensions.length > 0) {
|
|
124
|
+
const isDenied = deniedExtensions.some(denied => denied.toLowerCase() === extWithDot || denied.toLowerCase() === extWithoutDot);
|
|
125
|
+
if (isDenied) {
|
|
126
|
+
return {
|
|
127
|
+
valid: false,
|
|
128
|
+
error: `File extension '${ext}' is not allowed`,
|
|
129
|
+
riskLevel: 'high',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Check allowed extensions (support both .ts and ts formats)
|
|
134
|
+
if (allowedExtensions.length > 0) {
|
|
135
|
+
const isAllowed = allowedExtensions.some(allowed => allowed.toLowerCase() === extWithDot || allowed.toLowerCase() === extWithoutDot);
|
|
136
|
+
if (!isAllowed) {
|
|
137
|
+
return {
|
|
138
|
+
valid: false,
|
|
139
|
+
error: `File extension '${ext}' is not in allowed list`,
|
|
140
|
+
riskLevel: 'medium',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Combine with base path if provided
|
|
146
|
+
const finalPath = basePath
|
|
147
|
+
? this.joinPathsAbsolute(basePath, normalizedPath)
|
|
148
|
+
: normalizedPath;
|
|
149
|
+
// Verify final path doesn't escape base (use normalized base for comparison)
|
|
150
|
+
const normalizedBase = basePath.startsWith('/')
|
|
151
|
+
? `/${this.normalizePath(basePath)}`
|
|
152
|
+
: this.normalizePath(basePath);
|
|
153
|
+
if (basePath && !finalPath.startsWith(normalizedBase)) {
|
|
154
|
+
return {
|
|
155
|
+
valid: false,
|
|
156
|
+
error: 'Path escapes base directory',
|
|
157
|
+
riskLevel: 'critical',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
valid: true,
|
|
162
|
+
normalizedPath: finalPath,
|
|
163
|
+
riskLevel: 'none',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Normalize a path by resolving . and .. components
|
|
168
|
+
*/
|
|
169
|
+
normalizePath(path) {
|
|
170
|
+
// Replace backslashes with forward slashes
|
|
171
|
+
let normalized = path.replace(/\\/g, '/');
|
|
172
|
+
// Remove multiple consecutive slashes
|
|
173
|
+
normalized = normalized.replace(/\/+/g, '/');
|
|
174
|
+
// Split and resolve
|
|
175
|
+
const parts = normalized.split('/');
|
|
176
|
+
const result = [];
|
|
177
|
+
for (const part of parts) {
|
|
178
|
+
if (part === '.' || part === '') {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (part === '..') {
|
|
182
|
+
// Don't allow going above root
|
|
183
|
+
if (result.length > 0 && result[result.length - 1] !== '..') {
|
|
184
|
+
result.pop();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
result.push(part);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result.join('/');
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Safely join path components (strips leading/trailing slashes from all parts)
|
|
195
|
+
*/
|
|
196
|
+
joinPaths(...paths) {
|
|
197
|
+
if (paths.length === 0)
|
|
198
|
+
return '';
|
|
199
|
+
return paths
|
|
200
|
+
.map(p => p.replace(/^\/+|\/+$/g, ''))
|
|
201
|
+
.filter(Boolean)
|
|
202
|
+
.join('/');
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Join paths preserving absolute path from first component
|
|
206
|
+
*/
|
|
207
|
+
joinPathsAbsolute(...paths) {
|
|
208
|
+
if (paths.length === 0)
|
|
209
|
+
return '';
|
|
210
|
+
// Check if the first path is absolute
|
|
211
|
+
const isAbsolute = paths[0].startsWith('/');
|
|
212
|
+
const result = paths
|
|
213
|
+
// Use non-backtracking patterns with possessive-like behavior via split/join
|
|
214
|
+
.map(p => {
|
|
215
|
+
// Remove leading slashes by splitting and rejoining
|
|
216
|
+
while (p.startsWith('/'))
|
|
217
|
+
p = p.slice(1);
|
|
218
|
+
// Remove trailing slashes
|
|
219
|
+
while (p.endsWith('/'))
|
|
220
|
+
p = p.slice(0, -1);
|
|
221
|
+
return p;
|
|
222
|
+
})
|
|
223
|
+
.filter(Boolean)
|
|
224
|
+
.join('/');
|
|
225
|
+
// Preserve leading slash for absolute paths
|
|
226
|
+
return isAbsolute ? `/${result}` : result;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get file extension from path
|
|
230
|
+
*/
|
|
231
|
+
getExtension(path) {
|
|
232
|
+
const match = path.match(/\.([^./\\]+)$/);
|
|
233
|
+
return match ? match[1] : null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Standalone Functions (for backward compatibility)
|
|
238
|
+
// ============================================================================
|
|
239
|
+
const defaultValidator = new PathTraversalValidator();
|
|
240
|
+
export const validatePath = (path, options) => defaultValidator.validate(path, options);
|
|
241
|
+
export const normalizePath = (path) => defaultValidator.normalizePath(path);
|
|
242
|
+
export const joinPaths = (...paths) => defaultValidator.joinPaths(...paths);
|
|
243
|
+
export const joinPathsAbsolute = (...paths) => defaultValidator.joinPathsAbsolute(...paths);
|
|
244
|
+
export const getExtension = (path) => defaultValidator.getExtension(path);
|
|
245
|
+
//# sourceMappingURL=path-traversal-validator.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - MCP Security: Regex Safety Validator
|
|
3
|
+
* Implements the Strategy Pattern for ReDoS prevention
|
|
4
|
+
*
|
|
5
|
+
* Moved from src/mcp/security/validators/regex-safety-validator.ts to shared/security
|
|
6
|
+
* for cross-domain reuse without DDD boundary violations.
|
|
7
|
+
*/
|
|
8
|
+
import { IRegexValidationStrategy, RegexSafetyResult, RegexValidationOptions, RiskLevel, ValidationResult } from './validators-interfaces.js';
|
|
9
|
+
/**
|
|
10
|
+
* Patterns that can cause ReDoS (Regular Expression Denial of Service)
|
|
11
|
+
*/
|
|
12
|
+
export declare const REDOS_PATTERNS: RegExp[];
|
|
13
|
+
/**
|
|
14
|
+
* Count nested quantifier depth in a regex pattern
|
|
15
|
+
*/
|
|
16
|
+
export declare function countQuantifierNesting(pattern: string): number;
|
|
17
|
+
/**
|
|
18
|
+
* Check for exponential backtracking potential
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasExponentialBacktracking(pattern: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Regex Safety Validator Strategy
|
|
23
|
+
* Validates regex patterns to prevent ReDoS attacks
|
|
24
|
+
*/
|
|
25
|
+
export declare class RegexSafetyValidator implements IRegexValidationStrategy {
|
|
26
|
+
readonly name = "regex-safety";
|
|
27
|
+
private maxComplexity;
|
|
28
|
+
constructor(maxComplexity?: number);
|
|
29
|
+
/**
|
|
30
|
+
* Get the primary risk level this validator addresses
|
|
31
|
+
*/
|
|
32
|
+
getRiskLevel(): RiskLevel;
|
|
33
|
+
/**
|
|
34
|
+
* Validate a regex pattern (IValidationStrategy interface)
|
|
35
|
+
*/
|
|
36
|
+
validate(pattern: string, options?: RegexValidationOptions): ValidationResult;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a regex pattern is safe from ReDoS
|
|
39
|
+
*/
|
|
40
|
+
isRegexSafe(pattern: string, maxComplexity?: number): RegexSafetyResult;
|
|
41
|
+
/**
|
|
42
|
+
* Escape special regex characters in a string
|
|
43
|
+
*/
|
|
44
|
+
escapeRegex(str: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Create a safe regex with validation
|
|
47
|
+
*/
|
|
48
|
+
createSafeRegex(pattern: string, flags?: string, maxLength?: number): RegExp | null;
|
|
49
|
+
}
|
|
50
|
+
export declare const isRegexSafe: (pattern: string) => RegexSafetyResult;
|
|
51
|
+
export declare const escapeRegex: (str: string) => string;
|
|
52
|
+
export declare const createSafeRegex: (pattern: string, flags?: string, maxLength?: number) => RegExp | null;
|
|
53
|
+
//# sourceMappingURL=regex-safety-validator.d.ts.map
|