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