xypriss 2.0.0 → 2.1.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 (185) hide show
  1. package/README.md +170 -380
  2. package/dist/cjs/mods/security/src/algorithms/hash-algorithms.js +10 -0
  3. package/dist/cjs/mods/security/src/algorithms/hash-algorithms.js.map +1 -1
  4. package/dist/cjs/mods/security/src/components/cache/cacheSys.utils.js +10 -0
  5. package/dist/cjs/mods/security/src/components/cache/cacheSys.utils.js.map +1 -1
  6. package/dist/cjs/mods/security/src/components/cache/index.js +10 -2
  7. package/dist/cjs/mods/security/src/components/cache/index.js.map +1 -1
  8. package/dist/cjs/mods/security/src/components/fortified-function/index.js +9 -0
  9. package/dist/cjs/mods/security/src/components/fortified-function/index.js.map +1 -1
  10. package/dist/cjs/mods/security/src/components/fortified-function/security/security-handler.js +10 -0
  11. package/dist/cjs/mods/security/src/components/fortified-function/security/security-handler.js.map +1 -1
  12. package/dist/cjs/mods/security/src/core/crypto.js +14 -0
  13. package/dist/cjs/mods/security/src/core/crypto.js.map +1 -1
  14. package/dist/cjs/mods/security/src/index.js +10 -1
  15. package/dist/cjs/mods/security/src/index.js.map +1 -1
  16. package/dist/cjs/shared/logger/Logger.js +372 -29
  17. package/dist/cjs/shared/logger/Logger.js.map +1 -1
  18. package/dist/cjs/src/cluster/bun-cluster-manager.js +91 -1
  19. package/dist/cjs/src/cluster/bun-cluster-manager.js.map +1 -1
  20. package/dist/cjs/src/cluster/cluster-manager.js +15 -3
  21. package/dist/cjs/src/cluster/cluster-manager.js.map +1 -1
  22. package/dist/cjs/src/cluster/modules/AutoScaler.js +4 -4
  23. package/dist/cjs/src/cluster/modules/AutoScaler.js.map +1 -1
  24. package/dist/cjs/src/cluster/modules/CrossPlatformMemory.js +2 -2
  25. package/dist/cjs/src/cluster/modules/CrossPlatformMemory.js.map +1 -1
  26. package/dist/cjs/src/cluster/modules/EventLoopMonitor.js +270 -0
  27. package/dist/cjs/src/cluster/modules/EventLoopMonitor.js.map +1 -0
  28. package/dist/cjs/src/cluster/modules/GCStatsTracker.js +200 -0
  29. package/dist/cjs/src/cluster/modules/GCStatsTracker.js.map +1 -0
  30. package/dist/cjs/src/cluster/modules/HeapStatsCollector.js +111 -0
  31. package/dist/cjs/src/cluster/modules/HeapStatsCollector.js.map +1 -0
  32. package/dist/cjs/src/cluster/modules/NetworkTracker.js +162 -0
  33. package/dist/cjs/src/cluster/modules/NetworkTracker.js.map +1 -0
  34. package/dist/cjs/src/cluster/modules/ThroughputCalculator.js +186 -0
  35. package/dist/cjs/src/cluster/modules/ThroughputCalculator.js.map +1 -0
  36. package/dist/cjs/src/cluster/modules/WorkerManager.js +14 -15
  37. package/dist/cjs/src/cluster/modules/WorkerManager.js.map +1 -1
  38. package/dist/cjs/src/cluster/modules/{LoadBalancer.js → strategy/LoadBalancer.js} +1 -1
  39. package/dist/cjs/src/cluster/modules/strategy/LoadBalancer.js.map +1 -0
  40. package/dist/cjs/src/middleware/built-in/sqlInjection.js +335 -0
  41. package/dist/cjs/src/middleware/built-in/sqlInjection.js.map +1 -0
  42. package/dist/cjs/src/middleware/safe-json-middleware.js +1 -1
  43. package/dist/cjs/src/middleware/safe-json-middleware.js.map +1 -1
  44. package/dist/cjs/src/middleware/security-middleware.js +447 -332
  45. package/dist/cjs/src/middleware/security-middleware.js.map +1 -1
  46. package/dist/cjs/src/plugins/modules/index.js +9 -3
  47. package/dist/cjs/src/plugins/modules/index.js.map +1 -1
  48. package/dist/cjs/src/server/FastServer.js +41 -1
  49. package/dist/cjs/src/server/FastServer.js.map +1 -1
  50. package/dist/cjs/src/server/ServerFactory.js +62 -2
  51. package/dist/cjs/src/server/ServerFactory.js.map +1 -1
  52. package/dist/cjs/src/server/components/fastapi/ClusterManagerComponent.js +32 -6
  53. package/dist/cjs/src/server/components/fastapi/ClusterManagerComponent.js.map +1 -1
  54. package/dist/cjs/src/server/components/fastapi/WorkerPoolComponent.js +206 -0
  55. package/dist/cjs/src/server/components/fastapi/WorkerPoolComponent.js.map +1 -0
  56. package/dist/cjs/src/server/components/fastapi/console/ConsoleInterceptor.js +3 -28
  57. package/dist/cjs/src/server/components/fastapi/console/ConsoleInterceptor.js.map +1 -1
  58. package/dist/cjs/src/server/components/fastapi/modules/UFRP/WorkerPoolManager.js +265 -0
  59. package/dist/cjs/src/server/components/fastapi/modules/UFRP/WorkerPoolManager.js.map +1 -0
  60. package/dist/cjs/src/server/components/fastapi/modules/UFRP/workers/Logger.js +236 -0
  61. package/dist/cjs/src/server/components/fastapi/modules/UFRP/workers/cpu-tasks.js +294 -0
  62. package/dist/cjs/src/server/components/fastapi/modules/UFRP/workers/enhanced-cpu-worker.js +433 -0
  63. package/dist/cjs/src/server/components/fastapi/modules/UFRP/workers/io-worker.js +1615 -0
  64. package/dist/cjs/src/server/components/lifecycle/ServerLifecycleManager.js +143 -24
  65. package/dist/cjs/src/server/components/lifecycle/ServerLifecycleManager.js.map +1 -1
  66. package/dist/cjs/src/server/const/default.js +23 -9
  67. package/dist/cjs/src/server/const/default.js.map +1 -1
  68. package/dist/cjs/src/server/core/HttpServer.js +8 -8
  69. package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
  70. package/dist/cjs/src/server/core/XyprissApp.js +284 -17
  71. package/dist/cjs/src/server/core/XyprissApp.js.map +1 -1
  72. package/dist/cjs/src/server/handlers/NotFoundHandler.js +1 -1
  73. package/dist/cjs/src/server/handlers/NotFoundHandler.js.map +1 -1
  74. package/dist/cjs/src/server/middleware/MiddlewareManager.js +57 -12
  75. package/dist/cjs/src/server/middleware/MiddlewareManager.js.map +1 -1
  76. package/dist/cjs/src/server/utils/forceClosePort.js +1 -1
  77. package/dist/cjs/src/server/utils/forceClosePort.js.map +1 -1
  78. package/dist/esm/mods/security/src/algorithms/hash-algorithms.js +10 -0
  79. package/dist/esm/mods/security/src/algorithms/hash-algorithms.js.map +1 -1
  80. package/dist/esm/mods/security/src/components/cache/cacheSys.utils.js +10 -0
  81. package/dist/esm/mods/security/src/components/cache/cacheSys.utils.js.map +1 -1
  82. package/dist/esm/mods/security/src/components/cache/index.js +10 -2
  83. package/dist/esm/mods/security/src/components/cache/index.js.map +1 -1
  84. package/dist/esm/mods/security/src/components/fortified-function/index.js +9 -0
  85. package/dist/esm/mods/security/src/components/fortified-function/index.js.map +1 -1
  86. package/dist/esm/mods/security/src/components/fortified-function/security/security-handler.js +10 -0
  87. package/dist/esm/mods/security/src/components/fortified-function/security/security-handler.js.map +1 -1
  88. package/dist/esm/mods/security/src/core/crypto.js +14 -0
  89. package/dist/esm/mods/security/src/core/crypto.js.map +1 -1
  90. package/dist/esm/mods/security/src/index.js +10 -1
  91. package/dist/esm/mods/security/src/index.js.map +1 -1
  92. package/dist/esm/shared/logger/Logger.js +372 -29
  93. package/dist/esm/shared/logger/Logger.js.map +1 -1
  94. package/dist/esm/src/cluster/bun-cluster-manager.js +91 -1
  95. package/dist/esm/src/cluster/bun-cluster-manager.js.map +1 -1
  96. package/dist/esm/src/cluster/cluster-manager.js +15 -3
  97. package/dist/esm/src/cluster/cluster-manager.js.map +1 -1
  98. package/dist/esm/src/cluster/modules/AutoScaler.js +4 -4
  99. package/dist/esm/src/cluster/modules/AutoScaler.js.map +1 -1
  100. package/dist/esm/src/cluster/modules/CrossPlatformMemory.js +2 -2
  101. package/dist/esm/src/cluster/modules/CrossPlatformMemory.js.map +1 -1
  102. package/dist/esm/src/cluster/modules/EventLoopMonitor.js +268 -0
  103. package/dist/esm/src/cluster/modules/EventLoopMonitor.js.map +1 -0
  104. package/dist/esm/src/cluster/modules/GCStatsTracker.js +198 -0
  105. package/dist/esm/src/cluster/modules/GCStatsTracker.js.map +1 -0
  106. package/dist/esm/src/cluster/modules/HeapStatsCollector.js +109 -0
  107. package/dist/esm/src/cluster/modules/HeapStatsCollector.js.map +1 -0
  108. package/dist/esm/src/cluster/modules/NetworkTracker.js +160 -0
  109. package/dist/esm/src/cluster/modules/NetworkTracker.js.map +1 -0
  110. package/dist/esm/src/cluster/modules/ThroughputCalculator.js +184 -0
  111. package/dist/esm/src/cluster/modules/ThroughputCalculator.js.map +1 -0
  112. package/dist/esm/src/cluster/modules/WorkerManager.js +14 -14
  113. package/dist/esm/src/cluster/modules/WorkerManager.js.map +1 -1
  114. package/dist/esm/src/cluster/modules/{LoadBalancer.js → strategy/LoadBalancer.js} +1 -1
  115. package/dist/esm/src/cluster/modules/strategy/LoadBalancer.js.map +1 -0
  116. package/dist/esm/src/middleware/built-in/sqlInjection.js +333 -0
  117. package/dist/esm/src/middleware/built-in/sqlInjection.js.map +1 -0
  118. package/dist/esm/src/middleware/safe-json-middleware.js +1 -1
  119. package/dist/esm/src/middleware/safe-json-middleware.js.map +1 -1
  120. package/dist/esm/src/middleware/security-middleware.js +447 -332
  121. package/dist/esm/src/middleware/security-middleware.js.map +1 -1
  122. package/dist/esm/src/plugins/modules/index.js +9 -3
  123. package/dist/esm/src/plugins/modules/index.js.map +1 -1
  124. package/dist/esm/src/server/FastServer.js +41 -1
  125. package/dist/esm/src/server/FastServer.js.map +1 -1
  126. package/dist/esm/src/server/ServerFactory.js +62 -2
  127. package/dist/esm/src/server/ServerFactory.js.map +1 -1
  128. package/dist/esm/src/server/components/fastapi/ClusterManagerComponent.js +32 -6
  129. package/dist/esm/src/server/components/fastapi/ClusterManagerComponent.js.map +1 -1
  130. package/dist/esm/src/server/components/fastapi/WorkerPoolComponent.js +204 -0
  131. package/dist/esm/src/server/components/fastapi/WorkerPoolComponent.js.map +1 -0
  132. package/dist/esm/src/server/components/fastapi/console/ConsoleInterceptor.js +2 -27
  133. package/dist/esm/src/server/components/fastapi/console/ConsoleInterceptor.js.map +1 -1
  134. package/dist/esm/src/server/components/fastapi/modules/UFRP/WorkerPoolManager.js +263 -0
  135. package/dist/esm/src/server/components/fastapi/modules/UFRP/WorkerPoolManager.js.map +1 -0
  136. package/dist/esm/src/server/components/fastapi/modules/UFRP/workers/Logger.js +236 -0
  137. package/dist/esm/src/server/components/fastapi/modules/UFRP/workers/cpu-tasks.js +294 -0
  138. package/dist/esm/src/server/components/fastapi/modules/UFRP/workers/enhanced-cpu-worker.js +433 -0
  139. package/dist/esm/src/server/components/fastapi/modules/UFRP/workers/io-worker.js +1615 -0
  140. package/dist/esm/src/server/components/lifecycle/ServerLifecycleManager.js +143 -24
  141. package/dist/esm/src/server/components/lifecycle/ServerLifecycleManager.js.map +1 -1
  142. package/dist/esm/src/server/const/default.js +23 -9
  143. package/dist/esm/src/server/const/default.js.map +1 -1
  144. package/dist/esm/src/server/core/HttpServer.js +8 -8
  145. package/dist/esm/src/server/core/HttpServer.js.map +1 -1
  146. package/dist/esm/src/server/core/XyprissApp.js +284 -17
  147. package/dist/esm/src/server/core/XyprissApp.js.map +1 -1
  148. package/dist/esm/src/server/handlers/NotFoundHandler.js +1 -1
  149. package/dist/esm/src/server/handlers/NotFoundHandler.js.map +1 -1
  150. package/dist/esm/src/server/middleware/MiddlewareManager.js +57 -12
  151. package/dist/esm/src/server/middleware/MiddlewareManager.js.map +1 -1
  152. package/dist/esm/src/server/utils/forceClosePort.js +1 -1
  153. package/dist/esm/src/server/utils/forceClosePort.js.map +1 -1
  154. package/dist/index.d.ts +675 -516
  155. package/package.json +10 -11
  156. package/dist/cjs/src/cluster/index.js +0 -361
  157. package/dist/cjs/src/cluster/index.js.map +0 -1
  158. package/dist/cjs/src/cluster/modules/ClusterFactory.js +0 -539
  159. package/dist/cjs/src/cluster/modules/ClusterFactory.js.map +0 -1
  160. package/dist/cjs/src/cluster/modules/LoadBalancer.js.map +0 -1
  161. package/dist/cjs/src/server/components/fastapi/UltraFastRequestProcessor.js +0 -668
  162. package/dist/cjs/src/server/components/fastapi/UltraFastRequestProcessor.js.map +0 -1
  163. package/dist/cjs/src/server/components/fastapi/middlewares/MiddlewareAPI.js +0 -347
  164. package/dist/cjs/src/server/components/fastapi/middlewares/MiddlewareAPI.js.map +0 -1
  165. package/dist/cjs/src/server/components/fastapi/middlewares/MiddlewareMethodsManager.js +0 -204
  166. package/dist/cjs/src/server/components/fastapi/middlewares/MiddlewareMethodsManager.js.map +0 -1
  167. package/dist/cjs/src/server/components/fastapi/middlewares/middlewareManager.js +0 -953
  168. package/dist/cjs/src/server/components/fastapi/middlewares/middlewareManager.js.map +0 -1
  169. package/dist/cjs/src/server/components/fastapi/modules/UFRP/WorkerPool.js +0 -56
  170. package/dist/cjs/src/server/components/fastapi/modules/UFRP/WorkerPool.js.map +0 -1
  171. package/dist/esm/src/cluster/index.js +0 -339
  172. package/dist/esm/src/cluster/index.js.map +0 -1
  173. package/dist/esm/src/cluster/modules/ClusterFactory.js +0 -511
  174. package/dist/esm/src/cluster/modules/ClusterFactory.js.map +0 -1
  175. package/dist/esm/src/cluster/modules/LoadBalancer.js.map +0 -1
  176. package/dist/esm/src/server/components/fastapi/UltraFastRequestProcessor.js +0 -647
  177. package/dist/esm/src/server/components/fastapi/UltraFastRequestProcessor.js.map +0 -1
  178. package/dist/esm/src/server/components/fastapi/middlewares/MiddlewareAPI.js +0 -345
  179. package/dist/esm/src/server/components/fastapi/middlewares/MiddlewareAPI.js.map +0 -1
  180. package/dist/esm/src/server/components/fastapi/middlewares/MiddlewareMethodsManager.js +0 -202
  181. package/dist/esm/src/server/components/fastapi/middlewares/MiddlewareMethodsManager.js.map +0 -1
  182. package/dist/esm/src/server/components/fastapi/middlewares/middlewareManager.js +0 -951
  183. package/dist/esm/src/server/components/fastapi/middlewares/middlewareManager.js.map +0 -1
  184. package/dist/esm/src/server/components/fastapi/modules/UFRP/WorkerPool.js +0 -54
  185. package/dist/esm/src/server/components/fastapi/modules/UFRP/WorkerPool.js.map +0 -1
