@defai.digital/ax-cli 3.5.4 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/.ax-cli/memory.json +8 -8
  2. package/README.md +7 -0
  3. package/config-defaults/messages.yaml +75 -0
  4. package/config-defaults/models.yaml +66 -0
  5. package/config-defaults/prompts.yaml +156 -0
  6. package/config-defaults/settings.yaml +86 -0
  7. package/dist/agent/chat-history-manager.d.ts +56 -0
  8. package/dist/agent/chat-history-manager.js +150 -0
  9. package/dist/agent/chat-history-manager.js.map +1 -0
  10. package/dist/agent/llm-agent.js +1 -1
  11. package/dist/agent/llm-agent.js.map +1 -1
  12. package/dist/agent/tool-manager.d.ts +39 -0
  13. package/dist/agent/tool-manager.js +76 -0
  14. package/dist/agent/tool-manager.js.map +1 -0
  15. package/dist/commands/memory.js +1 -1
  16. package/dist/commands/memory.js.map +1 -1
  17. package/dist/commands/setup.js +19 -6
  18. package/dist/commands/setup.js.map +1 -1
  19. package/dist/index.js +7 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/llm/client.d.ts +1 -0
  22. package/dist/llm/client.js +44 -0
  23. package/dist/llm/client.js.map +1 -1
  24. package/dist/mcp/health.js +4 -2
  25. package/dist/mcp/health.js.map +1 -1
  26. package/dist/mcp/ssrf-protection.d.ts +86 -0
  27. package/dist/mcp/ssrf-protection.js +313 -0
  28. package/dist/mcp/ssrf-protection.js.map +1 -0
  29. package/dist/mcp/validation.d.ts +4 -0
  30. package/dist/mcp/validation.js +122 -11
  31. package/dist/mcp/validation.js.map +1 -1
  32. package/dist/schemas/settings-schemas.d.ts +30 -0
  33. package/dist/schemas/settings-schemas.js +30 -0
  34. package/dist/schemas/settings-schemas.js.map +1 -1
  35. package/dist/tools/bash.d.ts +3 -2
  36. package/dist/tools/bash.js +31 -2
  37. package/dist/tools/bash.js.map +1 -1
  38. package/dist/tools/search.d.ts +1 -1
  39. package/dist/tools/search.js +121 -128
  40. package/dist/tools/search.js.map +1 -1
  41. package/dist/tools/text-editor.js +52 -15
  42. package/dist/tools/text-editor.js.map +1 -1
  43. package/dist/ui/components/chat-history.js +1 -1
  44. package/dist/ui/components/chat-history.js.map +1 -1
  45. package/dist/ui/components/chat-interface.js +3 -2
  46. package/dist/ui/components/chat-interface.js.map +1 -1
  47. package/dist/ui/components/confirmation-dialog.js +1 -1
  48. package/dist/ui/components/confirmation-dialog.js.map +1 -1
  49. package/dist/ui/components/status-bar.js +2 -2
  50. package/dist/ui/components/status-bar.js.map +1 -1
  51. package/dist/{hooks → ui/hooks}/use-chat-reducer.d.ts +1 -1
  52. package/dist/ui/hooks/use-chat-reducer.js.map +1 -0
  53. package/dist/{hooks → ui/hooks}/use-enhanced-input.js +8 -3
  54. package/dist/ui/hooks/use-enhanced-input.js.map +1 -0
  55. package/dist/{hooks → ui/hooks}/use-input-handler.d.ts +1 -1
  56. package/dist/{hooks → ui/hooks}/use-input-handler.js +28 -24
  57. package/dist/ui/hooks/use-input-handler.js.map +1 -0
  58. package/dist/utils/audit-logger.d.ts +247 -0
  59. package/dist/utils/audit-logger.js +374 -0
  60. package/dist/utils/audit-logger.js.map +1 -0
  61. package/dist/utils/command-security.d.ts +85 -0
  62. package/dist/utils/command-security.js +200 -0
  63. package/dist/utils/command-security.js.map +1 -0
  64. package/dist/utils/config-loader.js +3 -3
  65. package/dist/utils/config-loader.js.map +1 -1
  66. package/dist/utils/encryption.d.ts +78 -0
  67. package/dist/utils/encryption.js +216 -0
  68. package/dist/utils/encryption.js.map +1 -0
  69. package/dist/utils/error-sanitizer.d.ts +119 -0
  70. package/dist/utils/error-sanitizer.js +253 -0
  71. package/dist/utils/error-sanitizer.js.map +1 -0
  72. package/dist/utils/input-sanitizer.d.ts +210 -0
  73. package/dist/utils/input-sanitizer.js +362 -0
  74. package/dist/utils/input-sanitizer.js.map +1 -0
  75. package/dist/utils/json-utils.d.ts +13 -0
  76. package/dist/utils/json-utils.js +55 -1
  77. package/dist/utils/json-utils.js.map +1 -1
  78. package/dist/utils/path-security.d.ts +90 -0
  79. package/dist/utils/path-security.js +328 -0
  80. package/dist/utils/path-security.js.map +1 -0
  81. package/dist/utils/process-pool.d.ts +105 -0
  82. package/dist/utils/process-pool.js +326 -0
  83. package/dist/utils/process-pool.js.map +1 -0
  84. package/dist/utils/rate-limiter.d.ts +207 -0
  85. package/dist/utils/rate-limiter.js +303 -0
  86. package/dist/utils/rate-limiter.js.map +1 -0
  87. package/dist/utils/settings-manager.js +99 -6
  88. package/dist/utils/settings-manager.js.map +1 -1
  89. package/dist/utils/streaming-analyzer.js +9 -21
  90. package/dist/utils/streaming-analyzer.js.map +1 -1
  91. package/package.json +1 -1
  92. package/dist/hooks/use-chat-reducer.js.map +0 -1
  93. package/dist/hooks/use-enhanced-input.js.map +0 -1
  94. package/dist/hooks/use-input-handler.js.map +0 -1
  95. package/dist/hooks/use-input-history.d.ts +0 -9
  96. package/dist/hooks/use-input-history.js +0 -112
  97. package/dist/hooks/use-input-history.js.map +0 -1
  98. /package/dist/{hooks → ui/hooks}/use-chat-reducer.js +0 -0
  99. /package/dist/{hooks → ui/hooks}/use-enhanced-input.d.ts +0 -0
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Input Sanitization Framework (REQ-SEC-007)
3
+ *
4
+ * Provides comprehensive input validation and sanitization to prevent:
5
+ * - ReDoS (Regular Expression Denial of Service)
6
+ * - Command injection
7
+ * - Path traversal
8
+ * - Unicode attacks
9
+ * - Buffer overflow
10
+ *
11
+ * Security: CVSS 7.3 (High Priority)
12
+ */
13
+ /**
14
+ * Default maximum input lengths for different contexts
15
+ */
16
+ export const MAX_INPUT_LENGTHS = {
17
+ COMMAND: 10_000, // Shell commands
18
+ FILE_PATH: 4_096, // File system paths
19
+ USER_INPUT: 50_000, // General user input (prompts, etc.)
20
+ SEARCH_QUERY: 1_000, // Search queries
21
+ ENV_VALUE: 10_000, // Environment variable values
22
+ CONFIG_VALUE: 10_000, // Configuration values
23
+ };
24
+ /**
25
+ * Dangerous patterns that indicate potential attacks
26
+ * These patterns are designed to be fast and avoid ReDoS
27
+ */
28
+ const DANGEROUS_PATTERNS = {
29
+ // Null bytes (path traversal, command injection)
30
+ NULL_BYTE: /\0/,
31
+ // Excessive repetition (ReDoS indicator)
32
+ // Using fixed quantifier to prevent ReDoS
33
+ EXCESSIVE_REPETITION: /(.)\1{100,}/,
34
+ // Control characters (except common ones like \n, \t)
35
+ CONTROL_CHARS: /[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/,
36
+ // Unicode direction override (used in homograph attacks)
37
+ UNICODE_OVERRIDE: /[\u202A-\u202E\u2066-\u2069]/,
38
+ };
39
+ /**
40
+ * Safe characters for different contexts
41
+ */
42
+ export const SAFE_PATTERNS = {
43
+ /**
44
+ * Alphanumeric, spaces, and common punctuation
45
+ */
46
+ BASIC: /^[a-zA-Z0-9\s.,!?'"()\-_]+$/,
47
+ /**
48
+ * Safe for file paths (no directory traversal)
49
+ */
50
+ FILE_PATH: /^[a-zA-Z0-9/._\-]+$/,
51
+ /**
52
+ * Safe for environment variable values
53
+ */
54
+ ENV_VALUE: /^[a-zA-Z0-9._\-:/=]+$/,
55
+ /**
56
+ * Printable ASCII only (most restrictive)
57
+ */
58
+ ASCII_PRINTABLE: /^[\x20-\x7E]+$/,
59
+ };
60
+ /**
61
+ * Normalize Unicode string to prevent homograph attacks
62
+ *
63
+ * Uses NFC (Canonical Decomposition, followed by Canonical Composition)
64
+ * which is the recommended normalization form for most use cases
65
+ *
66
+ * @param input - String to normalize
67
+ * @returns Normalized string
68
+ */
69
+ export function normalizeUnicode(input) {
70
+ return input.normalize('NFC');
71
+ }
72
+ /**
73
+ * Check for dangerous patterns in input
74
+ *
75
+ * @param input - String to check
76
+ * @returns Array of detected dangerous patterns
77
+ */
78
+ export function detectDangerousPatterns(input) {
79
+ const detected = [];
80
+ if (DANGEROUS_PATTERNS.NULL_BYTE.test(input)) {
81
+ detected.push('Null byte detected');
82
+ }
83
+ if (DANGEROUS_PATTERNS.EXCESSIVE_REPETITION.test(input)) {
84
+ detected.push('Excessive character repetition detected');
85
+ }
86
+ if (DANGEROUS_PATTERNS.CONTROL_CHARS.test(input)) {
87
+ detected.push('Control characters detected');
88
+ }
89
+ if (DANGEROUS_PATTERNS.UNICODE_OVERRIDE.test(input)) {
90
+ detected.push('Unicode direction override detected');
91
+ }
92
+ return detected;
93
+ }
94
+ /**
95
+ * Sanitize general user input with configurable options
96
+ *
97
+ * @param input - Raw input string
98
+ * @param options - Sanitization options
99
+ * @returns Sanitization result
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const result = sanitizeInput('User input here', {
104
+ * maxLength: 1000,
105
+ * normalizeUnicode: true,
106
+ * allowedPattern: SAFE_PATTERNS.BASIC,
107
+ * });
108
+ *
109
+ * if (result.valid) {
110
+ * // Use result.value safely
111
+ * } else {
112
+ * console.error(result.error);
113
+ * }
114
+ * ```
115
+ */
116
+ export function sanitizeInput(input, options = {}) {
117
+ const { maxLength = MAX_INPUT_LENGTHS.USER_INPUT, normalizeUnicode: shouldNormalize = true, allowedPattern, trim = true, allowEmpty = false, } = options;
118
+ const warnings = [];
119
+ let value = input;
120
+ // 1. Trim if requested
121
+ if (trim) {
122
+ value = value.trim();
123
+ }
124
+ // 2. Check if empty
125
+ if (!allowEmpty && value.length === 0) {
126
+ return {
127
+ valid: false,
128
+ error: 'Input cannot be empty',
129
+ };
130
+ }
131
+ // 3. Check length BEFORE normalization (prevent DoS via normalization)
132
+ if (value.length > maxLength) {
133
+ return {
134
+ valid: false,
135
+ error: `Input exceeds maximum length of ${maxLength} characters (got ${value.length})`,
136
+ };
137
+ }
138
+ // 4. Unicode normalization (prevent homograph attacks)
139
+ if (shouldNormalize) {
140
+ const normalized = normalizeUnicode(value);
141
+ if (normalized !== value) {
142
+ warnings.push('Input was normalized (Unicode)');
143
+ value = normalized;
144
+ }
145
+ }
146
+ // 5. Check for dangerous patterns
147
+ const dangerous = detectDangerousPatterns(value);
148
+ if (dangerous.length > 0) {
149
+ return {
150
+ valid: false,
151
+ error: `Dangerous patterns detected: ${dangerous.join(', ')}`,
152
+ };
153
+ }
154
+ // 6. Apply character whitelist if provided
155
+ if (allowedPattern && !allowedPattern.test(value)) {
156
+ return {
157
+ valid: false,
158
+ error: 'Input contains disallowed characters',
159
+ };
160
+ }
161
+ return {
162
+ valid: true,
163
+ value,
164
+ warnings: warnings.length > 0 ? warnings : undefined,
165
+ };
166
+ }
167
+ /**
168
+ * Sanitize file path input to prevent path traversal
169
+ *
170
+ * @param path - File path to sanitize
171
+ * @returns Sanitization result
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * const result = sanitizeFilePath('../../../etc/passwd');
176
+ * if (!result.valid) {
177
+ * console.error('Invalid path:', result.error);
178
+ * }
179
+ * ```
180
+ */
181
+ export function sanitizeFilePath(path) {
182
+ const result = sanitizeInput(path, {
183
+ maxLength: MAX_INPUT_LENGTHS.FILE_PATH,
184
+ trim: true,
185
+ allowEmpty: false,
186
+ });
187
+ if (!result.valid) {
188
+ return result;
189
+ }
190
+ const value = result.value;
191
+ // Additional path-specific checks
192
+ const warnings = result.warnings || [];
193
+ // Check for path traversal patterns
194
+ if (value.includes('..')) {
195
+ warnings.push('Path contains parent directory references (..)');
196
+ }
197
+ // Check for absolute paths (may be intentional, so just warn)
198
+ if (value.startsWith('/') || /^[A-Z]:/i.test(value)) {
199
+ warnings.push('Absolute path detected');
200
+ }
201
+ // Check for hidden files (Unix)
202
+ if (value.split('/').some(part => part.startsWith('.'))) {
203
+ warnings.push('Path contains hidden file/directory');
204
+ }
205
+ return {
206
+ valid: true,
207
+ value,
208
+ warnings: warnings.length > 0 ? warnings : undefined,
209
+ };
210
+ }
211
+ /**
212
+ * Sanitize shell command input
213
+ *
214
+ * NOTE: This is a last line of defense. Prefer execFile over exec
215
+ * and use argument arrays instead of concatenating commands.
216
+ *
217
+ * @param command - Command string to sanitize
218
+ * @returns Sanitization result
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const result = sanitizeCommand('ls -la');
223
+ * if (result.valid) {
224
+ * // Still prefer execFile with args array
225
+ * execFile(result.value.split(' ')[0], result.value.split(' ').slice(1));
226
+ * }
227
+ * ```
228
+ */
229
+ export function sanitizeCommand(command) {
230
+ const result = sanitizeInput(command, {
231
+ maxLength: MAX_INPUT_LENGTHS.COMMAND,
232
+ trim: true,
233
+ allowEmpty: false,
234
+ });
235
+ if (!result.valid) {
236
+ return result;
237
+ }
238
+ const value = result.value;
239
+ // Check for shell metacharacters that could enable injection
240
+ const shellMetaChars = /[;&|`$()<>\\]/;
241
+ if (shellMetaChars.test(value)) {
242
+ return {
243
+ valid: false,
244
+ error: 'Command contains dangerous shell metacharacters',
245
+ };
246
+ }
247
+ return {
248
+ valid: true,
249
+ value,
250
+ warnings: result.warnings,
251
+ };
252
+ }
253
+ /**
254
+ * Sanitize search query input
255
+ *
256
+ * @param query - Search query to sanitize
257
+ * @returns Sanitization result
258
+ */
259
+ export function sanitizeSearchQuery(query) {
260
+ return sanitizeInput(query, {
261
+ maxLength: MAX_INPUT_LENGTHS.SEARCH_QUERY,
262
+ trim: true,
263
+ allowEmpty: false,
264
+ });
265
+ }
266
+ /**
267
+ * Sanitize environment variable value
268
+ *
269
+ * @param value - Environment variable value to sanitize
270
+ * @returns Sanitization result
271
+ */
272
+ export function sanitizeEnvValue(value) {
273
+ return sanitizeInput(value, {
274
+ maxLength: MAX_INPUT_LENGTHS.ENV_VALUE,
275
+ trim: true,
276
+ allowEmpty: true, // Empty env vars are valid
277
+ });
278
+ }
279
+ /**
280
+ * Escape shell arguments for safe execution
281
+ *
282
+ * NOTE: This is a defense-in-depth measure. Always prefer:
283
+ * 1. execFile with argument array over exec
284
+ * 2. Argument validation/whitelisting
285
+ * 3. This escaping function as a last resort
286
+ *
287
+ * @param arg - Argument to escape
288
+ * @returns Safely escaped argument
289
+ */
290
+ export function escapeShellArg(arg) {
291
+ // On Windows, use double quotes
292
+ if (process.platform === 'win32') {
293
+ // Escape double quotes and backslashes
294
+ return `"${arg.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
295
+ }
296
+ // On Unix, use single quotes (safest - no interpolation)
297
+ // To include a single quote, end the quote, add escaped quote, resume quote
298
+ return `'${arg.replace(/'/g, "'\\''")}'`;
299
+ }
300
+ /**
301
+ * Validate regex pattern for ReDoS protection
302
+ *
303
+ * Checks for common ReDoS patterns:
304
+ * - Nested quantifiers (e.g., (a+)+)
305
+ * - Alternation with overlapping patterns
306
+ * - Excessive backtracking potential
307
+ *
308
+ * @param pattern - Regex pattern to validate
309
+ * @returns Validation result
310
+ *
311
+ * @example
312
+ * ```typescript
313
+ * const result = validateRegexPattern('(a+)+b');
314
+ * if (!result.valid) {
315
+ * console.error('Unsafe regex:', result.error);
316
+ * }
317
+ * ```
318
+ */
319
+ export function validateRegexPattern(pattern) {
320
+ // Check length first
321
+ if (pattern.length > 1000) {
322
+ return {
323
+ valid: false,
324
+ error: 'Regex pattern too long (max 1000 characters)',
325
+ };
326
+ }
327
+ const warnings = [];
328
+ // Check for nested quantifiers (major ReDoS risk)
329
+ // Pattern: quantifier inside a group that is itself quantified
330
+ const nestedQuantifiers = /\([^)]*[*+?{][^)]*\)[*+?{]/;
331
+ if (nestedQuantifiers.test(pattern)) {
332
+ return {
333
+ valid: false,
334
+ error: 'Regex contains nested quantifiers (ReDoS risk)',
335
+ };
336
+ }
337
+ // Check for excessive alternation
338
+ const alternations = pattern.split('|');
339
+ if (alternations.length > 20) {
340
+ warnings.push('Regex has many alternations (may be slow)');
341
+ }
342
+ // Check for backreferences (can cause exponential backtracking)
343
+ if (/\\[1-9]/.test(pattern)) {
344
+ warnings.push('Regex contains backreferences (may be slow)');
345
+ }
346
+ // Try to compile the regex to catch syntax errors
347
+ try {
348
+ new RegExp(pattern);
349
+ }
350
+ catch (error) {
351
+ return {
352
+ valid: false,
353
+ error: `Invalid regex: ${error instanceof Error ? error.message : 'Unknown error'}`,
354
+ };
355
+ }
356
+ return {
357
+ valid: true,
358
+ value: pattern,
359
+ warnings: warnings.length > 0 ? warnings : undefined,
360
+ };
361
+ }
362
+ //# sourceMappingURL=input-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-sanitizer.js","sourceRoot":"","sources":["../../src/utils/input-sanitizer.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,11 @@
1
1
  /**
2
2
  * JSON Parsing Utilities
3
3
  * Centralized JSON operations with validation and error handling
4
+ *
5
+ * Security: REQ-SEC-005 - Prototype Pollution Prevention
6
+ * - Sanitizes dangerous keys (__proto__, constructor, prototype)
7
+ * - Validates JSON structure before use
8
+ * - Prevents object property injection attacks
4
9
  */
5
10
  import { z } from 'zod';
6
11
  /**
@@ -57,3 +62,11 @@ export declare function parseJsonWithFallback<T>(jsonString: string, fallback: T
57
62
  * Parse JSON file with fallback value on error
58
63
  */
59
64
  export declare function parseJsonFileWithFallback<T>(filePath: string, fallback: T, schema?: z.ZodSchema<T>): T;
65
+ /**
66
+ * Sanitize an object to prevent prototype pollution
67
+ * Exported for testing purposes
68
+ *
69
+ * @param obj - Object to sanitize
70
+ * @returns Sanitized object
71
+ */
72
+ export declare function sanitizeJson<T>(obj: T): T;
@@ -1,15 +1,59 @@
1
1
  /**
2
2
  * JSON Parsing Utilities
3
3
  * Centralized JSON operations with validation and error handling
4
+ *
5
+ * Security: REQ-SEC-005 - Prototype Pollution Prevention
6
+ * - Sanitizes dangerous keys (__proto__, constructor, prototype)
7
+ * - Validates JSON structure before use
8
+ * - Prevents object property injection attacks
4
9
  */
5
10
  import { readFileSync, writeFileSync, renameSync, unlinkSync, existsSync, copyFileSync, mkdirSync } from 'fs';
6
11
  import { dirname } from 'path';
12
+ /**
13
+ * Dangerous keys that can cause prototype pollution
14
+ * These keys should never be allowed in parsed JSON
15
+ */
16
+ const DANGEROUS_KEYS = ['__proto__', 'constructor', 'prototype'];
17
+ /**
18
+ * Sanitize parsed JSON by removing dangerous keys
19
+ * Prevents prototype pollution attacks (REQ-SEC-005)
20
+ *
21
+ * @param obj - Object to sanitize (recursively)
22
+ * @returns Sanitized object with dangerous keys removed
23
+ */
24
+ function sanitizeObject(obj) {
25
+ if (obj === null || typeof obj !== 'object') {
26
+ return obj;
27
+ }
28
+ // Handle arrays
29
+ if (Array.isArray(obj)) {
30
+ return obj.map(item => sanitizeObject(item));
31
+ }
32
+ // Handle objects
33
+ const sanitized = {};
34
+ for (const key in obj) {
35
+ // Skip dangerous keys
36
+ if (DANGEROUS_KEYS.includes(key)) {
37
+ continue;
38
+ }
39
+ // Skip inherited properties
40
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) {
41
+ continue;
42
+ }
43
+ // Recursively sanitize nested objects
44
+ const value = obj[key];
45
+ sanitized[key] = sanitizeObject(value);
46
+ }
47
+ return sanitized;
48
+ }
7
49
  /**
8
50
  * Parse JSON string with Zod schema validation
9
51
  */
10
52
  export function parseJson(jsonString, schema) {
11
53
  try {
12
- const data = JSON.parse(jsonString);
54
+ const rawData = JSON.parse(jsonString);
55
+ // SECURITY: Sanitize to prevent prototype pollution (REQ-SEC-005)
56
+ const data = sanitizeObject(rawData);
13
57
  if (schema) {
14
58
  const result = schema.safeParse(data);
15
59
  if (!result.success) {
@@ -169,4 +213,14 @@ export function parseJsonFileWithFallback(filePath, fallback, schema) {
169
213
  const result = parseJsonFile(filePath, schema);
170
214
  return result.success ? result.data : fallback;
171
215
  }
216
+ /**
217
+ * Sanitize an object to prevent prototype pollution
218
+ * Exported for testing purposes
219
+ *
220
+ * @param obj - Object to sanitize
221
+ * @returns Sanitized object
222
+ */
223
+ export function sanitizeJson(obj) {
224
+ return sanitizeObject(obj);
225
+ }
172
226
  //# sourceMappingURL=json-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"json-utils.js","sourceRoot":"","sources":["../../src/utils/json-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"json-utils.js","sourceRoot":"","sources":["../../src/utils/json-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Path Security Utilities
3
+ *
4
+ * Provides comprehensive path validation to prevent path traversal,
5
+ * symlink attacks, and access to dangerous system directories (REQ-SEC-002).
6
+ *
7
+ * @module path-security
8
+ */
9
+ /**
10
+ * Result of path validation
11
+ */
12
+ export interface PathValidationResult {
13
+ success: boolean;
14
+ path?: string;
15
+ error?: string;
16
+ }
17
+ /**
18
+ * Options for path validation
19
+ */
20
+ export interface PathValidationOptions {
21
+ allowSymlinks?: boolean;
22
+ allowedRoots?: string[];
23
+ checkExists?: boolean;
24
+ }
25
+ /**
26
+ * Get OS-specific dangerous paths that should never be accessed.
27
+ *
28
+ * @returns Array of dangerous path prefixes
29
+ */
30
+ export declare function getDangerousPathsForOS(): string[];
31
+ /**
32
+ * Get dangerous file patterns that should be blocked.
33
+ *
34
+ * @returns Array of dangerous file patterns (strings or regexes)
35
+ */
36
+ export declare function getDangerousFilePatterns(): Array<string | RegExp>;
37
+ /**
38
+ * Check if a path matches a dangerous file pattern.
39
+ *
40
+ * @param filePath - Path to check
41
+ * @returns True if file matches dangerous pattern
42
+ */
43
+ export declare function isDangerousFile(filePath: string): boolean;
44
+ /**
45
+ * Canonicalize a path by resolving symlinks and normalizing.
46
+ *
47
+ * @param filePath - Path to canonicalize
48
+ * @returns Canonicalized path or original if canonicalization fails
49
+ */
50
+ export declare function canonicalizePath(filePath: string): Promise<string>;
51
+ /**
52
+ * Check if a path contains symlinks in any component.
53
+ *
54
+ * @param filePath - Path to check
55
+ * @returns True if any component is a symlink
56
+ */
57
+ export declare function containsSymlinks(filePath: string): Promise<boolean>;
58
+ /**
59
+ * Validate a file path for security.
60
+ *
61
+ * Performs comprehensive checks:
62
+ * 1. Canonicalization (resolve symlinks)
63
+ * 2. Allowed root validation
64
+ * 3. Dangerous path blocking
65
+ * 4. Symlink detection
66
+ * 5. Dangerous file detection
67
+ *
68
+ * @param filePath - Path to validate
69
+ * @param options - Validation options
70
+ * @returns Validation result with success status and validated path
71
+ */
72
+ export declare function validatePathSecure(filePath: string, options?: PathValidationOptions): Promise<PathValidationResult>;
73
+ /**
74
+ * Synchronous version of validatePathSecure.
75
+ * Less secure (doesn't resolve symlinks), use async version when possible.
76
+ *
77
+ * @param filePath - Path to validate
78
+ * @param options - Validation options
79
+ * @returns Validation result
80
+ */
81
+ export declare function validatePathSecureSync(filePath: string, options?: PathValidationOptions): PathValidationResult;
82
+ /**
83
+ * Create a safe path joiner that validates the result.
84
+ *
85
+ * @param basePath - Base directory path
86
+ * @param relativePath - Relative path to join
87
+ * @param options - Validation options
88
+ * @returns Validated joined path or null if invalid
89
+ */
90
+ export declare function safePathJoin(basePath: string, relativePath: string, options?: PathValidationOptions): Promise<string | null>;