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