0xray 4.0.33 → 4.0.35

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 (156) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.xray/codex.json +12 -4
  3. package/.xray/features.json +1 -1
  4. package/AGENTS-consumer.md +6 -6
  5. package/AGENTS.md +5 -5
  6. package/README.md +2 -2
  7. package/dist/AGENTS.md +5 -5
  8. package/dist/CHANGELOG.md +25 -0
  9. package/dist/README.md +2 -2
  10. package/dist/cli/index.js +2 -5
  11. package/dist/governance/governance-service.js +1 -1
  12. package/dist/integrations/base/README.md +1 -9
  13. package/dist/integrations/base/index.d.ts +0 -1
  14. package/dist/integrations/base/index.js +0 -2
  15. package/dist/integrations/governance/index.js +31 -8
  16. package/dist/integrations/grok/hooks/grok-hook-utils.js +1 -1
  17. package/dist/integrations/grok/hooks/session-start.js +12 -0
  18. package/dist/integrations/hooks/goggles-pipeline.mjs +108 -22
  19. package/dist/integrations/hooks/goggles-planes.json +23 -0
  20. package/dist/integrations/hooks/host-truth.mjs +74 -0
  21. package/dist/integrations/hooks/station-hook-runtime.cjs +3 -0
  22. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  23. package/dist/mcps/knowledge-skills/storyteller.server.js +0 -1
  24. package/dist/nucleus/delegation-gate.d.ts +2 -2
  25. package/dist/nucleus/delegation-gate.js +13 -2
  26. package/dist/nucleus/work-freshness.mjs +189 -0
  27. package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
  28. package/docs-site/docs/plates/boot.md +17 -2
  29. package/docs-site/docs/plates/governance.md +3 -2
  30. package/docs-site/docs/plates/index.md +3 -1
  31. package/docs-site/docs/plates/memory-recall.md +26 -35
  32. package/docs-site/docs/plates/orchestration.md +39 -35
  33. package/docs-site/docs/plates/processor.md +34 -36
  34. package/docs-site/docs/plates/reporting.md +3 -8
  35. package/docs-site/docs/plates/routing.md +22 -11
  36. package/package.json +2 -2
  37. package/scripts/foundry/release.mjs +48 -5
  38. package/scripts/mjs/test-consumer-readiness.mjs +1 -0
  39. package/scripts/mjs/test-mcp-functionality.mjs +14 -9
  40. package/scripts/node/basic-security-audit.cjs +0 -1
  41. package/scripts/node/bridge-mcp-wiring.cjs +66 -3
  42. package/scripts/node/postinstall.cjs +1 -1
  43. package/scripts/node/prepare-consumer.cjs +11 -7
  44. package/scripts/node/setup-dev.cjs +18 -26
  45. package/scripts/node/validate-mcp-connectivity.js +2 -1
  46. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  47. package/src/mcps/knowledge-skills/storyteller.server.ts +0 -1
  48. package/xray/agents_template.md +5 -5
  49. package/xray/codex.json +12 -4
  50. package/xray/features.json +1 -1
  51. package/dist/agents/known-names.d.ts +0 -26
  52. package/dist/agents/known-names.js +0 -72
  53. package/dist/analytics/consent-manager.d.ts +0 -92
  54. package/dist/analytics/consent-manager.js +0 -257
  55. package/dist/benchmark/performance-benchmark.d.ts +0 -103
  56. package/dist/benchmark/performance-benchmark.js +0 -373
  57. package/dist/cli/commands/analytics-disable.d.ts +0 -9
  58. package/dist/cli/commands/analytics-disable.js +0 -72
  59. package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
  60. package/dist/cli/commands/analytics-enable-action.js +0 -82
  61. package/dist/cli/commands/analytics-preview.d.ts +0 -9
  62. package/dist/cli/commands/analytics-preview.js +0 -106
  63. package/dist/cli/commands/analytics-status.d.ts +0 -9
  64. package/dist/cli/commands/analytics-status.js +0 -68
  65. package/dist/cli/commands/enforce.d.ts +0 -12
  66. package/dist/cli/commands/enforce.js +0 -78
  67. package/dist/cli/commands/govern.d.ts +0 -29
  68. package/dist/cli/commands/govern.js +0 -149
  69. package/dist/cli/commands/security-audit.d.ts +0 -23
  70. package/dist/cli/commands/security-audit.js +0 -219
  71. package/dist/cli/server.d.ts +0 -1
  72. package/dist/cli/server.js +0 -147
  73. package/dist/config/routing-mappings.d.ts +0 -26
  74. package/dist/config/routing-mappings.js +0 -151
  75. package/dist/core/bridge.mjs +0 -922
  76. package/dist/core/trace-context.d.ts +0 -12
  77. package/dist/core/trace-context.js +0 -33
  78. package/dist/enforcement/index.d.ts +0 -22
  79. package/dist/enforcement/index.js +0 -40
  80. package/dist/enforcement/loaders/index.d.ts +0 -36
  81. package/dist/enforcement/loaders/index.js +0 -39
  82. package/dist/enforcement/test-auto-healing.d.ts +0 -83
  83. package/dist/enforcement/test-auto-healing.js +0 -325
  84. package/dist/inference/index.d.ts +0 -10
  85. package/dist/inference/index.js +0 -5
  86. package/dist/infrastructure/iac-validator.d.ts +0 -150
  87. package/dist/infrastructure/iac-validator.js +0 -465
  88. package/dist/infrastructure/schemas/cloud-schemas.d.ts +0 -482
  89. package/dist/infrastructure/schemas/cloud-schemas.js +0 -488
  90. package/dist/integrations/base/ExampleIntegration.d.ts +0 -46
  91. package/dist/integrations/base/ExampleIntegration.js +0 -180
  92. package/dist/integrations/enforcement-gate.d.ts +0 -44
  93. package/dist/integrations/enforcement-gate.js +0 -348
  94. package/dist/mcps/connection/connection-manager.d.ts +0 -39
  95. package/dist/mcps/connection/connection-manager.js +0 -79
  96. package/dist/mcps/index.d.ts +0 -17
  97. package/dist/mcps/index.js +0 -65
  98. package/dist/mcps/orchestrator/index.d.ts +0 -6
  99. package/dist/mcps/orchestrator/index.js +0 -5
  100. package/dist/metrics/index.d.ts +0 -6
  101. package/dist/metrics/index.js +0 -6
  102. package/dist/orchestrator/self-direction-activation.d.ts +0 -108
  103. package/dist/orchestrator/self-direction-activation.js +0 -244
  104. package/dist/orchestrator/universal-registry-bridge.d.ts +0 -84
  105. package/dist/orchestrator/universal-registry-bridge.js +0 -246
  106. package/dist/performance/performance-budget-enforcer.d.ts +0 -157
  107. package/dist/performance/performance-budget-enforcer.js +0 -433
  108. package/dist/performance/performance-regression-tester.d.ts +0 -107
  109. package/dist/performance/performance-regression-tester.js +0 -341
  110. package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +0 -11
  111. package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +0 -50
  112. package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +0 -44
  113. package/dist/postprocessor/config/ProcessorConfigLoader.js +0 -16
  114. package/dist/postprocessor/integration.d.ts +0 -156
  115. package/dist/postprocessor/integration.js +0 -194
  116. package/dist/postprocessor/metamorphosis/index.d.ts +0 -2
  117. package/dist/postprocessor/metamorphosis/index.js +0 -1
  118. package/dist/postprocessor/redeploy/RetryHandler.d.ts +0 -49
  119. package/dist/postprocessor/redeploy/RetryHandler.js +0 -118
  120. package/dist/processors/implementations/session-capture-processor.d.ts +0 -14
  121. package/dist/processors/implementations/session-capture-processor.js +0 -37
  122. package/dist/public/XrayService.d.ts +0 -17
  123. package/dist/public/XrayService.js +0 -40
  124. package/dist/public/index.d.ts +0 -4
  125. package/dist/public/index.js +0 -2
  126. package/dist/security/comprehensive-security-audit.d.ts +0 -157
  127. package/dist/security/comprehensive-security-audit.js +0 -1004
  128. package/dist/security/index.d.ts +0 -13
  129. package/dist/security/index.js +0 -13
  130. package/dist/security/security-agent-coordinator.d.ts +0 -71
  131. package/dist/security/security-agent-coordinator.js +0 -203
  132. package/dist/security/security-hardening-system.d.ts +0 -238
  133. package/dist/security/security-hardening-system.js +0 -726
  134. package/dist/security/security-orchestration-layer.d.ts +0 -118
  135. package/dist/security/security-orchestration-layer.js +0 -495
  136. package/dist/testing/memory-regression-suite.d.ts +0 -105
  137. package/dist/testing/memory-regression-suite.js +0 -258
  138. package/dist/tools/assess-complexity-tool.d.ts +0 -28
  139. package/dist/tools/assess-complexity-tool.js +0 -44
  140. package/dist/tools/query-routing-tool.d.ts +0 -17
  141. package/dist/tools/query-routing-tool.js +0 -59
  142. package/dist/utils/batch-operations.d.ts +0 -25
  143. package/dist/utils/batch-operations.js +0 -292
  144. package/dist/utils/task-graph.d.ts +0 -29
  145. package/dist/utils/task-graph.js +0 -106
  146. package/dist/utils/test-template-generator.d.ts +0 -25
  147. package/dist/utils/test-template-generator.js +0 -178
  148. package/dist/utils/token-manager.d.ts +0 -48
  149. package/dist/utils/token-manager.js +0 -163
  150. package/dist/validation/agent-config-validator.d.ts +0 -110
  151. package/dist/validation/agent-config-validator.js +0 -280
  152. package/dist/validation/orchestration-flow-validator.d.ts +0 -87
  153. package/dist/validation/orchestration-flow-validator.js +0 -606
  154. package/src/mcps/connection/connection-manager.ts +0 -91
  155. package/src/mcps/index.ts +0 -80
  156. package/src/mcps/orchestrator/index.ts +0 -29