@@ -1,413 +1,528 @@
1
1
  'use strict';
2
2
 
3
- var crypto = require('../../mods/security/src/core/crypto.js');
4
- var secureObjectCore = require('../../mods/security/src/components/secure-object/core/secure-object-core.js');
5
- require('../../mods/security/src/core/hash/hash-core.js');
6
- require('../../mods/security/src/core/hash/hash-types.js');
7
- require('crypto');
8
- require('../../mods/security/src/core/hash/hash-security.js');
9
- require('../../mods/security/src/core/hash/hash-advanced.js');
10
- require('../../mods/security/src/algorithms/hash-algorithms.js');
11
- require('../../mods/security/src/core/random/random-types.js');
12
- require('../../mods/security/src/core/random/random-sources.js');
13
- require('nehonix-uri-processor');
14
- require('../../mods/security/src/utils/memory/index.js');
15
- require('../../mods/security/src/types.js');
16
- require('../../mods/security/src/types/secure-memory.js');
17
- require('../../mods/security/src/components/secure-string/advanced/entropy-analyzer.js');
18
- require('../../mods/security/src/components/secure-string/advanced/quantum-safe.js');
19
- require('../../mods/security/src/components/secure-string/advanced/performance-monitor.js');
20
- require('nehoid');
3
+ var helmet = require('helmet');
4
+ var cors = require('cors');
5
+ var rateLimit = require('express-rate-limit');
6
+ var csrfCsrf = require('csrf-csrf');
7
+ var mongoSanitize = require('express-mongo-sanitize');
8
+ var xss = require('xss');
9
+ var hpp = require('hpp');
10
+ var compression = require('compression');
11
+ var xyprissSecurity = require('xypriss-security');
12
+ var sqlInjection = require('./built-in/sqlInjection.js');
13
+ var Logger = require('../../shared/logger/Logger.js');
21
14
 
