@defai.digital/ax-cli 3.5.2 → 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 (125) hide show
  1. package/.ax-cli/memory.json +8 -8
  2. package/README.md +27 -1
  3. package/dist/agent/chat-history-manager.d.ts +56 -0
  4. package/dist/agent/chat-history-manager.js +150 -0
  5. package/dist/agent/chat-history-manager.js.map +1 -0
  6. package/dist/agent/llm-agent.js +1 -1
  7. package/dist/agent/llm-agent.js.map +1 -1
  8. package/dist/agent/tool-manager.d.ts +39 -0
  9. package/dist/agent/tool-manager.js +76 -0
  10. package/dist/agent/tool-manager.js.map +1 -0
  11. package/dist/analyzers/ast/index.d.ts +9 -0
  12. package/dist/analyzers/ast/index.js +10 -0
  13. package/dist/analyzers/ast/index.js.map +1 -0
  14. package/dist/analyzers/ast/node-helpers.d.ts +81 -0
  15. package/dist/analyzers/ast/node-helpers.js +128 -0
  16. package/dist/analyzers/ast/node-helpers.js.map +1 -0
  17. package/dist/analyzers/ast/traverser.d.ts +67 -0
  18. package/dist/analyzers/ast/traverser.js +156 -0
  19. package/dist/analyzers/ast/traverser.js.map +1 -0
  20. package/dist/analyzers/best-practices/index.d.ts +10 -0
  21. package/dist/analyzers/best-practices/index.js +11 -0
  22. package/dist/analyzers/best-practices/index.js.map +1 -0
  23. package/dist/commands/setup.js +13 -5
  24. package/dist/commands/setup.js.map +1 -1
  25. package/dist/index.js +7 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/llm/client.d.ts +1 -0
  28. package/dist/llm/client.js +44 -0
  29. package/dist/llm/client.js.map +1 -1
  30. package/dist/mcp/ssrf-protection.d.ts +86 -0
  31. package/dist/mcp/ssrf-protection.js +313 -0
  32. package/dist/mcp/ssrf-protection.js.map +1 -0
  33. package/dist/mcp/validation.d.ts +4 -0
  34. package/dist/mcp/validation.js +122 -11
  35. package/dist/mcp/validation.js.map +1 -1
  36. package/dist/schemas/settings-schemas.d.ts +30 -0
  37. package/dist/schemas/settings-schemas.js +30 -0
  38. package/dist/schemas/settings-schemas.js.map +1 -1
  39. package/dist/tools/bash.d.ts +3 -2
  40. package/dist/tools/bash.js +31 -2
  41. package/dist/tools/bash.js.map +1 -1
  42. package/dist/tools/search.d.ts +1 -1
  43. package/dist/tools/search.js +121 -128
  44. package/dist/tools/search.js.map +1 -1
  45. package/dist/tools/text-editor.js +52 -15
  46. package/dist/tools/text-editor.js.map +1 -1
  47. package/dist/ui/components/status-bar.js +2 -2
  48. package/dist/ui/components/status-bar.js.map +1 -1
  49. package/dist/ui/components/toast-notification.js +0 -1
  50. package/dist/ui/components/toast-notification.js.map +1 -1
  51. package/dist/utils/audit-logger.d.ts +247 -0
  52. package/dist/utils/audit-logger.js +374 -0
  53. package/dist/utils/audit-logger.js.map +1 -0
  54. package/dist/utils/command-security.d.ts +85 -0
  55. package/dist/utils/command-security.js +200 -0
  56. package/dist/utils/command-security.js.map +1 -0
  57. package/dist/utils/encryption.d.ts +78 -0
  58. package/dist/utils/encryption.js +216 -0
  59. package/dist/utils/encryption.js.map +1 -0
  60. package/dist/utils/error-sanitizer.d.ts +119 -0
  61. package/dist/utils/error-sanitizer.js +253 -0
  62. package/dist/utils/error-sanitizer.js.map +1 -0
  63. package/dist/utils/input-sanitizer.d.ts +210 -0
  64. package/dist/utils/input-sanitizer.js +362 -0
  65. package/dist/utils/input-sanitizer.js.map +1 -0
  66. package/dist/utils/json-utils.d.ts +13 -0
  67. package/dist/utils/json-utils.js +55 -1
  68. package/dist/utils/json-utils.js.map +1 -1
  69. package/dist/utils/parallel-analyzer.js +29 -12
  70. package/dist/utils/parallel-analyzer.js.map +1 -1
  71. package/dist/utils/path-security.d.ts +90 -0
  72. package/dist/utils/path-security.js +328 -0
  73. package/dist/utils/path-security.js.map +1 -0
  74. package/dist/utils/process-pool.d.ts +105 -0
  75. package/dist/utils/process-pool.js +326 -0
  76. package/dist/utils/process-pool.js.map +1 -0
  77. package/dist/utils/rate-limiter.d.ts +207 -0
  78. package/dist/utils/rate-limiter.js +303 -0
  79. package/dist/utils/rate-limiter.js.map +1 -0
  80. package/dist/utils/settings-manager.js +83 -4
  81. package/dist/utils/settings-manager.js.map +1 -1
  82. package/eslint.config.js +3 -0
  83. package/package.json +1 -1
  84. package/.ax-cli/checkpoints/2025-11-20/checkpoint-11e9e0ba-c39d-4fd2-aa77-bc818811c921.json +0 -69
  85. package/.ax-cli/checkpoints/2025-11-20/checkpoint-2b260b98-b418-4c7c-9694-e2b94967e662.json +0 -24
  86. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7e03601e-e8ab-4cd7-9841-a74b66adf78f.json +0 -69
  87. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7f9c6562-771f-4fd0-adcf-9e7e9ac34ae8.json +0 -44
  88. package/.ax-cli/checkpoints/2025-11-20/checkpoint-e1ebe666-4c3a-4367-ba5c-27fe512a9c70.json +0 -24
  89. package/.ax-cli/checkpoints/2025-11-21/checkpoint-15743e7d-430c-4d76-b6fc-955d7a5c250c.json +0 -44
  90. package/.ax-cli/checkpoints/2025-11-21/checkpoint-25cf7679-0b3f-4988-83d7-704548fbba91.json +0 -69
  91. package/.ax-cli/checkpoints/2025-11-21/checkpoint-54aedbac-6db0-464e-8ebb-dbb3979e6dca.json +0 -24
  92. package/.ax-cli/checkpoints/2025-11-21/checkpoint-7658aed8-fe5d-4222-903f-1a7c63717ea7.json +0 -24
  93. package/.ax-cli/checkpoints/2025-11-21/checkpoint-c9c13497-40dc-4294-a327-6a5fc854eaa1.json +0 -69
  94. package/ax.config.json +0 -333
  95. package/dist/hooks/use-chat-reducer.d.ts +0 -61
  96. package/dist/hooks/use-chat-reducer.js +0 -118
  97. package/dist/hooks/use-chat-reducer.js.map +0 -1
  98. package/dist/hooks/use-enhanced-input.d.ts +0 -40
  99. package/dist/hooks/use-enhanced-input.js +0 -249
  100. package/dist/hooks/use-enhanced-input.js.map +0 -1
  101. package/dist/hooks/use-input-handler.d.ts +0 -46
  102. package/dist/hooks/use-input-handler.js +0 -1430
  103. package/dist/hooks/use-input-handler.js.map +0 -1
  104. package/dist/hooks/use-input-history.d.ts +0 -9
  105. package/dist/hooks/use-input-history.js +0 -112
  106. package/dist/hooks/use-input-history.js.map +0 -1
  107. package/dist/utils/paste-collapse.d.ts +0 -46
  108. package/dist/utils/paste-collapse.js +0 -77
  109. package/dist/utils/paste-collapse.js.map +0 -1
  110. package/packages/schemas/dist/index.d.ts +0 -14
  111. package/packages/schemas/dist/index.d.ts.map +0 -1
  112. package/packages/schemas/dist/index.js +0 -19
  113. package/packages/schemas/dist/index.js.map +0 -1
  114. package/packages/schemas/dist/public/core/brand-types.d.ts +0 -308
  115. package/packages/schemas/dist/public/core/brand-types.d.ts.map +0 -1
  116. package/packages/schemas/dist/public/core/brand-types.js +0 -243
  117. package/packages/schemas/dist/public/core/brand-types.js.map +0 -1
  118. package/packages/schemas/dist/public/core/enums.d.ts +0 -227
  119. package/packages/schemas/dist/public/core/enums.d.ts.map +0 -1
  120. package/packages/schemas/dist/public/core/enums.js +0 -222
  121. package/packages/schemas/dist/public/core/enums.js.map +0 -1
  122. package/packages/schemas/dist/public/core/id-types.d.ts +0 -286
  123. package/packages/schemas/dist/public/core/id-types.d.ts.map +0 -1
  124. package/packages/schemas/dist/public/core/id-types.js +0 -136
  125. package/packages/schemas/dist/public/core/id-types.js.map +0 -1