@@ -1,726 +0,0 @@
1
- /**
2
- * Security Hardening System
3
- *
4
- * Comprehensive security hardening implementation with OWASP compliance.
5
- * Implements defense-in-depth security architecture for enterprise applications.
6
- *
7
- * @since 2026-01-08
8
- */
9
- import { EventEmitter } from "events";
10
- import * as crypto from "crypto";
11
- import { frameworkLogger } from "../core/framework-logger.js";
12
- // Security configuration constants
13
- export const SECURITY_CONFIG = {
14
- headers: {
15
- "X-Content-Type-Options": "nosniff",
16
- "X-Frame-Options": "DENY",
17
- "X-XSS-Protection": "1; mode=block",
18
- "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
19
- "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'",
20
- "Referrer-Policy": "strict-origin-when-cross-origin",
21
- "Permissions-Policy": "geolocation=(), microphone=(), camera=()",
22
- "Cross-Origin-Embedder-Policy": "require-corp",
23
- "Cross-Origin-Opener-Policy": "same-origin",
24
- "Cross-Origin-Resource-Policy": "same-origin",
25
- },
26
- rateLimiting: {
27
- windowMs: 15 * 60 * 1000, // 15 minutes
28
- maxRequests: 100, // limit each IP to 100 requests per windowMs
29
- skipSuccessfulRequests: false,
30
- skipFailedRequests: false,
31
- },
32
- inputValidation: {
33
- maxStringLength: 10000,
34
- maxArrayLength: 1000,
35
- maxObjectDepth: 10,
36
- allowedCharacters: /^[a-zA-Z0-9\s\-_.@]+$/,
37
- sqlInjectionPatterns: [
38
- /(\b(union|select|insert|delete|update|drop|create|alter|exec|execute)\b)/i,
39
- /('|(\\x27)|(\\x2D\\x2D)|(\-\-)|(\#)|(\;)|(\*))/i,
40
- ],
41
- xssPatterns: [
42
- /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
43
- /javascript:/gi,
44
- /on\w+\s*=/gi,
45
- /<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
46
- ],
47
- },
48
- encryption: {
49
- algorithm: "aes-256-gcm",
50
- keyLength: 32,
51
- ivLength: 16,
52
- saltRounds: 12,
53
- },
54
- audit: {
55
- logLevel: "detailed",
56
- retentionDays: 90,
57
- sensitiveFields: ["password", "token", "secret", "key", "authorization"],
58
- },
59
- };
60
- /**
61
- * Core security hardening system
62
- */
63
- export class SecurityHardeningSystem extends EventEmitter {
64
- rateLimitStore = new Map();
65
- securityEvents = [];
66
- encryptionKey = Buffer.alloc(0);
67
- auditLogEnabled = true;
68
- started = false;
69
- pendingEncryptionKey;
70
- boundSecurityEvent;
71
- boundRateLimitExceeded;
72
- boundValidationFailure;
73
- constructor(encryptionKey) {
74
- super();
75
- this.pendingEncryptionKey = encryptionKey;
76
- }
77
- start() {
78
- if (this.started)
79
- return;
80
- this.started = true;
81
- this.encryptionKey = this.pendingEncryptionKey
82
- ? crypto.scryptSync(this.pendingEncryptionKey, "salt", SECURITY_CONFIG.encryption.keyLength)
83
- : crypto.randomBytes(SECURITY_CONFIG.encryption.keyLength);
84
- this.setupEventHandlers();
85
- }
86
- /**
87
- * Setup event handlers for security events
88
- */
89
- setupEventHandlers() {
90
- this.boundSecurityEvent = this.handleSecurityEvent.bind(this);
91
- this.boundRateLimitExceeded = this.handleRateLimitExceeded.bind(this);
92
- this.boundValidationFailure = this.handleValidationFailure.bind(this);
93
- this.on("security-event", this.boundSecurityEvent);
94
- this.on("rate-limit-exceeded", this.boundRateLimitExceeded);
95
- this.on("validation-failure", this.boundValidationFailure);
96
- }
97
- destroy() {
98
- this.off("security-event", this.boundSecurityEvent);
99
- this.off("rate-limit-exceeded", this.boundRateLimitExceeded);
100
- this.off("validation-failure", this.boundValidationFailure);
101
- this.removeAllListeners();
102
- }
103
- /**
104
- * Create security middleware for HTTP requests
105
- */
106
- createSecurityMiddleware(options = {}) {
107
- const config = {
108
- enableRateLimiting: true,
109
- enableInputValidation: true,
110
- enableSecurityHeaders: true,
111
- enableAuditLogging: true,
112
- enableCsrfProtection: true,
113
- enableHsts: true,
114
- ...options,
115
- };
116
- return async (req, res) => {
117
- try {
118
- // Rate limiting check
119
- if (config.enableRateLimiting) {
120
- const rateLimitResult = this.checkRateLimit(req);
121
- if (!rateLimitResult.allowed) {
122
- this.emitSecurityEvent({
123
- type: "rate_limit_exceeded",
124
- severity: "medium",
125
- message: `Rate limit exceeded for IP: ${rateLimitResult.ip}`,
126
- source: "rate-limiter",
127
- ipAddress: rateLimitResult.ip,
128
- metadata: {
129
- limit: rateLimitResult.limit,
130
- remaining: rateLimitResult.remaining,
131
- },
132
- });
133
- res.writeHead(429, { "Content-Type": "application/json" });
134
- res.end(JSON.stringify({
135
- error: "Too Many Requests",
136
- message: "Rate limit exceeded. Please try again later.",
137
- retryAfter: Math.ceil((rateLimitResult.resetTime - Date.now()) / 1000),
138
- }));
139
- return false;
140
- }
141
- }
142
- // Security headers
143
- if (config.enableSecurityHeaders) {
144
- this.applySecurityHeaders(res, config);
145
- }
146
- // CSRF protection
147
- if (config.enableCsrfProtection) {
148
- const csrfValid = this.validateCsrfToken(req);
149
- if (!csrfValid) {
150
- this.emitSecurityEvent({
151
- type: "csrf_attempt",
152
- severity: "high",
153
- message: "CSRF token validation failed",
154
- source: "csrf-protection",
155
- ipAddress: this.getClientIP(req),
156
- userAgent: req.headers["user-agent"],
157
- metadata: { path: req.url },
158
- });
159
- res.writeHead(403, { "Content-Type": "application/json" });
160
- res.end(JSON.stringify({
161
- error: "Forbidden",
162
- message: "CSRF validation failed",
163
- }));
164
- return false;
165
- }
166
- }
167
- // Audit logging
168
- if (config.enableAuditLogging) {
169
- this.logAuditEvent(req, "request-processed");
170
- }
171
- return true;
172
- }
173
- catch (error) {
174
- frameworkLogger.log("security-hardening", "middleware-error", "error", { error: error instanceof Error ? error.message : String(error) });
175
- this.emitSecurityEvent({
176
- type: "suspicious_activity",
177
- severity: "high",
178
- message: `Security middleware error: ${error instanceof Error ? error.message : String(error)}`,
179
- source: "security-middleware",
180
- ipAddress: this.getClientIP(req),
181
- metadata: {
182
- error: error instanceof Error ? error.message : String(error),
183
- },
184
- });
185
- res.writeHead(500, { "Content-Type": "application/json" });
186
- res.end(JSON.stringify({
187
- error: "Internal Server Error",
188
- message: "Security validation failed",
189
- }));
190
- return false;
191
- }
192
- };
193
- }
194
- /**
195
- * Check rate limiting for requests
196
- */
197
- checkRateLimit(req) {
198
- const ip = this.getClientIP(req);
199
- const now = Date.now();
200
- const windowMs = SECURITY_CONFIG.rateLimiting.windowMs;
201
- const maxRequests = SECURITY_CONFIG.rateLimiting.maxRequests;
202
- let entry = this.rateLimitStore.get(ip);
203
- if (!entry || now > entry.resetTime) {
204
- entry = {
205
- count: 0,
206
- resetTime: now + windowMs,
207
- lastRequest: now,
208
- };
209
- }
210
- entry.count++;
211
- entry.lastRequest = now;
212
- this.rateLimitStore.set(ip, entry);
213
- // Clean up old entries periodically
214
- if (Math.random() < 0.01) {
215
- // 1% chance to clean up
216
- this.cleanupRateLimitStore();
217
- }
218
- const allowed = entry.count <= maxRequests;
219
- const remaining = Math.max(0, maxRequests - entry.count);
220
- return {
221
- allowed,
222
- ip,
223
- limit: maxRequests,
224
- remaining,
225
- resetTime: entry.resetTime,
226
- };
227
- }
228
- /**
229
- * Apply security headers to response
230
- */
231
- applySecurityHeaders(res, config) {
232
- const headers = { ...SECURITY_CONFIG.headers };
233
- // Apply custom headers
234
- if (config.customHeaders) {
235
- Object.assign(headers, config.customHeaders);
236
- }
237
- // Conditionally remove HSTS
238
- if (!config.enableHsts) {
239
- const headersRecord = headers;
240
- const { "Strict-Transport-Security": _, ...remainingHeaders } = headersRecord;
241
- Object.assign(headers, remainingHeaders);
242
- }
243
- // Set all headers
244
- Object.entries(headers).forEach(([key, value]) => {
245
- res.setHeader(key, value);
246
- });
247
- // Add rate limit headers
248
- const rateLimitInfo = this.getRateLimitInfo(this.getClientIP({ headers: {}, socket: { remoteAddress: "unknown" } }));
249
- if (rateLimitInfo) {
250
- res.setHeader("X-RateLimit-Limit", rateLimitInfo.limit.toString());
251
- res.setHeader("X-RateLimit-Remaining", rateLimitInfo.remaining.toString());
252
- res.setHeader("X-RateLimit-Reset", Math.ceil(rateLimitInfo.resetTime / 1000).toString());
253
- }
254
- }
255
- /**
256
- * Validate CSRF token
257
- */
258
- validateCsrfToken(req) {
259
- const token = req.headers["x-csrf-token"];
260
- const reqWithSession = req;
261
- const sessionToken = reqWithSession.session?.csrfToken;
262
- if (!token || !sessionToken) {
263
- return false;
264
- }
265
- return crypto.timingSafeEqual(Buffer.from(token, "hex"), Buffer.from(sessionToken, "hex"));
266
- }
267
- /**
268
- * Validate and sanitize input data
269
- */
270
- validateInput(input, context = "general") {
271
- const result = {
272
- isValid: true,
273
- errors: [],
274
- securityEvents: [],
275
- };
276
- try {
277
- // Type validation
278
- if (input === null || input === undefined) {
279
- result.isValid = false;
280
- result.errors.push("Input cannot be null or undefined");
281
- return result;
282
- }
283
- // String validation
284
- if (typeof input === "string") {
285
- result.sanitizedValue = this.validateString(input, context, result);
286
- }
287
- // Object validation
288
- else if (typeof input === "object") {
289
- result.sanitizedValue = this.validateObject(input, context, result);
290
- }
291
- // Array validation
292
- else if (Array.isArray(input)) {
293
- result.sanitizedValue = this.validateArray(input, context, result);
294
- }
295
- // Security pattern checks
296
- this.checkSecurityPatterns(input, context, result);
297
- }
298
- catch (error) {
299
- result.isValid = false;
300
- result.errors.push(`Validation error: ${error instanceof Error ? error.message : String(error)}`);
301
- frameworkLogger.log("security-hardening-system", "-security-data-decryption-failed-error-instanceof-", "error", {
302
- message: `[SECURITY] Data decryption failed: ${error instanceof Error ? error.message : String(error)}`,
303
- });
304
- }
305
- return result;
306
- }
307
- /**
308
- * Validate string input
309
- */
310
- validateString(input, context, result) {
311
- // Length check
312
- if (input.length > SECURITY_CONFIG.inputValidation.maxStringLength) {
313
- result.isValid = false;
314
- result.errors.push(`String length exceeds maximum (${SECURITY_CONFIG.inputValidation.maxStringLength})`);
315
- return input.substring(0, SECURITY_CONFIG.inputValidation.maxStringLength);
316
- }
317
- // Character validation
318
- if (!SECURITY_CONFIG.inputValidation.allowedCharacters.test(input)) {
319
- result.isValid = false;
320
- result.errors.push("String contains invalid characters");
321
- }
322
- // SQL injection check
323
- for (const pattern of SECURITY_CONFIG.inputValidation
324
- .sqlInjectionPatterns) {
325
- if (pattern.test(input)) {
326
- result.isValid = false;
327
- result.errors.push("Potential SQL injection detected");
328
- this.emitSecurityEvent({
329
- type: "sql_injection_attempt",
330
- severity: "high",
331
- message: "SQL injection pattern detected in input",
332
- source: "input-validator",
333
- metadata: { context, pattern: pattern.source },
334
- });
335
- break;
336
- }
337
- }
338
- // XSS check
339
- for (const pattern of SECURITY_CONFIG.inputValidation.xssPatterns) {
340
- if (pattern.test(input)) {
341
- result.isValid = false;
342
- result.errors.push("Potential XSS attack detected");
343
- this.emitSecurityEvent({
344
- type: "xss_attempt",
345
- severity: "high",
346
- message: "XSS pattern detected in input",
347
- source: "input-validator",
348
- metadata: { context, pattern: pattern.source },
349
- });
350
- break;
351
- }
352
- }
353
- return input;
354
- }
355
- /**
356
- * Validate object input
357
- */
358
- validateObject(input, context, result) {
359
- const sanitized = {};
360
- // Depth check
361
- const depth = this.getObjectDepth(input);
362
- if (depth > SECURITY_CONFIG.inputValidation.maxObjectDepth) {
363
- result.isValid = false;
364
- result.errors.push(`Object depth exceeds maximum (${SECURITY_CONFIG.inputValidation.maxObjectDepth})`);
365
- return sanitized;
366
- }
367
- // Validate each property
368
- for (const [key, value] of Object.entries(input)) {
369
- if (typeof key === "string" && key.length > 0) {
370
- const keyValidation = this.validateInput(key, `${context}.key`);
371
- const valueValidation = this.validateInput(value, `${context}.${key}`);
372
- if (!keyValidation.isValid) {
373
- result.isValid = false;
374
- result.errors.push(...keyValidation.errors.map((e) => `Key '${key}': ${e}`));
375
- }
376
- if (!valueValidation.isValid) {
377
- result.isValid = false;
378
- result.errors.push(...valueValidation.errors.map((e) => `Property '${key}': ${e}`));
379
- }
380
- result.securityEvents.push(...keyValidation.securityEvents, ...valueValidation.securityEvents);
381
- sanitized[key] =
382
- valueValidation.sanitizedValue !== undefined
383
- ? valueValidation.sanitizedValue
384
- : value;
385
- }
386
- }
387
- return sanitized;
388
- }
389
- /**
390
- * Validate array input
391
- */
392
- validateArray(input, context, result) {
393
- const sanitized = [];
394
- // Length check
395
- if (input.length > SECURITY_CONFIG.inputValidation.maxArrayLength) {
396
- result.isValid = false;
397
- result.errors.push(`Array length exceeds maximum (${SECURITY_CONFIG.inputValidation.maxArrayLength})`);
398
- return sanitized;
399
- }
400
- // Validate each element
401
- for (let i = 0; i < input.length; i++) {
402
- const elementValidation = this.validateInput(input[i], `${context}[${i}]`);
403
- if (!elementValidation.isValid) {
404
- result.isValid = false;
405
- result.errors.push(...elementValidation.errors.map((e) => `Element ${i}: ${e}`));
406
- }
407
- result.securityEvents.push(...elementValidation.securityEvents);
408
- sanitized.push(elementValidation.sanitizedValue !== undefined
409
- ? elementValidation.sanitizedValue
410
- : input[i]);
411
- }
412
- return sanitized;
413
- }
414
- /**
415
- * Check for security patterns in input
416
- */
417
- checkSecurityPatterns(input, context, result) {
418
- const inputString = JSON.stringify(input);
419
- // Additional security checks can be added here
420
- // For example: path traversal, command injection, etc.
421
- }
422
- /**
423
- * Encrypt sensitive data using AES-256-GCM
424
- * SECURITY: Proper encryption with random IV and authentication tag (H-001 fix)
425
- *
426
- * @param data - Plaintext data to encrypt
427
- * @returns Base64-encoded string containing encrypted data + IV + auth tag
428
- */
429
- encryptData(data) {
430
- try {
431
- // Generate random IV (Initialization Vector) for each encryption
432
- const iv = crypto.randomBytes(SECURITY_CONFIG.encryption.ivLength);
433
- // Create cipher with AES-256-GCM
434
- const cipher = crypto.createCipheriv(SECURITY_CONFIG.encryption.algorithm, this.encryptionKey, iv);
435
- // Encrypt the data
436
- let encrypted = cipher.update(data, "utf8", "binary");
437
- encrypted += cipher.final("binary");
438
- // Get authentication tag (for integrity verification)
439
- const authTag = cipher.getAuthTag();
440
- // Combine: IV + encrypted data + auth tag (all in binary)
441
- const combined = Buffer.concat([
442
- iv,
443
- Buffer.from(encrypted, "binary"),
444
- authTag,
445
- ]);
446
- // Return as Base64 string for storage/transmission
447
- return combined.toString("base64");
448
- }
449
- catch (error) {
450
- frameworkLogger.log("security-hardening-system", "-security-data-encryption-failed-error-instanceof-", "error", {
451
- message: `[SECURITY] Data encryption failed: ${error instanceof Error ? error.message : String(error)}`,
452
- });
453
- throw new Error(`Encryption failed: ${error instanceof Error ? error.message : String(error)}`);
454
- }
455
- }
456
- /**
457
- * Decrypt sensitive data using AES-256-GCM
458
- * SECURITY: Proper decryption with IV and auth tag verification (H-001 fix)
459
- *
460
- * @param encryptedData - Base64-encoded string containing encrypted data + IV + auth tag
461
- * @returns Decrypted plaintext data
462
- * @throws Error if decryption fails or authentication tag doesn't match
463
- */
464
- decryptData(encryptedData) {
465
- try {
466
- const combined = Buffer.from(encryptedData, "base64");
467
- const iv = combined.subarray(0, SECURITY_CONFIG.encryption.ivLength);
468
- const authTag = combined.subarray(combined.length - 16);
469
- const encrypted = combined.subarray(SECURITY_CONFIG.encryption.ivLength, combined.length - 16);
470
- const decipher = crypto.createDecipheriv(SECURITY_CONFIG.encryption.algorithm, this.encryptionKey, iv);
471
- decipher.setAuthTag(authTag);
472
- const decrypted = Buffer.concat([
473
- decipher.update(encrypted),
474
- decipher.final(),
475
- ]).toString("utf8");
476
- return decrypted;
477
- }
478
- catch (error) {
479
- frameworkLogger.log("security-hardening-system", "decryption-failed", "warning", {
480
- message: `Data decryption failed (likely key mismatch from prior session): ${error instanceof Error ? error.message : String(error)}`,
481
- });
482
- return null;
483
- }
484
- }
485
- /**
486
- * Hash password securely with unique salt
487
- * SECURITY: Generates unique random salt for each password (H-003 fix)
488
- */
489
- async hashPassword(password) {
490
- return new Promise((resolve, reject) => {
491
- // Generate unique random salt for each password (prevents rainbow table attacks)
492
- const salt = crypto.randomBytes(32).toString("hex");
493
- crypto.scrypt(password, salt, SECURITY_CONFIG.encryption.keyLength, { N: 16384, r: 8, p: 1 }, (err, derivedKey) => {
494
- if (err)
495
- reject(err);
496
- else
497
- resolve({ hash: derivedKey.toString("hex"), salt });
498
- });
499
- });
500
- }
501
- /**
502
- * Verify password hash
503
- */
504
- async verifyPassword(password, hash, salt) {
505
- return new Promise((resolve, reject) => {
506
- crypto.scrypt(password, salt, SECURITY_CONFIG.encryption.keyLength, { N: 16384, r: 8, p: 1 }, (err, derivedKey) => {
507
- if (err) {
508
- resolve(false);
509
- }
510
- else {
511
- try {
512
- const isMatch = crypto.timingSafeEqual(Buffer.from(derivedKey.toString("hex"), "hex"), Buffer.from(hash, "hex"));
513
- resolve(isMatch);
514
- }
515
- catch (error) {
516
- resolve(false);
517
- }
518
- }
519
- });
520
- });
521
- }
522
- /**
523
- * Generate secure random token
524
- */
525
- generateSecureToken(length = 32) {
526
- return crypto.randomBytes(length).toString("hex");
527
- }
528
- /**
529
- * Log audit event
530
- */
531
- logAuditEvent(req, action) {
532
- if (!this.auditLogEnabled)
533
- return;
534
- const auditEvent = {
535
- timestamp: new Date().toISOString(),
536
- action,
537
- ip: this.getClientIP(req),
538
- userAgent: req.headers["user-agent"],
539
- method: req.method,
540
- url: req.url,
541
- headers: this.sanitizeHeadersForAudit(req.headers),
542
- };
543
- frameworkLogger.log("security-hardening-system", "-audit-json-stringify-auditevent-", "info", { message: `[AUDIT] ${JSON.stringify(auditEvent)}` });
544
- }
545
- /**
546
- * Sanitize headers for audit logging
547
- */
548
- sanitizeHeadersForAudit(headers) {
549
- const sanitized = { ...headers };
550
- SECURITY_CONFIG.audit.sensitiveFields.forEach((field) => {
551
- if (sanitized[field]) {
552
- sanitized[field] = "[REDACTED]";
553
- }
554
- });
555
- return sanitized;
556
- }
557
- /**
558
- * Emit security event
559
- */
560
- emitSecurityEvent(event) {
561
- const securityEvent = {
562
- id: this.generateSecureToken(16),
563
- timestamp: Date.now(),
564
- ...event,
565
- };
566
- this.securityEvents.push(securityEvent);
567
- this.emit("security-event", securityEvent);
568
- // Log high-severity events
569
- if (event.severity === "high" || event.severity === "critical") {
570
- frameworkLogger.log("security-hardening", "high-severity-event", "error", {
571
- severity: event.severity,
572
- message: event.message,
573
- type: event.type,
574
- source: event.source,
575
- ipAddress: event.ipAddress,
576
- });
577
- }
578
- }
579
- /**
580
- * Handle security events
581
- */
582
- handleSecurityEvent(event) {
583
- // Store event for analysis
584
- // In production, this would be sent to SIEM, logged to database, etc.
585
- if (event.severity === "critical") {
586
- // Immediate action required for critical events
587
- frameworkLogger.log("security-hardening", "critical-event", "error", {
588
- message: event.message,
589
- type: event.type,
590
- source: event.source,
591
- ipAddress: event.ipAddress,
592
- });
593
- // Could trigger alerts, notifications, etc.
594
- }
595
- }
596
- /**
597
- * Handle rate limit exceeded
598
- */
599
- handleRateLimitExceeded(event) {
600
- frameworkLogger.log("security-hardening", "rate-limit-exceeded", "warning", {
601
- ipAddress: event.ipAddress,
602
- message: event.message,
603
- });
604
- }
605
- /**
606
- * Handle validation failure
607
- */
608
- handleValidationFailure(event) {
609
- frameworkLogger.log("security-hardening", "input-validation-failed", "warning", {
610
- message: event.message,
611
- type: event.type,
612
- source: event.source,
613
- });
614
- }
615
- /**
616
- * Get client IP address
617
- */
618
- getClientIP(req) {
619
- const forwarded = req.headers["x-forwarded-for"];
620
- const realIP = req.headers["x-real-ip"];
621
- const clientIP = req.headers["x-client-ip"];
622
- return (forwarded?.split(",")[0]?.trim() ||
623
- realIP ||
624
- clientIP ||
625
- req.socket?.remoteAddress ||
626
- "unknown");
627
- }
628
- /**
629
- * Get rate limit info for IP
630
- */
631
- getRateLimitInfo(ip) {
632
- const entry = this.rateLimitStore.get(ip);
633
- if (!entry)
634
- return null;
635
- const maxRequests = SECURITY_CONFIG.rateLimiting.maxRequests;
636
- return {
637
- limit: maxRequests,
638
- remaining: Math.max(0, maxRequests - entry.count),
639
- resetTime: entry.resetTime,
640
- };
641
- }
642
- /**
643
- * Get object depth
644
- */
645
- getObjectDepth(obj, currentDepth = 0) {
646
- if (typeof obj !== "object" || obj === null) {
647
- return currentDepth;
648
- }
649
- let maxDepth = currentDepth;
650
- for (const value of Object.values(obj)) {
651
- if (typeof value === "object" && value !== null) {
652
- const depth = this.getObjectDepth(value, currentDepth + 1);
653
- maxDepth = Math.max(maxDepth, depth);
654
- }
655
- }
656
- return maxDepth;
657
- }
658
- /**
659
- * Cleanup old rate limit entries
660
- */
661
- cleanupRateLimitStore() {
662
- const now = Date.now();
663
- const entriesToDelete = [];
664
- this.rateLimitStore.forEach((entry, ip) => {
665
- if (now > entry.resetTime) {
666
- entriesToDelete.push(ip);
667
- }
668
- });
669
- entriesToDelete.forEach((ip) => this.rateLimitStore.delete(ip));
670
- }
671
- /**
672
- * Get security events
673
- */
674
- getSecurityEvents(limit = 100) {
675
- return this.securityEvents.slice(-limit);
676
- }
677
- /**
678
- * Clear security events
679
- */
680
- clearSecurityEvents() {
681
- this.securityEvents = [];
682
- }
683
- /**
684
- * Get security statistics
685
- */
686
- getSecurityStats() {
687
- const eventsByType = {
688
- input_validation_failure: 0,
689
- rate_limit_exceeded: 0,
690
- authentication_failure: 0,
691
- authorization_failure: 0,
692
- suspicious_activity: 0,
693
- sql_injection_attempt: 0,
694
- xss_attempt: 0,
695
- csrf_attempt: 0,
696
- security_header_missing: 0,
697
- encryption_failure: 0,
698
- audit_log_failure: 0,
699
- };
700
- const eventsBySeverity = {
701
- low: 0,
702
- medium: 0,
703
- high: 0,
704
- critical: 0,
705
- };
706
- this.securityEvents.forEach((event) => {
707
- eventsByType[event.type] = (eventsByType[event.type] || 0) + 1;
708
- eventsBySeverity[event.severity] =
709
- (eventsBySeverity[event.severity] || 0) + 1;
710
- });
711
- return {
712
- totalEvents: this.securityEvents.length,
713
- eventsByType,
714
- eventsBySeverity,
715
- recentEvents: this.securityEvents.slice(-10),
716
- };
717
- }
718
- /**
719
- * Enable/disable audit logging
720
- */
721
- setAuditLogging(enabled) {
722
- this.auditLogEnabled = enabled;
723
- }
724
- }
725
- // Export singleton instance
726
- export const securityHardeningSystem = new SecurityHardeningSystem();