22
15
  /**
23
- * XyPrissJS Security Middleware
24
- * Military-grade security middleware for Express applications
16
+ * XyPriss Security Middleware
17
+ * Comprehensive security middleware using proven external libraries
18
+ */
19
+ /**
20
+ * Security middleware class implementing comprehensive protection
21
+ * Implements SecurityConfig interface to ensure type safety
25
22
  */
26
23
  class SecurityMiddleware {
27
- constructor(config = {}) {
28
- this.bruteForceMap = new Map();
29
- this.config = {
30
- level: "enhanced",
31
- csrf: true,
32
- helmet: true,
33
- xss: true,
34
- sqlInjection: true,
35
- bruteForce: true,
36
- encryption: {
37
- algorithm: "AES-256-GCM",
38
- keySize: 32,
39
- },
40
- authentication: {
41
- jwt: {
42
- secret: crypto.XyPrissSecurity.generateSecureToken({
24
+ constructor(config = {}, logger) {
25
+ // Initialize logger (create default if not provided)
26
+ this.logger =
27
+ logger ||
28
+ new Logger.Logger({
29
+ enabled: true,
30
+ level: "debug",
31
+ components: { security: true },
32
+ types: { debug: true },
33
+ });
34
+ // Set defaults and merge with provided config
35
+ this.level = config.level || "enhanced";
36
+ this.csrf = config.csrf !== false;
37
+ this.helmet = config.helmet !== false;
38
+ this.xss = config.xss !== false;
39
+ this.sqlInjection = config.sqlInjection !== false;
40
+ this.bruteForce = config.bruteForce !== false;
41
+ this.encryption = {
42
+ algorithm: "AES-256-GCM",
43
+ keySize: 32,
44
+ ...config.encryption,
45
+ };
46
+ this.authentication = {
47
+ jwt: {
48
+ secret: config.authentication?.jwt?.secret ||
49
+ xyprissSecurity.XyPrissSecurity.generateSecureToken({
43
50
  length: 32,
44
51
  entropy: "high",
45
52
  }),
46
- expiresIn: "1h",
47
- algorithm: "HS256",
48
- },
49
- session: {
50
- secret: crypto.XyPrissSecurity.generateSecureToken({
53
+ expiresIn: config.authentication?.jwt?.expiresIn || "1h",
54
+ algorithm: config.authentication?.jwt?.algorithm || "HS256",
55
+ },
56
+ session: {
57
+ secret: config.authentication?.session?.secret ||
58
+ xyprissSecurity.XyPrissSecurity.generateSecureToken({
51
59
  length: 32,
52
60
  entropy: "high",
53
61
  }),
54
- name: "XyPriss.sid",
55
- cookie: {
56
- maxAge: 24 * 60 * 60 * 1000, // 24 hours
57
- secure: true,
58
- httpOnly: true,
59
- sameSite: "strict",
60
- },
62
+ name: config.authentication?.session?.name ||
63
+ "nehonix.XyPriss.sid",
64
+ cookie: {
65
+ maxAge: 24 * 60 * 60 * 1000, // 24 hours
66
+ secure: true,
67
+ httpOnly: true,
68
+ sameSite: "strict",
69
+ ...config.authentication?.session?.cookie,
61
70
  },
62
71
  },
63
- ...config,
64
- };
65
- }
66
- /**
67
- * Get the main security middleware
68
- */
69
- getMiddleware() {
70
- return (req, res, next) => {
71
- // Apply security measures based on level
72
- this.applySecurityHeaders(req, res);
73
- this.checkBruteForce(req, res, next);
72
+ ...config.authentication,
74
73
  };
74
+ // Initialize security detectors
75
+ this.sqlInjectionDetector = new sqlInjection({
76
+ strictMode: false,
77
+ contextualAnalysis: true,
78
+ logAttempts: true,
79
+ falsePositiveThreshold: 0.6,
80
+ });
81
+ // Initialize all middleware instances
82
+ this.initializeMiddleware();
75
83
  }
76
84
  /**
77
- * Apply security headers
85
+ * Initialize all security middleware instances using external libraries
78
86
  */
79
- applySecurityHeaders(req, res) {
80
- if (this.config.helmet) {
81
- // Security headers (helmet.js equivalent)
82
- res.set({
83
- "X-Content-Type-Options": "nosniff",
84
- "X-Frame-Options": "DENY",
85
- "X-XSS-Protection": "1; mode=block",
86
- "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
87
- "Referrer-Policy": "strict-origin-when-cross-origin",
88
- "Permissions-Policy": "geolocation=(), microphone=(), camera=()",
89
- "Content-Security-Policy": this.getCSPHeader(),
87
+ initializeMiddleware() {
88
+ // Helmet for security headers
89
+ if (this.helmet) {
90
+ this.helmetMiddleware = helmet({
91
+ contentSecurityPolicy: this.level === "maximum"
92
+ ? {
93
+ directives: {
94
+ defaultSrc: ["'self'"],
95
+ styleSrc: ["'self'", "'unsafe-inline'"],
96
+ scriptSrc: ["'self'"],
97
+ imgSrc: ["'self'", "data:", "https:"],
98
+ },
99
+ }
100
+ : false,
101
+ hsts: this.level !== "basic",
102
+ crossOriginEmbedderPolicy: this.level === "maximum",
90
103
  });
91
104
  }
92
- // Remove server information
93
- res.removeHeader("X-Powered-By");
94
- res.set("Server", "XyPrissJS");
95
- }
96
- /**
97
- * Get Content Security Policy header
98
- */
99
- getCSPHeader() {
100
- switch (this.config.level) {
101
- case "maximum":
102
- return "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';";
103
- case "enhanced":
104
- return "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self';";
105
- case "basic":
106
- default:
107
- return "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';";
108
- }
109
- }
110
- /**
111
- * Check for brute force attacks
112
- */
113
- checkBruteForce(req, res, next) {
114
- if (!this.config.bruteForce) {
115
- return next();
116
- }
117
- const ip = this.getClientIP(req);
118
- const now = Date.now();
119
- const maxAttempts = 10;
120
- const windowMs = 15 * 60 * 1000; // 15 minutes
121
- const blockDuration = 60 * 60 * 1000; // 1 hour
122
- let record = this.bruteForceMap.get(ip);
123
- if (!record) {
124
- record = { attempts: 0, lastAttempt: now };
125
- this.bruteForceMap.set(ip, record);
105
+ // CORS middleware
106
+ this.corsMiddleware = cors({
107
+ origin: this.level === "maximum" ? false : true,
108
+ credentials: true,
109
+ optionsSuccessStatus: 200,
110
+ });
111
+ // Rate limiting for brute force protection
112
+ if (this.bruteForce) {
113
+ const maxRequests = this.level === "maximum"
114
+ ? 50
115
+ : this.level === "enhanced"
116
+ ? 100
117
+ : 200;
118
+ this.rateLimitMiddleware = rateLimit({
119
+ windowMs: 15 * 60 * 1000, // 15 minutes
120
+ max: maxRequests,
121
+ message: {
122
+ error: "Too many requests from this IP, please try again later.",
123
+ retryAfter: "15 minutes",
124
+ },
125
+ standardHeaders: true,
126
+ legacyHeaders: false,
127
+ skip: (req) => {
128
+ // Skip rate limiting for health checks
129
+ return req.path === "/health" || req.path === "/ping";
130
+ },
131
+ });
126
132
  }
127
- // Check if IP is currently blocked
128
- if (record.blockedUntil && record.blockedUntil > now) {
129
- return res.status(429).json({
130
- error: "IP temporarily blocked due to suspicious activity",
131
- retryAfter: Math.ceil((record.blockedUntil - now) / 1000),
133
+ // CSRF protection using csrf-csrf library
134
+ if (this.csrf) {
135
+ const { doubleCsrfProtection } = csrfCsrf.doubleCsrf({
136
+ getSecret: () => this.authentication.session?.secret || "default-secret",
137
+ getSessionIdentifier: (req) => req.sessionID || req.ip || "anonymous",
138
+ cookieName: "__Host-csrf-token",
139
+ cookieOptions: {
140
+ httpOnly: true,
141
+ sameSite: "strict",
142
+ secure: process.env.NODE_ENV === "production",
143
+ maxAge: 24 * 60 * 60 * 1000, // 24 hours
144
+ },
145
+ size: 64,
146
+ ignoredMethods: ["GET", "HEAD", "OPTIONS"],
132
147
  });
148
+ // Create a wrapper that ensures cookies exist
149
+ this.csrfMiddleware = (req, res, next) => {
150
+ // Ensure cookies object exists for Express compatibility
151
+ if (!req.cookies) {
152
+ req.cookies = {};
153
+ }
154
+ // Call the original CSRF middleware
155
+ doubleCsrfProtection(req, res, next);
156
+ };
133
157
  }
134
- // Reset attempts if window has passed
135
- if (now - record.lastAttempt > windowMs) {
136
- record.attempts = 0;
158
+ // MongoDB injection protection
159
+ if (this.sqlInjection) {
160
+ const originalMongoSanitize = mongoSanitize({
161
+ replaceWith: "_",
162
+ onSanitize: ({ req, key }) => {
163
+ console.warn(`Sanitized key ${key} in request from ${req.ip}`);
164
+ },
165
+ });
166
+ // Create a wrapper that handles readonly properties
167
+ this.mongoSanitizeMiddleware = (req, res, next) => {
168
+ // Make request properties writable before sanitization
169
+ this.makeRequestPropertiesWritable(req);
170
+ // Call the original middleware
171
+ originalMongoSanitize(req, res, next);
172
+ };
137
173
  }
138
- // Check for failed authentication on this request
139
- res.on("finish", () => {
140
- if (res.statusCode === 401 || res.statusCode === 403) {
141
- record.attempts++;
142
- record.lastAttempt = now;
143
- if (record.attempts >= maxAttempts) {
144
- record.blockedUntil = now + blockDuration;
145
- console.warn(`IP ${ip} blocked for ${blockDuration / 1000}s after ${maxAttempts} failed attempts`);
174
+ // HTTP Parameter Pollution protection
175
+ const originalHpp = hpp({
176
+ whitelist: ["tags", "categories"], // Allow arrays for specific parameters
177
+ });
178
+ // Create a wrapper that handles readonly properties
179
+ this.hppMiddleware = (req, res, next) => {
180
+ // Make request properties writable before processing
181
+ this.makeRequestPropertiesWritable(req);
182
+ // Call the original middleware
183
+ originalHpp(req, res, next);
184
+ };
185
+ // Compression middleware
186
+ this.compressionMiddleware = compression({
187
+ filter: (req, res) => {
188
+ if (req.headers["x-no-compression"]) {
189
+ return false;
146
190
  }
147
- }
191
+ return compression.filter(req, res);
192
+ },
193
+ level: 6,
194
+ threshold: 1024,
148
195
  });
149
- next();
150
196
  }
151
197
  /**
152
- * Detect obfuscated SQL injection attempts using entropy analysis
198
+ * Get the main security middleware stack
199
+ * Returns a single middleware function that applies all security measures
153
200
  */
154
- detectObfuscatedSQLInjection(input) {
155
- // Check for excessive URL encoding
156
- const urlEncodedCount = (input.match(/%[0-9a-f]{2}/gi) || []).length;
157
- if (urlEncodedCount > input.length * 0.3) {
158
- return true;
159
- }
160
- // Check for excessive hex encoding
161
- const hexCount = (input.match(/\\x[0-9a-f]{2}/gi) || []).length;
162
- if (hexCount > 3) {
163
- return true;
164
- }
165
- // Check for suspicious character sequences
166
- const suspiciousPatterns = [
167
- /(\+|\s)(and|or)(\+|\s)/gi,
168
- /[0-9]+\s*[=<>]\s*[0-9]+/gi,
169
- /(char|ascii)\s*\(\s*[0-9]+/gi,
170
- /concat\s*\(/gi,
171
- ];
172
- return suspiciousPatterns.some((pattern) => pattern.test(input));
201
+ getMiddleware() {
202
+ return (req, res, next) => {
203
+ this.applySecurityStack(req, res, next);
204
+ };
173
205
  }
174
206
  /**
175
- * Get client IP address
207
+ * Apply all security middleware in the correct order
176
208
  */
177
- getClientIP(req) {
178
- return (req.headers["x-forwarded-for"]?.split(",")[0] ||
179
- req.headers["x-real-ip"] ||
180
- req.connection?.remoteAddress ||
181
- req.socket?.remoteAddress ||
182
- req.ip ||
183
- "unknown");
209
+ applySecurityStack(req, res, next) {
210
+ this.logger.debug("security", "Starting security middleware stack");
211
+ const middlewareStack = [];
212
+ // 1. Compression (should be first)
213
+ this.logger.debug("security", "Adding compression middleware");
214
+ middlewareStack.push(this.compressionMiddleware);
215
+ // 2. Security headers (Helmet)
216
+ if (this.helmet && this.helmetMiddleware) {
217
+ this.logger.debug("security", "Adding helmet middleware");
218
+ middlewareStack.push(this.helmetMiddleware);
219
+ }
220
+ // 3. CORS
221
+ this.logger.debug("security", "Adding CORS middleware");
222
+ middlewareStack.push(this.corsMiddleware);
223
+ // 4. Rate limiting
224
+ if (this.bruteForce && this.rateLimitMiddleware) {
225
+ this.logger.debug("security", "Adding rate limit middleware");
226
+ middlewareStack.push(this.rateLimitMiddleware);
227
+ }
228
+ // 5. HTTP Parameter Pollution protection
229
+ this.logger.debug("security", "Adding HPP middleware");
230
+ middlewareStack.push(this.hppMiddleware);
231
+ // 6. MongoDB sanitization
232
+ if (this.sqlInjection && this.mongoSanitizeMiddleware) {
233
+ this.logger.debug("security", "Adding mongo sanitize middleware");
234
+ middlewareStack.push(this.mongoSanitizeMiddleware);
235
+ }
236
+ // 7. XSS protection (custom implementation)
237
+ if (this.xss) {
238
+ this.logger.debug("security", "Adding XSS protection middleware");
239
+ middlewareStack.push(this.xssProtection.bind(this));
240
+ }
241
+ // 8. CSRF protection (should be after body parsing)
242
+ if (this.csrf && this.csrfMiddleware) {
243
+ this.logger.debug("security", "Adding CSRF middleware");
244
+ middlewareStack.push(this.csrfMiddleware);
245
+ }
246
+ this.logger.debug("security", `Total middleware in stack: ${middlewareStack.length}`);
247
+ // Execute middleware stack
248
+ this.executeMiddlewareStack(middlewareStack, req, res, next);
184
249
  }
185
250
  /**
186
- * XSS Protection middleware
251
+ * Execute middleware stack sequentially with proper async handling
187
252
  */
188
- xssProtection() {
189
- return (req, res, next) => {
190
- if (!this.config.xss) {
191
- return next();
253
+ executeMiddlewareStack(stack, req, res, finalNext) {
254
+ let index = 0;
255
+ let nextCalled = false;
256
+ this.logger.debug("security", `Executing middleware stack with ${stack.length} middleware`);
257
+ const next = (error) => {
258
+ if (nextCalled) {
259
+ this.logger.debug("security", "next() already called, ignoring duplicate call");
260
+ return;
192
261
  }
193
- // Sanitize input
194
- this.sanitizeObject(req.body);
195
- this.sanitizeObject(req.query);
196
- this.sanitizeObject(req.params);
197
- next();
198
- };
199
- }
200
- /**
201
- * SQL Injection protection middleware
202
- */
203
- sqlInjectionProtection() {
204
- return (req, res, next) => {
205
- if (!this.config.sqlInjection) {
206
- return next();
262
+ if (error) {
263
+ nextCalled = true;
264
+ this.logger.debug("security", `Error in middleware at index ${index - 1}:`, error);
265
+ return finalNext(error);
207
266
  }
208
- // SQL injection patterns with comprehensive coverage
209
- const sqlPatterns = [
210
- // SQL keywords
211
- /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC|UNION|SCRIPT|TRUNCATE|GRANT|REVOKE)\b)/gi,
212
- // SQL injection characters and sequences
213
- /(--|\/\*|\*\/|;|'|"|`|\||&|\+|%|<|>|=|\(|\))/g,
214
- // Boolean-based injection patterns
215
- /(\b(OR|AND)\b\s*['"]*\s*[0-9]+\s*['"]*\s*[=<>])/gi,
216
- // Union-based injection
217
- /(\bUNION\b.*\bSELECT\b)/gi,
218
- // Time-based injection
219
- /(\b(SLEEP|WAITFOR|DELAY)\b\s*\()/gi,
220
- // Error-based injection
221
- /(\b(CAST|CONVERT|EXTRACTVALUE|UPDATEXML)\b.*\()/gi,
222
- // Hex encoding attempts
223
- /(0x[0-9a-f]+)/gi,
224
- // SQL functions commonly used in attacks
225
- /(\b(CHAR|ASCII|SUBSTRING|CONCAT|VERSION|DATABASE|USER|SCHEMA)\b\s*\()/gi,
226
- ];
227
- const validateSQLInput = (obj, path = "") => {
228
- if (typeof obj === "string") {
229
- // Use XyPrissJS pattern matching for enhanced detection
230
- const normalizedInput = obj
231
- .toLowerCase()
232
- .replace(/\s+/g, " ")
233
- .trim();
234
- // Check against SQL injection patterns
235
- for (const pattern of sqlPatterns) {
236
- if (pattern.test(normalizedInput)) {
237
- console.warn(` SQL injection pattern detected in ${path}: ${pattern.source}`);
238
- return true;
239
- }
240
- }
241
- // Additional entropy-based detection for obfuscated attacks
242
- if (this.detectObfuscatedSQLInjection(normalizedInput)) {
243
- console.warn(` Obfuscated SQL injection detected in ${path}`);
244
- return true;
267
+ if (index >= stack.length) {
268
+ nextCalled = true;
269
+ this.logger.debug("security", "All middleware completed, calling final next");
270
+ return finalNext();
271
+ }
272
+ const currentIndex = index;
273
+ this.logger.debug("security", `Executing middleware ${currentIndex + 1}/${stack.length}`);
274
+ const middleware = stack[index++];
275
+ try {
276
+ // Set a timeout to detect if middleware doesn't call next()
277
+ let timeoutId = null;
278
+ let middlewareCompleted = false;
279
+ const middlewareNext = (err) => {
280
+ if (middlewareCompleted)
281
+ return;
282
+ middlewareCompleted = true;
283
+ if (timeoutId) {
284
+ clearTimeout(timeoutId);
245
285
  }
246
- return false;
247
- }
248
- if (typeof obj === "object" && obj !== null) {
249
- for (const [key, value] of Object.entries(obj)) {
250
- if (validateSQLInput(value, `${path}.${key}`)) {
251
- return true;
252
- }
286
+ this.logger.debug("security", `Middleware ${currentIndex + 1} completed`);
287
+ next(err);
288
+ };
289
+ // Set timeout to detect hanging middleware
290
+ timeoutId = setTimeout(() => {
291
+ if (!middlewareCompleted) {
292
+ this.logger.debug("security", `Middleware ${currentIndex + 1} timed out, continuing anyway`);
293
+ middlewareCompleted = true;
294
+ next();
253
295
  }
254
- }
255
- return false;
256
- };
257
- if (validateSQLInput(req.body, "body") ||
258
- validateSQLInput(req.query, "query") ||
259
- validateSQLInput(req.params, "params")) {
260
- console.warn(` SQL injection attempt detected from ${this.getClientIP(req)}`);
261
- return res.status(400).json({
262
- error: "Invalid input detected",
263
- });
296
+ }, 100); // 100ms timeout
297
+ // Execute the middleware
298
+ middleware(req, res, middlewareNext);
299
+ }
300
+ catch (error) {
301
+ this.logger.debug("security", `Exception in middleware at index ${currentIndex}:`, error);
302
+ finalNext(error);
264
303
  }
265
- next();
266
304
  };
305
+ // Start the middleware chain
306
+ this.logger.debug("security", "Starting middleware chain");
307
+ next();
267
308
  }
268
309
  /**
269
- * CSRF Protection middleware
310
+ * Custom XSS protection middleware
270
311
  */
271
- csrfProtection() {
272
- return (req, res, next) => {
273
- if (!this.config.csrf) {
274
- return next();
312
+ xssProtection(req, res, next) {
313
+ let maliciousContentDetected = false;
314
+ const detectedThreats = [];
315
+ // Check and sanitize request body
316
+ if (req.body && typeof req.body === "object") {
317
+ const { sanitized, threats } = this.sanitizeObjectWithDetection(req.body);
318
+ if (threats.length > 0) {
319
+ maliciousContentDetected = true;
320
+ detectedThreats.push(...threats.map((t) => `body.${t}`));
275
321
  }
276
- // Skip CSRF for safe methods
277
- if (["GET", "HEAD", "OPTIONS"].includes(req.method)) {
278
- return next();
322
+ try {
323
+ req.body = sanitized;
279
324
  }
280
- const token = req.headers["x-csrf-token"] ||
281
- req.body?._csrf ||
282
- req.query?._csrf;
283
- const sessionToken = req.session?.csrfToken;
284
- if (!token ||
285
- !sessionToken ||
286
- !crypto.XyPrissSecurity.constantTimeEqual(token, sessionToken)) {
287
- return res.status(403).json({
288
- error: "CSRF token validation failed",
325
+ catch (error) {
326
+ // Handle readonly property - create new object
327
+ Object.defineProperty(req, "body", {
328
+ value: sanitized,
329
+ writable: true,
330
+ configurable: true,
289
331
  });
290
332
  }
291
- next();
292
- };
333
+ }
334
+ // Check and sanitize query parameters
335
+ if (req.query && typeof req.query === "object") {
336
+ const { sanitized, threats } = this.sanitizeObjectWithDetection(req.query);
337
+ if (threats.length > 0) {
338
+ maliciousContentDetected = true;
339
+ detectedThreats.push(...threats.map((t) => `query.${t}`));
340
+ }
341
+ try {
342
+ req.query = sanitized;
343
+ }
344
+ catch (error) {
345
+ // Handle readonly property - create new object
346
+ Object.defineProperty(req, "query", {
347
+ value: sanitized,
348
+ writable: true,
349
+ configurable: true,
350
+ });
351
+ }
352
+ }
353
+ // Check and sanitize URL parameters
354
+ if (req.params && typeof req.params === "object") {
355
+ const { sanitized, threats } = this.sanitizeObjectWithDetection(req.params);
356
+ if (threats.length > 0) {
357
+ maliciousContentDetected = true;
358
+ detectedThreats.push(...threats.map((t) => `params.${t}`));
359
+ }
360
+ try {
361
+ req.params = sanitized;
362
+ }
363
+ catch (error) {
364
+ // Handle readonly property - create new object
365
+ Object.defineProperty(req, "params", {
366
+ value: sanitized,
367
+ writable: true,
368
+ configurable: true,
369
+ });
370
+ }
371
+ }
372
+ // Block request if malicious content was detected
373
+ if (maliciousContentDetected) {
374
+ this.logger.warn("security", `XSS attack blocked from ${req.ip}. Threats detected: ${detectedThreats.join(", ")}`);
375
+ res.status(400).json({
376
+ error: "Malicious content detected",
377
+ message: "Request blocked due to potential XSS attack",
378
+ threats: detectedThreats,
379
+ timestamp: new Date().toISOString(),
380
+ });
381
+ return; // Don't call next() - block the request
382
+ }
383
+ next();
293
384
  }
294
385
  /**
295
- * Request encryption middleware
386
+ * Make request properties writable to avoid readonly property errors
296
387
  */
297
- requestEncryption() {
298
- const self = this; // Capture 'this' context
299
- return (req, res, next) => {
300
- if (!self.config.encryption) {
301
- return next();
302
- }
303
- // Check if request is encrypted
304
- const encryptedHeader = req.headers["x-encrypted-request"];
305
- if (encryptedHeader && req.body) {
388
+ makeRequestPropertiesWritable(req) {
389
+ const properties = ["body", "params", "headers", "query"];
390
+ properties.forEach((prop) => {
391
+ if (req[prop] !== undefined) {
306
392
  try {
307
- // Decryption using SecureObject
308
- const encryptedData = req.body.data;
309
- const secureObj = new secureObjectCore.SecureObject({ data: encryptedData });
310
- secureObj.setEncryptionKey(self.config.authentication?.jwt?.secret || "default-key");
311
- const decryptedData = secureObj.toObject();
312
- req.body = JSON.parse(decryptedData.data);
393
+ // Test if property is writable
394
+ const original = req[prop];
395
+ req[prop] = original;
313
396
  }
314
397
  catch (error) {
315
- return res.status(400).json({
316
- error: "Failed to decrypt request",
398
+ // Property is readonly, make it writable
399
+ const value = req[prop];
400
+ Object.defineProperty(req, prop, {
401
+ value: value,
402
+ writable: true,
403
+ configurable: true,
404
+ enumerable: true,
317
405
  });
318
406
  }
319
407
  }
320
- // Encrypt response if requested
321
- const originalJson = res.json;
322
- res.json = function (data) {
323
- if (req.headers["x-encrypt-response"]) {
324
- // Encryption using SecureObject
325
- const secureObj = new secureObjectCore.SecureObject({
326
- data: JSON.stringify(data),
327
- });
328
- secureObj.setEncryptionKey(self.config.authentication?.jwt?.secret || "default-key");
329
- secureObj.encryptAll();
330
- const encrypted = secureObj.exportData();
331
- res.set("X-Encrypted-Response", "true");
332
- return originalJson.call(this, { data: encrypted });
333
- }
334
- return originalJson.call(this, data);
335
- };
336
- next();
337
- };
408
+ });
338
409
  }
339
410
  /**
340
- * Sanitize object recursively
411
+ * Recursively sanitize object properties
341
412
  */
342
413
  sanitizeObject(obj) {
343
414
  if (typeof obj === "string") {
344
- return this.sanitizeString(obj);
415
+ return xss(obj);
345
416
  }
346
- if (typeof obj === "object" && obj !== null) {
347
- for (const key in obj) {
348
- if (obj.hasOwnProperty(key)) {
349
- obj[key] = this.sanitizeObject(obj[key]);
350
- }
417
+ if (Array.isArray(obj)) {
418
+ return obj.map((item) => this.sanitizeObject(item));
419
+ }
420
+ if (obj && typeof obj === "object") {
421
+ const sanitized = {};
422
+ for (const [key, value] of Object.entries(obj)) {
423
+ sanitized[key] = this.sanitizeObject(value);
351
424
  }
425
+ return sanitized;
352
426
  }
353
427
  return obj;
354
428
  }
355
429
  /**
356
- * Sanitize string for XSS
357
- */
358
- sanitizeString(str) {
359
- return str
360
- .replace(/</g, "&lt;")
361
- .replace(/>/g, "&gt;")
362
- .replace(/"/g, "&quot;")
363
- .replace(/'/g, "&#x27;")
364
- .replace(/\//g, "&#x2F;")
365
- .replace(/javascript:/gi, "")
366
- .replace(/on\w+=/gi, "");
367
- }
368
- /**
369
- * Get security configuration
430
+ * Sanitize object and detect threats
370
431
  */
371
- getConfig() {
372
- return this.config;
373
- }
374
- /**
375
- * Get brute force statistics
376
- */
377
- getBruteForceStats() {
378
- const stats = {
379
- totalIPs: this.bruteForceMap.size,
380
- blockedIPs: 0,
381
- suspiciousIPs: 0,
382
- };
383
- const now = Date.now();
384
- for (const [_ip, record] of this.bruteForceMap.entries()) {
385
- if (record.blockedUntil && record.blockedUntil > now) {
386
- stats.blockedIPs++;
432
+ sanitizeObjectWithDetection(obj, path = "") {
433
+ const threats = [];
434
+ const sanitizeWithDetection = (value, currentPath) => {
435
+ if (typeof value === "string") {
436
+ const original = value;
437
+ let sanitized = xss(value);
438
+ let threatDetected = false;
439
+ const detectedPatterns = [];
440
+ // Check if XSS library sanitization changed the content
441
+ if (original !== sanitized) {
442
+ threatDetected = true;
443
+ detectedPatterns.push("XSS");
444
+ }
445
+ // SQL Injection Detection
446
+ if (this.sqlInjection) {
447
+ const sqlResult = this.sqlInjectionDetector.detect(original, currentPath);
448
+ if (sqlResult.isMalicious) {
449
+ threatDetected = true;
450
+ detectedPatterns.push(`SQL Injection (${sqlResult.riskLevel})`);
451
+ // Use the SQL detector's sanitized version if available
452
+ if (sqlResult.sanitizedInput) {
453
+ sanitized = sqlResult.sanitizedInput;
454
+ }
455
+ }
456
+ }
457
+ // Additional threat detection for patterns XSS library might miss
458
+ const additionalThreats = [
459
+ /javascript:/i,
460
+ /vbscript:/i,
461
+ /data:/i,
462
+ /on\w+\s*=/i, // event handlers like onclick=, onload=
463
+ /<iframe/i,
464
+ /<object/i,
465
+ /<embed/i,
466
+ /<link/i,
467
+ /<meta/i,
468
+ /expression\s*\(/i, // CSS expression()
469
+ /url\s*\(\s*javascript:/i,
470
+ ];
471
+ for (const pattern of additionalThreats) {
472
+ if (pattern.test(original)) {
473
+ threatDetected = true;
474
+ detectedPatterns.push("Enhanced XSS");
475
+ // Sanitize these additional threats
476
+ sanitized = original.replace(pattern, "[BLOCKED]");
477
+ break;
478
+ }
479
+ }
480
+ if (threatDetected) {
481
+ threats.push(currentPath || "root");
482
+ // Log the specific threats detected
483
+ this.logger.warn("security", `Security threat detected in ${currentPath || "root"}: ${detectedPatterns.join(", ")}`);
484
+ }
485
+ return sanitized;
387
486
  }
388
- else if (record.attempts > 3) {
389
- stats.suspiciousIPs++;
487
+ if (Array.isArray(value)) {
488
+ return value.map((item, index) => sanitizeWithDetection(item, `${currentPath}[${index}]`));
390
489
  }
391
- }
392
- return stats;
490
+ if (value && typeof value === "object") {
491
+ const sanitized = {};
492
+ for (const [key, val] of Object.entries(value)) {
493
+ const newPath = currentPath ? `${currentPath}.${key}` : key;
494
+ sanitized[key] = sanitizeWithDetection(val, newPath);
495
+ }
496
+ return sanitized;
497
+ }
498
+ return value;
499
+ };
500
+ const sanitized = sanitizeWithDetection(obj, path);
501
+ return { sanitized, threats };
393
502
  }
394
503
  /**
395
- * Unblock IP address
504
+ * Get CSRF token for client-side usage
396
505
  */
397
- unblockIP(ip) {
398
- const record = this.bruteForceMap.get(ip);
399
- if (record) {
400
- delete record.blockedUntil;
401
- record.attempts = 0;
402
- return true;
506
+ generateCsrfToken(req) {
507
+ if (this.csrf && req.csrfToken) {
508
+ return req.csrfToken();
403
509
  }
404
- return false;
510
+ return null;
405
511
  }
406
512
  /**
407
- * Clear all brute force records
513
+ * Get security configuration
408
514
  */
409
- clearBruteForceRecords() {
410
- this.bruteForceMap.clear();
515
+ getConfig() {
516
+ return {
517
+ level: this.level,
518
+ csrf: this.csrf,
519
+ helmet: this.helmet,
520
+ xss: this.xss,
521
+ sqlInjection: this.sqlInjection,
522
+ bruteForce: this.bruteForce,
523
+ encryption: this.encryption,
524
+ authentication: this.authentication,
525
+ };
411
526
  }
412
527
  }
413
528