@@ -0,0 +1,78 @@
1
+ /**
2
+ * API Key Encryption Utilities
3
+ *
4
+ * Provides secure encryption/decryption for API keys stored in configuration
5
+ * files (REQ-SEC-003).
6
+ *
7
+ * Uses Node.js crypto module with:
8
+ * - AES-256-GCM for encryption (authenticated encryption)
9
+ * - PBKDF2 for key derivation from machine-specific identifier
10
+ * - Random IV for each encryption
11
+ * - Authentication tag verification
12
+ *
13
+ * @module encryption
14
+ */
15
+ /**
16
+ * Encrypted value format
17
+ */
18
+ export interface EncryptedValue {
19
+ encrypted: string;
20
+ iv: string;
21
+ tag: string;
22
+ version: number;
23
+ }
24
+ /**
25
+ * Encrypt a string value (typically an API key).
26
+ *
27
+ * @param plaintext - The value to encrypt
28
+ * @returns Encrypted value object with iv, tag, and encrypted data
29
+ */
30
+ export declare function encrypt(plaintext: string): EncryptedValue;
31
+ /**
32
+ * Decrypt an encrypted value.
33
+ *
34
+ * @param encryptedValue - The encrypted value object
35
+ * @returns Decrypted plaintext
36
+ * @throws Error if decryption fails (wrong machine, corrupted data, etc.)
37
+ */
38
+ export declare function decrypt(encryptedValue: EncryptedValue): string;
39
+ /**
40
+ * Check if a value is encrypted (has the expected structure).
41
+ *
42
+ * @param value - Value to check
43
+ * @returns True if value appears to be encrypted
44
+ */
45
+ export declare function isEncrypted(value: unknown): value is EncryptedValue;
46
+ /**
47
+ * Encrypt an object's sensitive fields.
48
+ *
49
+ * @param obj - Object containing sensitive fields
50
+ * @param fieldsToEncrypt - Array of field names to encrypt
51
+ * @returns New object with encrypted fields
52
+ */
53
+ export declare function encryptFields<T extends Record<string, any>>(obj: T, fieldsToEncrypt: string[]): T;
54
+ /**
55
+ * Decrypt an object's encrypted fields.
56
+ *
57
+ * @param obj - Object containing encrypted fields
58
+ * @param fieldsToDecrypt - Array of field names to decrypt
59
+ * @returns New object with decrypted fields
60
+ */
61
+ export declare function decryptFields<T extends Record<string, any>>(obj: T, fieldsToDecrypt: string[]): T;
62
+ /**
63
+ * Test if encryption is working (for diagnostics).
64
+ *
65
+ * @returns True if encryption/decryption round-trip works
66
+ */
67
+ export declare function testEncryption(): boolean;
68
+ /**
69
+ * Get encryption info for diagnostics.
70
+ */
71
+ export declare function getEncryptionInfo(): {
72
+ algorithm: string;
73
+ keyLength: number;
74
+ ivLength: number;
75
+ pbkdf2Iterations: number;
76
+ version: number;
77
+ machineId: string;
78
+ };
@@ -0,0 +1,216 @@
1
+ /**
2
+ * API Key Encryption Utilities
3
+ *
4
+ * Provides secure encryption/decryption for API keys stored in configuration
5
+ * files (REQ-SEC-003).
6
+ *
7
+ * Uses Node.js crypto module with:
8
+ * - AES-256-GCM for encryption (authenticated encryption)
9
+ * - PBKDF2 for key derivation from machine-specific identifier
10
+ * - Random IV for each encryption
11
+ * - Authentication tag verification
12
+ *
13
+ * @module encryption
14
+ */
15
+ import crypto from 'crypto';
16
+ import os from 'os';
17
+ /**
18
+ * Encryption configuration
19
+ */
20
+ const ENCRYPTION_CONFIG = {
21
+ algorithm: 'aes-256-gcm',
22
+ keyLength: 32, // 256 bits
23
+ ivLength: 16, // 128 bits
24
+ saltLength: 32, // 256 bits
25
+ tagLength: 16, // 128 bits
26
+ pbkdf2Iterations: 100000, // OWASP recommendation
27
+ version: 1,
28
+ };
29
+ /**
30
+ * Get a machine-specific identifier for key derivation.
31
+ * Uses hostname + platform + arch to create a unique-per-machine string.
32
+ *
33
+ * Note: This is not cryptographically strong protection (attacker with file
34
+ * access can derive the key), but it prevents casual browsing of config files
35
+ * and provides defense in depth.
36
+ */
37
+ function getMachineIdentifier() {
38
+ const hostname = os.hostname();
39
+ const platform = os.platform();
40
+ const arch = os.arch();
41
+ // Combine machine-specific data
42
+ return `${hostname}-${platform}-${arch}`;
43
+ }
44
+ /**
45
+ * Derive an encryption key from machine identifier and salt using PBKDF2.
46
+ *
47
+ * @param salt - Salt for key derivation
48
+ * @returns Derived encryption key
49
+ */
50
+ function deriveKey(salt) {
51
+ const machineId = getMachineIdentifier();
52
+ return crypto.pbkdf2Sync(machineId, salt, ENCRYPTION_CONFIG.pbkdf2Iterations, ENCRYPTION_CONFIG.keyLength, 'sha256');
53
+ }
54
+ /**
55
+ * Encrypt a string value (typically an API key).
56
+ *
57
+ * @param plaintext - The value to encrypt
58
+ * @returns Encrypted value object with iv, tag, and encrypted data
59
+ */
60
+ export function encrypt(plaintext) {
61
+ // Generate random salt and IV
62
+ const salt = crypto.randomBytes(ENCRYPTION_CONFIG.saltLength);
63
+ const iv = crypto.randomBytes(ENCRYPTION_CONFIG.ivLength);
64
+ // Derive key from machine identifier
65
+ const key = deriveKey(salt);
66
+ // Create cipher
67
+ const cipher = crypto.createCipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
68
+ // Encrypt the plaintext
69
+ let encrypted = cipher.update(plaintext, 'utf8', 'base64');
70
+ encrypted += cipher.final('base64');
71
+ // Get authentication tag
72
+ const tag = cipher.getAuthTag();
73
+ // Return encrypted value with metadata
74
+ // Store salt in the IV field for simplicity (both are public)
75
+ const saltAndIv = Buffer.concat([salt, iv]);
76
+ return {
77
+ encrypted,
78
+ iv: saltAndIv.toString('base64'),
79
+ tag: tag.toString('base64'),
80
+ version: ENCRYPTION_CONFIG.version,
81
+ };
82
+ }
83
+ /**
84
+ * Decrypt an encrypted value.
85
+ *
86
+ * @param encryptedValue - The encrypted value object
87
+ * @returns Decrypted plaintext
88
+ * @throws Error if decryption fails (wrong machine, corrupted data, etc.)
89
+ */
90
+ export function decrypt(encryptedValue) {
91
+ try {
92
+ // Check version
93
+ if (encryptedValue.version !== ENCRYPTION_CONFIG.version) {
94
+ throw new Error(`Unsupported encryption version: ${encryptedValue.version}`);
95
+ }
96
+ // Extract salt and IV
97
+ const saltAndIv = Buffer.from(encryptedValue.iv, 'base64');
98
+ if (saltAndIv.length !== ENCRYPTION_CONFIG.saltLength + ENCRYPTION_CONFIG.ivLength) {
99
+ throw new Error('Invalid encrypted data: incorrect salt/IV length');
100
+ }
101
+ const salt = saltAndIv.subarray(0, ENCRYPTION_CONFIG.saltLength);
102
+ const iv = saltAndIv.subarray(ENCRYPTION_CONFIG.saltLength);
103
+ // Derive key from machine identifier
104
+ const key = deriveKey(salt);
105
+ // Create decipher
106
+ const decipher = crypto.createDecipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
107
+ // Set authentication tag
108
+ const tag = Buffer.from(encryptedValue.tag, 'base64');
109
+ decipher.setAuthTag(tag);
110
+ // Decrypt
111
+ let decrypted = decipher.update(encryptedValue.encrypted, 'base64', 'utf8');
112
+ decrypted += decipher.final('utf8');
113
+ return decrypted;
114
+ }
115
+ catch (error) {
116
+ // Provide a user-friendly error message
117
+ if (error instanceof Error) {
118
+ if (error.message.includes('Unsupported state or unable to authenticate data')) {
119
+ throw new Error('Failed to decrypt API key. This may be due to: ' +
120
+ '(1) moving config to a different machine, ' +
121
+ '(2) corrupted config file, or ' +
122
+ '(3) config file was manually edited. ' +
123
+ 'Please re-enter your API key.');
124
+ }
125
+ throw new Error(`Decryption failed: ${error.message}`);
126
+ }
127
+ throw new Error('Decryption failed: Unknown error');
128
+ }
129
+ }
130
+ /**
131
+ * Check if a value is encrypted (has the expected structure).
132
+ *
133
+ * @param value - Value to check
134
+ * @returns True if value appears to be encrypted
135
+ */
136
+ export function isEncrypted(value) {
137
+ if (typeof value !== 'object' || value === null) {
138
+ return false;
139
+ }
140
+ const obj = value;
141
+ return (typeof obj.encrypted === 'string' &&
142
+ typeof obj.iv === 'string' &&
143
+ typeof obj.tag === 'string' &&
144
+ typeof obj.version === 'number');
145
+ }
146
+ /**
147
+ * Encrypt an object's sensitive fields.
148
+ *
149
+ * @param obj - Object containing sensitive fields
150
+ * @param fieldsToEncrypt - Array of field names to encrypt
151
+ * @returns New object with encrypted fields
152
+ */
153
+ export function encryptFields(obj, fieldsToEncrypt) {
154
+ const result = { ...obj };
155
+ for (const field of fieldsToEncrypt) {
156
+ if (field in result && typeof result[field] === 'string') {
157
+ // Don't re-encrypt already encrypted values
158
+ if (!isEncrypted(result[field])) {
159
+ result[field] = encrypt(result[field]);
160
+ }
161
+ }
162
+ }
163
+ return result;
164
+ }
165
+ /**
166
+ * Decrypt an object's encrypted fields.
167
+ *
168
+ * @param obj - Object containing encrypted fields
169
+ * @param fieldsToDecrypt - Array of field names to decrypt
170
+ * @returns New object with decrypted fields
171
+ */
172
+ export function decryptFields(obj, fieldsToDecrypt) {
173
+ const result = { ...obj };
174
+ for (const field of fieldsToDecrypt) {
175
+ if (field in result && isEncrypted(result[field])) {
176
+ try {
177
+ result[field] = decrypt(result[field]);
178
+ }
179
+ catch (error) {
180
+ // If decryption fails, leave the field as-is and let caller handle it
181
+ console.error(`Failed to decrypt field "${field}":`, error instanceof Error ? error.message : String(error));
182
+ }
183
+ }
184
+ }
185
+ return result;
186
+ }
187
+ /**
188
+ * Test if encryption is working (for diagnostics).
189
+ *
190
+ * @returns True if encryption/decryption round-trip works
191
+ */
192
+ export function testEncryption() {
193
+ try {
194
+ const testValue = 'test-api-key-12345';
195
+ const encrypted = encrypt(testValue);
196
+ const decrypted = decrypt(encrypted);
197
+ return decrypted === testValue;
198
+ }
199
+ catch {
200
+ return false;
201
+ }
202
+ }
203
+ /**
204
+ * Get encryption info for diagnostics.
205
+ */
206
+ export function getEncryptionInfo() {
207
+ return {
208
+ algorithm: ENCRYPTION_CONFIG.algorithm,
209
+ keyLength: ENCRYPTION_CONFIG.keyLength,
210
+ ivLength: ENCRYPTION_CONFIG.ivLength,
211
+ pbkdf2Iterations: ENCRYPTION_CONFIG.pbkdf2Iterations,
212
+ version: ENCRYPTION_CONFIG.version,
213
+ machineId: getMachineIdentifier(),
214
+ };
215
+ }
216
+ //# sourceMappingURL=encryption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/utils/encryption.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Error Message Sanitization (REQ-SEC-010)
3
+ *
4
+ * Sanitizes error messages to prevent information disclosure
5
+ * Removes:
6
+ * - File system paths
7
+ * - API keys and secrets
8
+ * - Stack traces (for user-facing errors)
9
+ * - Internal implementation details
10
+ *
11
+ * Security: CVSS 6.5 (Medium Priority)
12
+ */
13
+ /**
14
+ * Sanitized error structure
15
+ */
16
+ export interface SanitizedError {
17
+ /**
18
+ * Sanitized error message (safe for user display)
19
+ */
20
+ message: string;
21
+ /**
22
+ * Error code (for documentation lookup)
23
+ */
24
+ code?: string;
25
+ /**
26
+ * Generic error category
27
+ */
28
+ category: string;
29
+ /**
30
+ * Suggested action for user
31
+ */
32
+ suggestion?: string;
33
+ /**
34
+ * Original error (for internal logging only)
35
+ */
36
+ originalError?: Error;
37
+ }
38
+ /**
39
+ * Error categories for user-friendly messages
40
+ */
41
+ export declare enum ErrorCategory {
42
+ NETWORK = "NETWORK",
43
+ FILE_SYSTEM = "FILE_SYSTEM",
44
+ VALIDATION = "VALIDATION",
45
+ AUTHENTICATION = "AUTHENTICATION",
46
+ RATE_LIMIT = "RATE_LIMIT",
47
+ API_ERROR = "API_ERROR",
48
+ INTERNAL = "INTERNAL",
49
+ USER_INPUT = "USER_INPUT"
50
+ }
51
+ /**
52
+ * Sanitize error message by removing sensitive information
53
+ *
54
+ * @param message - Raw error message
55
+ * @returns Sanitized message safe for user display
56
+ */
57
+ export declare function sanitizeErrorMessage(message: string): string;
58
+ /**
59
+ * Sanitize stack trace by removing sensitive paths
60
+ *
61
+ * @param stack - Raw stack trace
62
+ * @returns Sanitized stack trace
63
+ */
64
+ export declare function sanitizeStackTrace(stack: string): string;
65
+ /**
66
+ * Remove stack trace entirely (for user-facing errors)
67
+ *
68
+ * @param message - Error message with potential stack trace
69
+ * @returns Message without stack trace
70
+ */
71
+ export declare function removeStackTrace(message: string): string;
72
+ /**
73
+ * Categorize error and create user-friendly message
74
+ *
75
+ * @param error - Error object
76
+ * @returns Sanitized error with category and suggestion
77
+ */
78
+ export declare function sanitizeError(error: Error | unknown): SanitizedError;
79
+ /**
80
+ * Format sanitized error for user display
81
+ *
82
+ * @param sanitizedError - Sanitized error object
83
+ * @returns Formatted error message
84
+ */
85
+ export declare function formatUserError(sanitizedError: SanitizedError): string;
86
+ /**
87
+ * Create internal log message with full details (not sanitized)
88
+ *
89
+ * @param error - Original error
90
+ * @param context - Additional context
91
+ * @returns Detailed log message
92
+ */
93
+ export declare function createInternalLogMessage(error: Error | unknown, context?: Record<string, unknown>): string;
94
+ /**
95
+ * Safe error wrapper for user-facing operations
96
+ *
97
+ * @param operation - Async operation to execute
98
+ * @param errorHandler - Optional custom error handler
99
+ * @returns Result or sanitized error
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const result = await safeExecute(
104
+ * () => riskyOperation(),
105
+ * (error) => console.error('Internal error:', error)
106
+ * );
107
+ *
108
+ * if (!result.success) {
109
+ * console.log(formatUserError(result.error));
110
+ * }
111
+ * ```
112
+ */
113
+ export declare function safeExecute<T>(operation: () => Promise<T>, errorHandler?: (error: Error, sanitized: SanitizedError) => void): Promise<{
114
+ success: true;
115
+ data: T;
116
+ } | {
117
+ success: false;
118
+ error: SanitizedError;
119
+ }>;
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Error Message Sanitization (REQ-SEC-010)
3
+ *
4
+ * Sanitizes error messages to prevent information disclosure
5
+ * Removes:
6
+ * - File system paths
7
+ * - API keys and secrets
8
+ * - Stack traces (for user-facing errors)
9
+ * - Internal implementation details
10
+ *
11
+ * Security: CVSS 6.5 (Medium Priority)
12
+ */
13
+ import { homedir } from 'os';
14
+ import { getAuditLogger, AuditCategory } from './audit-logger.js';
15
+ /**
16
+ * Patterns to detect and sanitize in error messages
17
+ */
18
+ const SENSITIVE_PATTERNS = {
19
+ // File paths (Windows and Unix)
20
+ FILE_PATH: /([A-Za-z]:\\|\/)[^\s"'<>|]+/g,
21
+ // API keys and tokens (common formats)
22
+ // Matches patterns like "api_key=XXX", "secret: XXX", "API key: XXX", "bearer XXX"
23
+ API_KEY: /\b(?:api[_ -]?key|token|secret|password|bearer)[\s:=]+['"]?[a-zA-Z0-9_\-]{16,}['"]?/gi,
24
+ // Environment variables
25
+ ENV_VAR: /\$\{?[A-Z_][A-Z0-9_]*\}?/g,
26
+ // IP addresses (for SSRF protection)
27
+ IP_ADDRESS: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
28
+ // URLs with credentials
29
+ URL_WITH_CREDS: /https?:\/\/[^:]+:[^@]+@[^\s]+/g,
30
+ // Stack trace lines
31
+ STACK_TRACE_LINE: /^\s*at\s+.+\(.+:\d+:\d+\)$/gm,
32
+ // Home directory references
33
+ HOME_DIR: new RegExp(homedir().replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
34
+ };
35
+ /**
36
+ * Replacement strings for sanitized content
37
+ */
38
+ const REPLACEMENTS = {
39
+ FILE_PATH: '[REDACTED_PATH]',
40
+ API_KEY: '[REDACTED_KEY]',
41
+ ENV_VAR: '[REDACTED_ENV]',
42
+ IP_ADDRESS: '[REDACTED_IP]',
43
+ URL_WITH_CREDS: '[REDACTED_URL]',
44
+ STACK_TRACE_LINE: '',
45
+ HOME_DIR: '[USER_HOME]',
46
+ };
47
+ /**
48
+ * Error categories for user-friendly messages
49
+ */
50
+ export var ErrorCategory;
51
+ (function (ErrorCategory) {
52
+ ErrorCategory["NETWORK"] = "NETWORK";
53
+ ErrorCategory["FILE_SYSTEM"] = "FILE_SYSTEM";
54
+ ErrorCategory["VALIDATION"] = "VALIDATION";
55
+ ErrorCategory["AUTHENTICATION"] = "AUTHENTICATION";
56
+ ErrorCategory["RATE_LIMIT"] = "RATE_LIMIT";
57
+ ErrorCategory["API_ERROR"] = "API_ERROR";
58
+ ErrorCategory["INTERNAL"] = "INTERNAL";
59
+ ErrorCategory["USER_INPUT"] = "USER_INPUT";
60
+ })(ErrorCategory || (ErrorCategory = {}));
61
+ /**
62
+ * Sanitize error message by removing sensitive information
63
+ *
64
+ * @param message - Raw error message
65
+ * @returns Sanitized message safe for user display
66
+ */
67
+ export function sanitizeErrorMessage(message) {
68
+ let sanitized = message;
69
+ // Remove URLs with credentials first (before FILE_PATH catches them)
70
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.URL_WITH_CREDS, REPLACEMENTS.URL_WITH_CREDS);
71
+ // Remove home directory references (before FILE_PATH catches them)
72
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.HOME_DIR, REPLACEMENTS.HOME_DIR);
73
+ // Remove file paths
74
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.FILE_PATH, REPLACEMENTS.FILE_PATH);
75
+ // Remove API keys and secrets
76
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.API_KEY, REPLACEMENTS.API_KEY);
77
+ // Remove environment variables
78
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.ENV_VAR, REPLACEMENTS.ENV_VAR);
79
+ // Remove IP addresses
80
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.IP_ADDRESS, REPLACEMENTS.IP_ADDRESS);
81
+ return sanitized;
82
+ }
83
+ /**
84
+ * Sanitize stack trace by removing sensitive paths
85
+ *
86
+ * @param stack - Raw stack trace
87
+ * @returns Sanitized stack trace
88
+ */
89
+ export function sanitizeStackTrace(stack) {
90
+ let sanitized = stack;
91
+ // Remove home directory references first
92
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.HOME_DIR, REPLACEMENTS.HOME_DIR);
93
+ // Remove file paths from stack frames
94
+ sanitized = sanitized.replace(SENSITIVE_PATTERNS.FILE_PATH, REPLACEMENTS.FILE_PATH);
95
+ return sanitized;
96
+ }
97
+ /**
98
+ * Remove stack trace entirely (for user-facing errors)
99
+ *
100
+ * @param message - Error message with potential stack trace
101
+ * @returns Message without stack trace
102
+ */
103
+ export function removeStackTrace(message) {
104
+ // Split at first "at " (stack trace start)
105
+ const parts = message.split(/\n\s*at\s+/);
106
+ return parts[0].trim();
107
+ }
108
+ /**
109
+ * Categorize error and create user-friendly message
110
+ *
111
+ * @param error - Error object
112
+ * @returns Sanitized error with category and suggestion
113
+ */
114
+ export function sanitizeError(error) {
115
+ const errorObj = error instanceof Error ? error : new Error(String(error));
116
+ const message = errorObj.message;
117
+ // Sanitize the message
118
+ const sanitizedMessage = sanitizeErrorMessage(removeStackTrace(message));
119
+ // Determine category and suggestion
120
+ let category = ErrorCategory.INTERNAL;
121
+ let suggestion;
122
+ let code;
123
+ // Network errors
124
+ if (message.includes('ENOTFOUND') || message.includes('ECONNREFUSED') || message.includes('fetch failed')) {
125
+ category = ErrorCategory.NETWORK;
126
+ suggestion = 'Check your network connection and try again.';
127
+ code = 'ERR_NETWORK';
128
+ }
129
+ // File system errors
130
+ else if (message.includes('ENOENT') || message.includes('EACCES') || message.includes('EPERM')) {
131
+ category = ErrorCategory.FILE_SYSTEM;
132
+ suggestion = 'Check that the file exists and you have permission to access it.';
133
+ code = 'ERR_FILE_SYSTEM';
134
+ }
135
+ // Validation errors
136
+ else if (message.includes('validation') || message.includes('invalid') || message.includes('required')) {
137
+ category = ErrorCategory.VALIDATION;
138
+ suggestion = 'Check your input and try again.';
139
+ code = 'ERR_VALIDATION';
140
+ }
141
+ // Authentication errors
142
+ else if (message.includes('unauthorized') || message.includes('authentication') || message.includes('API key')) {
143
+ category = ErrorCategory.AUTHENTICATION;
144
+ suggestion = 'Check your API key configuration.';
145
+ code = 'ERR_AUTH';
146
+ }
147
+ // Rate limit errors
148
+ else if (message.includes('rate limit') || message.includes('too many requests')) {
149
+ category = ErrorCategory.RATE_LIMIT;
150
+ suggestion = 'Please wait a moment before trying again.';
151
+ code = 'ERR_RATE_LIMIT';
152
+ }
153
+ // API errors
154
+ else if (message.includes('API') || message.includes('status code')) {
155
+ category = ErrorCategory.API_ERROR;
156
+ suggestion = 'The API returned an error. Please try again later.';
157
+ code = 'ERR_API';
158
+ }
159
+ // REQ-SEC-008: Audit log errors with sensitive info detection
160
+ if (message !== sanitizedMessage) {
161
+ const auditLogger = getAuditLogger();
162
+ auditLogger.logWarning({
163
+ category: AuditCategory.SYSTEM_EVENT,
164
+ action: 'sensitive_data_in_error',
165
+ outcome: 'success',
166
+ details: {
167
+ category,
168
+ sanitized: true,
169
+ },
170
+ });
171
+ }
172
+ return {
173
+ message: sanitizedMessage,
174
+ code,
175
+ category,
176
+ suggestion,
177
+ originalError: errorObj,
178
+ };
179
+ }
180
+ /**
181
+ * Format sanitized error for user display
182
+ *
183
+ * @param sanitizedError - Sanitized error object
184
+ * @returns Formatted error message
185
+ */
186
+ export function formatUserError(sanitizedError) {
187
+ const parts = [];
188
+ if (sanitizedError.code) {
189
+ parts.push(`[${sanitizedError.code}]`);
190
+ }
191
+ parts.push(sanitizedError.message);
192
+ if (sanitizedError.suggestion) {
193
+ parts.push(`\nℹ️ ${sanitizedError.suggestion}`);
194
+ }
195
+ return parts.join(' ');
196
+ }
197
+ /**
198
+ * Create internal log message with full details (not sanitized)
199
+ *
200
+ * @param error - Original error
201
+ * @param context - Additional context
202
+ * @returns Detailed log message
203
+ */
204
+ export function createInternalLogMessage(error, context) {
205
+ const errorObj = error instanceof Error ? error : new Error(String(error));
206
+ const parts = [
207
+ `Error: ${errorObj.message}`,
208
+ ];
209
+ if (errorObj.stack) {
210
+ parts.push(`Stack: ${sanitizeStackTrace(errorObj.stack)}`);
211
+ }
212
+ if (context) {
213
+ parts.push(`Context: ${JSON.stringify(context, null, 2)}`);
214
+ }
215
+ return parts.join('\n');
216
+ }
217
+ /**
218
+ * Safe error wrapper for user-facing operations
219
+ *
220
+ * @param operation - Async operation to execute
221
+ * @param errorHandler - Optional custom error handler
222
+ * @returns Result or sanitized error
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const result = await safeExecute(
227
+ * () => riskyOperation(),
228
+ * (error) => console.error('Internal error:', error)
229
+ * );
230
+ *
231
+ * if (!result.success) {
232
+ * console.log(formatUserError(result.error));
233
+ * }
234
+ * ```
235
+ */
236
+ export async function safeExecute(operation, errorHandler) {
237
+ try {
238
+ const data = await operation();
239
+ return { success: true, data };
240
+ }
241
+ catch (error) {
242
+ const sanitized = sanitizeError(error);
243
+ // Log internal error details
244
+ if (errorHandler) {
245
+ errorHandler(sanitized.originalError, sanitized);
246
+ }
247
+ else {
248
+ console.error(createInternalLogMessage(error));
249
+ }
250
+ return { success: false, error: sanitized };
251
+ }
252
+ }
253
+ //# sourceMappingURL=error-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-sanitizer.js","sourceRoot":"","sources":["../../src/utils/error-sanitizer.ts"],"names":[],"mappings":"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"}