xypriss 9.6.97 → 9.7.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 (171) hide show
  1. package/README.md +55 -22
  2. package/dist/cjs/src/index.js +0 -19
  3. package/dist/cjs/src/index.js.map +1 -1
  4. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  5. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  6. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js +510 -0
  7. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  8. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  9. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  10. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js +413 -0
  11. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  12. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js +98 -0
  13. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  14. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js +52 -0
  15. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  16. package/dist/cjs/src/middleware/safe-json-middleware.js +0 -82
  17. package/dist/cjs/src/middleware/safe-json-middleware.js.map +1 -1
  18. package/dist/cjs/src/middleware/security-middleware.js +7 -4
  19. package/dist/cjs/src/middleware/security-middleware.js.map +1 -1
  20. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  21. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  22. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  23. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  24. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  25. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  26. package/dist/cjs/src/plugins/const/XyprissTempDir.js +72 -9
  27. package/dist/cjs/src/plugins/const/XyprissTempDir.js.map +1 -1
  28. package/dist/cjs/src/plugins/core/manager/PluginLoader.js +8 -0
  29. package/dist/cjs/src/plugins/core/manager/PluginLoader.js.map +1 -1
  30. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js +87 -0
  31. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  32. package/dist/cjs/src/server/FastServer/index.js +5 -0
  33. package/dist/cjs/src/server/FastServer/index.js.map +1 -1
  34. package/dist/cjs/src/server/ServerFactory.js +8 -13
  35. package/dist/cjs/src/server/ServerFactory.js.map +1 -1
  36. package/dist/cjs/src/server/components/fastapi/RedirectManager.js +8 -58
  37. package/dist/cjs/src/server/components/fastapi/RedirectManager.js.map +1 -1
  38. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  39. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  40. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js +9 -1
  41. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  42. package/dist/cjs/src/server/core/HttpServer.js +22 -0
  43. package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
  44. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js +33 -2
  45. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  46. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  47. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  48. package/dist/cjs/src/server/core/XyServerCreator.js +1 -0
  49. package/dist/cjs/src/server/core/XyServerCreator.js.map +1 -1
  50. package/dist/cjs/src/shared/logger/quickLogger.js +162 -0
  51. package/dist/cjs/src/shared/logger/quickLogger.js.map +1 -0
  52. package/dist/cjs/src/xhsc/PathApi.js +44 -3
  53. package/dist/cjs/src/xhsc/PathApi.js.map +1 -1
  54. package/dist/cjs/src/xhsc/System.js +2 -0
  55. package/dist/cjs/src/xhsc/System.js.map +1 -1
  56. package/dist/cjs/src/xhsc/UtilsApi.js +52 -0
  57. package/dist/cjs/src/xhsc/UtilsApi.js.map +1 -0
  58. package/dist/cjs/src/xhsc/XyPrissRunner.js +30 -2
  59. package/dist/cjs/src/xhsc/XyPrissRunner.js.map +1 -1
  60. package/dist/cjs/src/xhsc/fs/FSCore.js +148 -0
  61. package/dist/cjs/src/xhsc/fs/FSCore.js.map +1 -1
  62. package/dist/cjs/src/xhsc/fs/FileHandle.js +112 -0
  63. package/dist/cjs/src/xhsc/fs/FileHandle.js.map +1 -0
  64. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js +134 -0
  65. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  66. package/dist/cjs/src/xhsc/utils/ArrayUtils.js +67 -0
  67. package/dist/cjs/src/xhsc/utils/ArrayUtils.js.map +1 -0
  68. package/dist/cjs/src/xhsc/utils/AsyncUtils.js +582 -0
  69. package/dist/cjs/src/xhsc/utils/AsyncUtils.js.map +1 -0
  70. package/dist/cjs/src/xhsc/utils/DateUtils.js +959 -0
  71. package/dist/cjs/src/xhsc/utils/DateUtils.js.map +1 -0
  72. package/dist/cjs/src/xhsc/utils/FunctionUtils.js +29 -0
  73. package/dist/cjs/src/xhsc/utils/FunctionUtils.js.map +1 -0
  74. package/dist/cjs/src/xhsc/utils/IdUtils.js +22 -0
  75. package/dist/cjs/src/xhsc/utils/IdUtils.js.map +1 -0
  76. package/dist/cjs/src/xhsc/utils/NumberUtils.js +79 -0
  77. package/dist/cjs/src/xhsc/utils/NumberUtils.js.map +1 -0
  78. package/dist/cjs/src/xhsc/utils/ObjectUtils.js +141 -0
  79. package/dist/cjs/src/xhsc/utils/ObjectUtils.js.map +1 -0
  80. package/dist/cjs/src/xhsc/utils/StringUtils.js +145 -0
  81. package/dist/cjs/src/xhsc/utils/StringUtils.js.map +1 -0
  82. package/dist/cjs/src/xhsc/utils/ValidationUtils.js +49 -0
  83. package/dist/cjs/src/xhsc/utils/ValidationUtils.js.map +1 -0
  84. package/dist/cjs/src/xhsc.js +5 -3
  85. package/dist/cjs/src/xhsc.js.map +1 -1
  86. package/dist/esm/src/index.js +0 -2
  87. package/dist/esm/src/index.js.map +1 -1
  88. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  89. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  90. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js +508 -0
  91. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  92. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  93. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  94. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js +391 -0
  95. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  96. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js +96 -0
  97. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  98. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js +50 -0
  99. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  100. package/dist/esm/src/middleware/safe-json-middleware.js +1 -79
  101. package/dist/esm/src/middleware/safe-json-middleware.js.map +1 -1
  102. package/dist/esm/src/middleware/security-middleware.js +7 -4
  103. package/dist/esm/src/middleware/security-middleware.js.map +1 -1
  104. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  105. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  106. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  107. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  108. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  109. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  110. package/dist/esm/src/plugins/const/XyprissTempDir.js +70 -9
  111. package/dist/esm/src/plugins/const/XyprissTempDir.js.map +1 -1
  112. package/dist/esm/src/plugins/core/manager/PluginLoader.js +8 -0
  113. package/dist/esm/src/plugins/core/manager/PluginLoader.js.map +1 -1
  114. package/dist/esm/src/plugins/core/manager/PluginSecurity.js +87 -0
  115. package/dist/esm/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  116. package/dist/esm/src/server/FastServer/index.js +5 -0
  117. package/dist/esm/src/server/FastServer/index.js.map +1 -1
  118. package/dist/esm/src/server/ServerFactory.js +8 -1
  119. package/dist/esm/src/server/ServerFactory.js.map +1 -1
  120. package/dist/esm/src/server/components/fastapi/RedirectManager.js +8 -58
  121. package/dist/esm/src/server/components/fastapi/RedirectManager.js.map +1 -1
  122. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  123. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  124. package/dist/esm/src/server/components/multi-server/MultiServerManager.js +9 -1
  125. package/dist/esm/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  126. package/dist/esm/src/server/core/HttpServer.js +22 -0
  127. package/dist/esm/src/server/core/HttpServer.js.map +1 -1
  128. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js +33 -2
  129. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  130. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  131. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  132. package/dist/esm/src/server/core/XyServerCreator.js +1 -0
  133. package/dist/esm/src/server/core/XyServerCreator.js.map +1 -1
  134. package/dist/esm/src/shared/logger/quickLogger.js +160 -0
  135. package/dist/esm/src/shared/logger/quickLogger.js.map +1 -0
  136. package/dist/esm/src/xhsc/PathApi.js +44 -3
  137. package/dist/esm/src/xhsc/PathApi.js.map +1 -1
  138. package/dist/esm/src/xhsc/System.js +2 -0
  139. package/dist/esm/src/xhsc/System.js.map +1 -1
  140. package/dist/esm/src/xhsc/UtilsApi.js +50 -0
  141. package/dist/esm/src/xhsc/UtilsApi.js.map +1 -0
  142. package/dist/esm/src/xhsc/XyPrissRunner.js +30 -2
  143. package/dist/esm/src/xhsc/XyPrissRunner.js.map +1 -1
  144. package/dist/esm/src/xhsc/fs/FSCore.js +148 -0
  145. package/dist/esm/src/xhsc/fs/FSCore.js.map +1 -1
  146. package/dist/esm/src/xhsc/fs/FileHandle.js +110 -0
  147. package/dist/esm/src/xhsc/fs/FileHandle.js.map +1 -0
  148. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js +113 -0
  149. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  150. package/dist/esm/src/xhsc/utils/ArrayUtils.js +65 -0
  151. package/dist/esm/src/xhsc/utils/ArrayUtils.js.map +1 -0
  152. package/dist/esm/src/xhsc/utils/AsyncUtils.js +580 -0
  153. package/dist/esm/src/xhsc/utils/AsyncUtils.js.map +1 -0
  154. package/dist/esm/src/xhsc/utils/DateUtils.js +957 -0
  155. package/dist/esm/src/xhsc/utils/DateUtils.js.map +1 -0
  156. package/dist/esm/src/xhsc/utils/FunctionUtils.js +27 -0
  157. package/dist/esm/src/xhsc/utils/FunctionUtils.js.map +1 -0
  158. package/dist/esm/src/xhsc/utils/IdUtils.js +20 -0
  159. package/dist/esm/src/xhsc/utils/IdUtils.js.map +1 -0
  160. package/dist/esm/src/xhsc/utils/NumberUtils.js +77 -0
  161. package/dist/esm/src/xhsc/utils/NumberUtils.js.map +1 -0
  162. package/dist/esm/src/xhsc/utils/ObjectUtils.js +139 -0
  163. package/dist/esm/src/xhsc/utils/ObjectUtils.js.map +1 -0
  164. package/dist/esm/src/xhsc/utils/StringUtils.js +143 -0
  165. package/dist/esm/src/xhsc/utils/StringUtils.js.map +1 -0
  166. package/dist/esm/src/xhsc/utils/ValidationUtils.js +47 -0
  167. package/dist/esm/src/xhsc/utils/ValidationUtils.js.map +1 -0
  168. package/dist/esm/src/xhsc.js +6 -5
  169. package/dist/esm/src/xhsc.js.map +1 -1
  170. package/dist/index.d.ts +1872 -234
  171. package/package.json +119 -137
@@ -16,7 +16,7 @@ class SQLInjectionDetector {
16
16
  /\/\*.*?\*\/(or|OR|and|AND)\/\*.*?\*\//gi,
17
17
  // Time-based with specific syntax (enhanced)
18
18
  /(sleep|SLEEP|waitfor|WAITFOR|delay|DELAY)\s*\(.*?\)/gi,
19
- /(waitfor|WAITFOR)\s+(delay|DELAY)\s+'/gi,
19
+ /waitfor\s+delay\s+/i,
20
20
  // System stored procedures
21
21
  /(exec|EXEC|execute|EXECUTE)\s+(sp_|xp_)\w+/gi,
22
22
  // Information schema with specific queries
@@ -27,8 +27,8 @@ class SQLInjectionDetector {
27
27
  /0x(27|22|5C|2D|2D)/gi, // ', ", \, --
28
28
  // Multiple quotes for quote breaking
29
29
  /('{3,}|"{3,})/g,
30
- // Stacked queries with dangerous operations
31
- /;(\s)*(drop|delete|insert|update|create|alter)(\s)+/gi,
30
+ // Stacked queries
31
+ /;\s*(drop|delete|insert|update|create|alter|select)\b/i,
32
32
  ];
33
33
  // Medium risk patterns (require context analysis)
34
34
  this.mediumRiskPatterns = [
@@ -44,6 +44,18 @@ class SQLInjectionDetector {
44
44
  // Wildcards
45
45
  /[%_]/g,
46
46
  ];
47
+ this.referencePayloads = [
48
+ "1' OR '1'='1",
49
+ "admin'--",
50
+ "' UNION SELECT NULL,NULL,NULL--",
51
+ "'; WAITFOR DELAY '0:0:5'--",
52
+ "1 OR 1=1;--",
53
+ "') OR ('1'='1",
54
+ "1/0",
55
+ "CHAR(113)+CHAR(118)+CHAR(112)+CHAR(113)",
56
+ "SELECT * FROM users",
57
+ "DROP TABLE customers",
58
+ ];
47
59
  // Characters that are suspicious in certain contexts
48
60
  this.contextSensitiveChars = /[';\"\\%_]/g;
49
61
  this.config = {
@@ -53,6 +65,7 @@ class SQLInjectionDetector {
53
65
  logAttempts: config.logAttempts ?? true,
54
66
  contextualAnalysis: config.contextualAnalysis ?? true,
55
67
  falsePositiveThreshold: config.falsePositiveThreshold ?? 0.6,
68
+ proximityThreshold: config.proximityThreshold ?? 0.85,
56
69
  };
57
70
  }
58
71
  /**
@@ -84,28 +97,31 @@ class SQLInjectionDetector {
84
97
  this.highRiskPatterns.forEach((pattern, index) => {
85
98
  const matches = input.match(pattern);
86
99
  if (matches) {
87
- const patternName = this.getHighRiskPatternName(index);
88
- result.detectedPatterns.push(`${patternName}: ${matches.join(", ")}`);
89
- highRiskScore += this.getHighRiskPatternWeight(index);
100
+ result.detectedPatterns.push(`Pattern Match: ${matches.join(", ")}`);
101
+ highRiskScore += 0.3;
90
102
  }
91
103
  });
92
- // Medium-risk pattern analysis (context-dependent)
93
- let mediumRiskScore = 0;
94
- if (this.config.contextualAnalysis) {
95
- mediumRiskScore = this.analyzeContext(input, context || "");
96
- }
97
- else {
98
- // Basic medium risk analysis without context
99
- this.mediumRiskPatterns.forEach((pattern, index) => {
100
- const matches = input.match(pattern);
101
- if (matches) {
102
- mediumRiskScore += 0.1 * matches.length; // Lower weight for medium risk
103
- }
104
- });
104
+ // 1. Medium risk patterns (accumulative)
105
+ let mediumMatches = 0;
106
+ this.mediumRiskPatterns.forEach((pattern) => {
107
+ const matches = input.match(pattern);
108
+ if (matches) {
109
+ mediumMatches += matches.length;
110
+ }
111
+ });
112
+ // Cap medium match contribution to prevent false positives in large structured data
113
+ const maxMediumMatches = 20;
114
+ const cappedMediumMatches = Math.min(mediumMatches, maxMediumMatches);
115
+ let mediumRiskScore = cappedMediumMatches * 0.1;
116
+ // 2. Proximity analysis (Levenshtein) - Complementary to regex
117
+ const proximityScore = this.calculateMaxProximity(input);
118
+ if (proximityScore > 0.4) {
119
+ highRiskScore += proximityScore * 0.5;
120
+ result.detectedPatterns.push(`Proximity Match (${Math.round(proximityScore * 100)}%)`);
105
121
  }
106
122
  // Contextual analysis for legitimate use cases
107
123
  const legitimacyScore = this.calculateLegitimacyScore(input);
108
- // Calculate confidence with false positive mitigation
124
+ // 3. Final confidence calculation
109
125
  const rawScore = highRiskScore + mediumRiskScore * 0.3;
110
126
  result.confidence = Math.max(0, rawScore - legitimacyScore);
111
127
  result.confidence = Math.min(result.confidence, 1.0);
@@ -186,10 +202,25 @@ class SQLInjectionDetector {
186
202
  */
187
203
  calculateLegitimacyScore(input) {
188
204
  let legitimacyScore = 0;
205
+ // JSON check - Structured data often triggers false positives due to quotes/braces
206
+ if ((input.startsWith("{") && input.endsWith("}")) ||
207
+ (input.startsWith("[") && input.endsWith("]"))) {
208
+ try {
209
+ // Quick check for JSON validity
210
+ JSON.parse(input);
211
+ legitimacyScore += 0.8; // Significant boost for valid JSON
212
+ }
213
+ catch (e) {
214
+ // Not valid JSON, but maybe partial JSON
215
+ if (input.includes('":') || input.includes('",')) {
216
+ legitimacyScore += 0.3;
217
+ }
218
+ }
219
+ }
189
220
  // Natural language indicators
190
221
  const naturalWords = input.match(/\b[a-zA-Z]{3,}\b/g);
191
- if (naturalWords && naturalWords.length > 2) {
192
- legitimacyScore += 0.2; // Looks like natural text
222
+ if (naturalWords && naturalWords.length > 5) {
223
+ legitimacyScore += 0.4; // More weight for clearly natural text
193
224
  }
194
225
  // Check for common legitimate patterns
195
226
  const legitimatePatterns = [
@@ -200,20 +231,71 @@ class SQLInjectionDetector {
200
231
  ];
201
232
  legitimatePatterns.forEach((pattern) => {
202
233
  if (pattern.test(input)) {
203
- legitimacyScore += 0.15;
234
+ legitimacyScore += 0.2;
204
235
  }
205
236
  });
206
- // Length-based legitimacy (very short or very specific lengths are more suspicious)
207
- if (input.length > 10 && input.length < 200) {
208
- legitimacyScore += 0.1;
209
- }
210
237
  // Check for balanced quotes (legitimate text often has balanced quotes)
211
238
  const singleQuotes = (input.match(/'/g) || []).length;
212
239
  const doubleQuotes = (input.match(/"/g) || []).length;
213
- if (singleQuotes % 2 === 0 && doubleQuotes % 2 === 0) {
214
- legitimacyScore += 0.1;
240
+ if (singleQuotes > 0 &&
241
+ singleQuotes % 2 === 0 &&
242
+ doubleQuotes % 2 === 0) {
243
+ legitimacyScore += 0.15;
244
+ }
245
+ return Math.min(legitimacyScore, 1.2); // Cap increased to allow full offset of medium risk
246
+ }
247
+ calculateMaxProximity(input) {
248
+ const normalizedInput = input.toLowerCase().replace(/\s+/g, " ");
249
+ let maxProximity = 0;
250
+ // Optimized proximity check: only check near suspicious characters to save CPU
251
+ const suspiciousIndices = [];
252
+ for (let i = 0; i < input.length; i++) {
253
+ if (["'", '"', ";", "-", "#", "u", "s", "d"].includes(input[i].toLowerCase())) {
254
+ suspiciousIndices.push(i);
255
+ }
256
+ }
257
+ // Limit the number of checks for very large strings
258
+ const maxChecks = 50;
259
+ const stride = Math.ceil(suspiciousIndices.length / maxChecks);
260
+ this.referencePayloads.forEach((payload) => {
261
+ const normalizedPayload = payload.toLowerCase();
262
+ const pLen = normalizedPayload.length;
263
+ for (let i = 0; i < suspiciousIndices.length; i += stride) {
264
+ const start = Math.max(0, suspiciousIndices[i] - 5);
265
+ const end = Math.min(normalizedInput.length, start + pLen + 10);
266
+ const chunk = normalizedInput.substring(start, end);
267
+ if (chunk.length < pLen / 2)
268
+ continue;
269
+ const distance = this.levenshteinDistance(normalizedPayload, chunk);
270
+ const similarity = 1 - distance / Math.max(pLen, chunk.length);
271
+ if (similarity > maxProximity) {
272
+ maxProximity = similarity;
273
+ }
274
+ }
275
+ });
276
+ return maxProximity;
277
+ }
278
+ levenshteinDistance(a, b) {
279
+ const matrix = [];
280
+ for (let i = 0; i <= b.length; i++) {
281
+ matrix[i] = [i];
282
+ }
283
+ for (let j = 0; j <= a.length; j++) {
284
+ matrix[0][j] = j;
285
+ }
286
+ for (let i = 1; i <= b.length; i++) {
287
+ for (let j = 1; j <= a.length; j++) {
288
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
289
+ matrix[i][j] = matrix[i - 1][j - 1];
290
+ }
291
+ else {
292
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
293
+ matrix[i][j - 1] + 1, // insertion
294
+ matrix[i - 1][j] + 1);
295
+ }
296
+ }
215
297
  }
216
- return Math.min(legitimacyScore, 0.5); // Cap legitimacy score
298
+ return matrix[b.length][a.length];
217
299
  }
218
300
  /**
219
301
  * Smart sanitization that preserves legitimate content
@@ -240,10 +322,7 @@ class SQLInjectionDetector {
240
322
  validateAndSanitize(input, throwOnDetection = false) {
241
323
  const result = this.detect(input);
242
324
  if (result.isMalicious && throwOnDetection) {
243
- throw new Error(`SQL injection attempt detected. Confidence: ${(result.confidence * 100).toFixed(1)}%. `
244
- // +
245
- // `Patterns: ${result.detectedPatterns.join(", ")}`
246
- );
325
+ throw new Error(`SQL injection attempt detected. Confidence: ${(result.confidence * 100).toFixed(1)}%. `);
247
326
  }
248
327
  return result.sanitizedInput || "";
249
328
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SQLInjectionDetector.js","sources":["../../../../../../src/middleware/built-in/security/SQLInjectionDetector.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SQLInjectionDetector.js","sources":["../../../../../../src/middleware/built-in/security/SQLInjectionDetector.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,391 @@
1
+ import * as vm from 'vm';
2
+
3
+ /**
4
+ * @module UriNormalizer
5
+ *
6
+ * Normalization and security utilities for URIs and paths.
7
+ *
8
+ * ### Supported Threats
9
+ * - Path traversal (including encoded variants: `%2F`, `%2E`, double-encoded `%2520`)
10
+ * - Injection of null bytes and control characters
11
+ * - ReDoS attacks via sandbox execution with an adaptive timeout
12
+ * - Backslash smuggling (`\..\..\`)
13
+ * - Unicode normalized segments (NFC) to prevent traversal homoglyphs
14
+ *
15
+ * ### Non-regression Guarantees (no false positives)
16
+ * - Legitimate paths with encoded special characters are preserved correctly.
17
+ * - The trailing slash is preserved if present in the original input.
18
+ * - Internal empty segments are cleanly removed (`//` collapse).
19
+ * - The root `/` is always returned for an empty or null input.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * UriNormalizer.normalizePath("/foo/%2E%2E/bar"); // => "/bar"
24
+ * UriNormalizer.normalizePath("/a//b/../c/"); // => "/a/c/"
25
+ * UriNormalizer.safeRegexCheck(/^[a-z]+$/, "hello"); // => true
26
+ * ```
27
+ */
28
+ class UriNormalizer {
29
+ // ─────────────────────────────────────────────────────────────────────────
30
+ // Public API
31
+ // ─────────────────────────────────────────────────────────────────────────
32
+ /**
33
+ * Normalizes a URI path by resolving `.` and `..` segments, multiple
34
+ * slashes, backslashes, null bytes, control characters, and all URI
35
+ * encodings (including double-encodings such as `%2520`).
36
+ *
37
+ * Normalization follows this strict order to eliminate bypass vectors:
38
+ * 1. Iterative decoding until stabilization (anti double-encoding).
39
+ * 2. Unicode NFC normalization (anti homoglyphs).
40
+ * 3. Replacement of backslashes with forward slashes.
41
+ * 4. Removal of null bytes and control characters.
42
+ * 5. Collapse of multiple slashes.
43
+ * 6. Resolution of `.` and `..` segments.
44
+ * 7. Restoration of the trailing slash if the original input had one.
45
+ *
46
+ * ### Guaranteed Behaviors
47
+ * - `""` or `null`/`undefined` → `"/"`
48
+ * - Paths where all segments resolve above the root are clipped
49
+ * to `"/"` (no underflow possible).
50
+ * - The trailing slash is faithfully preserved or removed based on the input.
51
+ * - Unicode control characters (U+0000–U+001F, U+007F–U+009F)
52
+ * are systematically removed.
53
+ *
54
+ * @param {string} pathStr - The raw path to normalize (can be encoded).
55
+ * @returns {string} The normalized path, always prefixed with `/`.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * UriNormalizer.normalizePath("/foo/bar"); // "/foo/bar"
60
+ * UriNormalizer.normalizePath("/foo/../bar"); // "/bar"
61
+ * UriNormalizer.normalizePath("/foo/%2E%2E/bar"); // "/bar"
62
+ * UriNormalizer.normalizePath("/foo/%252E%252E/bar"); // "/bar" (double-encoded)
63
+ * UriNormalizer.normalizePath("/a//b/./c/"); // "/a/b/c/"
64
+ * UriNormalizer.normalizePath("\\foo\\..\\bar"); // "/bar"
65
+ * UriNormalizer.normalizePath("/foo/\0bar"); // "/foo/bar"
66
+ * UriNormalizer.normalizePath(""); // "/"
67
+ * ```
68
+ */
69
+ static normalizePath(pathStr) {
70
+ if (!pathStr)
71
+ return "/";
72
+ // Step 1: Iterative decoding to neutralize double-encodings
73
+ const decoded = UriNormalizer.iterativeDecode(pathStr);
74
+ // Step 2: Unicode NFC normalization
75
+ const nfc = decoded.normalize("NFC");
76
+ // Step 3: Replace backslashes with forward slashes
77
+ const forwardSlashed = nfc.replace(/\\/g, "/");
78
+ // Step 4: Removal of null bytes and control characters
79
+ const sanitized = UriNormalizer.stripControlCharacters(forwardSlashed);
80
+ // Step 5: Collapse multiple slashes (e.g., `///` → `/`)
81
+ const collapsed = sanitized.replace(/\/+/g, "/");
82
+ // Memorize trailing slash before resolution (it will be lost during split)
83
+ const hasTrailingSlash = collapsed.endsWith("/") && collapsed.length > 1;
84
+ // Step 6: Resolve `.` and `..` segments
85
+ const resolved = UriNormalizer.resolveSegments(collapsed);
86
+ // Step 7: Restore trailing slash
87
+ return hasTrailingSlash ? resolved + "/" : resolved;
88
+ }
89
+ /**
90
+ * Executes a regex test with a strict timeout to prevent ReDoS
91
+ * (Regular Expression Denial of Service) attacks.
92
+ *
93
+ * ### Protection Strategy
94
+ * - Short strings (< {@link REGEX_VM_LENGTH_THRESHOLD} characters) are
95
+ * tested directly for performance, but the threshold has been lowered to
96
+ * 20 to cover catastrophic patterns on short repetitions.
97
+ * - Beyond the threshold, the regex is executed in an isolated Node.js VM
98
+ * context with an adaptive timeout calculated by {@link computeRegexTimeout}.
99
+ * - In the event of a timeout or VM error, the method returns `false` **and**
100
+ * throws a typed error to distinguish a real ReDoS from a false positive.
101
+ *
102
+ * ### Error Differentiation
103
+ * - `UriNormalizerRegexTimeoutError`: timeout reached → probable ReDoS.
104
+ * - Any other internal exception is propagated as-is to avoid hiding
105
+ * caller layer bugs.
106
+ *
107
+ * @param {RegExp} pattern - The regular expression to evaluate.
108
+ * @param {string} str - The string to test against.
109
+ * @param {number} [timeoutMs] - Base timeout in ms (default: {@link REGEX_BASE_TIMEOUT_MS}).
110
+ * Automatically increased based on `str` length.
111
+ * @returns {boolean} `true` if the regex matches, `false` otherwise or on timeout.
112
+ * @throws {TypeError} If `pattern` is not a RegExp instance.
113
+ * @throws {UriNormalizerRegexTimeoutError} If the VM timeout is reached (probable ReDoS).
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * // Basic usage
118
+ * UriNormalizer.safeRegexCheck(/^[a-z]+$/, "hello"); // true
119
+ * UriNormalizer.safeRegexCheck(/^[a-z]+$/, "Hello"); // false
120
+ *
121
+ * // Potentially catastrophic pattern on long input
122
+ * try {
123
+ * UriNormalizer.safeRegexCheck(/(a+)+$/, "a".repeat(5000) + "!");
124
+ * } catch (e) {
125
+ * if (e instanceof UriNormalizerRegexTimeoutError) {
126
+ * console.warn("ReDoS blocked: ", e.message);
127
+ * }
128
+ * }
129
+ * ```
130
+ */
131
+ static safeRegexCheck(pattern, str, timeoutMs = UriNormalizer.REGEX_BASE_TIMEOUT_MS) {
132
+ // Strict pattern validation for a clear error message
133
+ if (!(pattern instanceof RegExp)) {
134
+ throw new TypeError(`UriNormalizer.safeRegexCheck: "pattern" must be an instance of RegExp, received: ${typeof pattern}`);
135
+ }
136
+ // Fast path for very short strings (negligible ReDoS risk)
137
+ if (str.length < UriNormalizer.REGEX_VM_LENGTH_THRESHOLD) {
138
+ return pattern.test(str);
139
+ }
140
+ // Calculate adaptive timeout
141
+ const effectiveTimeout = UriNormalizer.computeRegexTimeout(str.length, timeoutMs);
142
+ try {
143
+ const sandbox = { result: false, pattern, str };
144
+ const context = vm.createContext(sandbox);
145
+ vm.runInContext("result = pattern.test(str)", context, {
146
+ timeout: effectiveTimeout,
147
+ });
148
+ return sandbox.result;
149
+ }
150
+ catch (e) {
151
+ // Distinguish a VM timeout from an unexpected error
152
+ if (UriNormalizer.isVmTimeoutError(e)) {
153
+ throw new UriNormalizerRegexTimeoutError(`Regex exceeded timeout (${effectiveTimeout}ms) on an input of ${str.length} characters. Possible ReDoS.`, effectiveTimeout, str.length);
154
+ }
155
+ // Propagate any other VM error (e.g., internal syntax error)
156
+ throw e;
157
+ }
158
+ }
159
+ // ─────────────────────────────────────────────────────────────────────────
160
+ // Private Methods — URI Decoding
161
+ // ─────────────────────────────────────────────────────────────────────────
162
+ /**
163
+ * Iteratively decodes a URI path until it is stable (idempotent),
164
+ * neutralizing double-encodings and cascading encodings.
165
+ *
166
+ * **Example of bypass without this protection:**
167
+ * ```
168
+ * %2520 → (1st decode) %20 → (2nd decode) " "
169
+ * %252E%252E → %2E%2E → .. ← hidden traversal
170
+ * ```
171
+ *
172
+ * The loop is bounded to {@link MAX_DECODE_ITERATIONS} to prevent any
173
+ * infinite loop on pathological synthetic inputs. If the limit is reached,
174
+ * the last stable state is returned without throwing an exception.
175
+ *
176
+ * @param {string} raw - The raw string, potentially multi-encoded.
177
+ * @returns {string} The fully decoded string.
178
+ *
179
+ * @private
180
+ */
181
+ static iterativeDecode(raw) {
182
+ let current = raw;
183
+ for (let i = 0; i < UriNormalizer.MAX_DECODE_ITERATIONS; i++) {
184
+ let next;
185
+ try {
186
+ next = decodeURIComponent(current);
187
+ }
188
+ catch {
189
+ // Malformed URI (e.g., `%GG`): abort and keep previous state
190
+ break;
191
+ }
192
+ if (next === current) {
193
+ // Idempotence reached: decoding is stable
194
+ break;
195
+ }
196
+ current = next;
197
+ }
198
+ return current;
199
+ }
200
+ // ─────────────────────────────────────────────────────────────────────────
201
+ // Private Methods — String Sanitization
202
+ // ─────────────────────────────────────────────────────────────────────────
203
+ /**
204
+ * Strips all ASCII and Unicode control characters from a string.
205
+ *
206
+ * The removed ranges are:
207
+ * - U+0000–U+001F: C0 control characters (including null byte, tab, LF, CR...)
208
+ * - U+007F : DEL
209
+ * - U+0080–U+009F: C1 control characters
210
+ *
211
+ * These characters can be exploited to bypass filters relying on naive
212
+ * string comparisons or to cause unexpected behavior in downstream parsers
213
+ * (e.g., HTTP servers, file systems).
214
+ *
215
+ * @param {string} str - The string to sanitize.
216
+ * @returns {string} The string without control characters.
217
+ *
218
+ * @private
219
+ */
220
+ static stripControlCharacters(str) {
221
+ // eslint-disable-next-line no-control-regex
222
+ return str.replace(/[\u0000-\u001F\u007F-\u009F]/g, "");
223
+ }
224
+ // ─────────────────────────────────────────────────────────────────────────
225
+ // Private Methods — Segment Resolution
226
+ // ─────────────────────────────────────────────────────────────────────────
227
+ /**
228
+ * Resolves `.` (current directory) and `..` (parent directory) segments
229
+ * from a normalized path (without double-slashes or residual encodings).
230
+ *
231
+ * The stack can never go below the root: a `..` at the head of the path
232
+ * is silently ignored, preventing any underflow to `../`.
233
+ *
234
+ * @param {string} path - The pre-normalized path (consolidated slashes, decoded).
235
+ * @returns {string} The path with all `.` and `..` segments resolved,
236
+ * always prefixed by `/`.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * // (private method — internal illustration)
241
+ * resolveSegments("/a/b/../../c") // "/c"
242
+ * resolveSegments("/../../../etc") // "/etc" ← no underflow
243
+ * resolveSegments("/a/./b") // "/a/b"
244
+ * ```
245
+ *
246
+ * @private
247
+ */
248
+ static resolveSegments(path) {
249
+ const parts = path.split("/");
250
+ const stack = [];
251
+ for (const segment of parts) {
252
+ if (segment === "..") {
253
+ // Never exceed root (anti-underflow)
254
+ if (stack.length > 0) {
255
+ stack.pop();
256
+ }
257
+ }
258
+ else if (segment !== "." && segment !== "") {
259
+ stack.push(segment);
260
+ }
261
+ }
262
+ return "/" + stack.join("/");
263
+ }
264
+ // ─────────────────────────────────────────────────────────────────────────
265
+ // Private Methods — ReDoS / VM Utilities
266
+ // ─────────────────────────────────────────────────────────────────────────
267
+ /**
268
+ * Calculates an adaptive timeout for executing a regex in the VM sandbox,
269
+ * adding a delta proportional to the length of the string being tested.
270
+ *
271
+ * ### Formula
272
+ * ```
273
+ * timeout = min(baseMs + floor(length / 1000) * PER_1K, MAX_TIMEOUT)
274
+ * ```
275
+ *
276
+ * This avoids false positives on long legitimate inputs while maintaining
277
+ * a hard ceiling ({@link REGEX_MAX_TIMEOUT_MS}) to contain severe ReDoS.
278
+ *
279
+ * @param {number} length - Length of the tested string.
280
+ * @param {number} baseMs - Base timeout provided by the caller.
281
+ * @returns {number} The effective timeout in milliseconds.
282
+ *
283
+ * @private
284
+ */
285
+ static computeRegexTimeout(length, baseMs) {
286
+ const delta = Math.floor(length / 1000) *
287
+ UriNormalizer.REGEX_TIMEOUT_PER_1K_CHARS;
288
+ return Math.min(baseMs + delta, UriNormalizer.REGEX_MAX_TIMEOUT_MS);
289
+ }
290
+ /**
291
+ * Determines whether an error thrown by `vm.runInContext` is a timeout
292
+ * overrun (i.e. a Node.js script interruption).
293
+ *
294
+ * Node.js does not provide a dedicated error class for this type of error.
295
+ * Detection relies on the `ERR_SCRIPT_EXECUTION_TIMEOUT` error code and/or
296
+ * the error message (`"Script execution timed out"`), which are stable since Node 10.
297
+ *
298
+ * @param {unknown} error - The exception to inspect.
299
+ * @returns {boolean} `true` if the error is a VM timeout, `false` otherwise.
300
+ *
301
+ * @private
302
+ */
303
+ static isVmTimeoutError(error) {
304
+ if (!(error instanceof Error))
305
+ return false;
306
+ const nodeError = error;
307
+ if (nodeError.code === "ERR_SCRIPT_EXECUTION_TIMEOUT")
308
+ return true;
309
+ // Fallback to the message for older Node versions
310
+ return error.message.toLowerCase().includes("timed out");
311
+ }
312
+ }
313
+ // ─────────────────────────────────────────────────────────────────────────
314
+ // Private Constants
315
+ // ─────────────────────────────────────────────────────────────────────────
316
+ /**
317
+ * Maximum number of URI decoding iterations to stop infinite loops
318
+ * on pathological inputs (e.g., synthetic infinite encodings).
319
+ */
320
+ UriNormalizer.MAX_DECODE_ITERATIONS = 10;
321
+ /**
322
+ * Minimum length (inclusive) from which regex execution is deferred
323
+ * to an isolated VM context with a timeout, regardless of the apparent
324
+ * complexity of the pattern.
325
+ *
326
+ * Lowered to 20 chars to cover catastrophic patterns on short
327
+ * repetitive inputs (e.g., `(a+)+` tested on `"aaaaaaaaaaaaaaaab"`).
328
+ */
329
+ UriNormalizer.REGEX_VM_LENGTH_THRESHOLD = 20;
330
+ /**
331
+ * Base VM timeout in milliseconds. It is proportionally increased
332
+ * according to the string length to avoid false positives on long
333
+ * legitimate inputs while keeping a hard limit on ReDoS.
334
+ *
335
+ * @see {@link UriNormalizer.computeRegexTimeout}
336
+ */
337
+ UriNormalizer.REGEX_BASE_TIMEOUT_MS = 50;
338
+ /**
339
+ * Multiplicative factor (ms per 1,000 characters) added to the base
340
+ * timeout for long strings. This prevents false positives on large
341
+ * legitimate inputs.
342
+ */
343
+ UriNormalizer.REGEX_TIMEOUT_PER_1K_CHARS = 5;
344
+ /**
345
+ * Absolute ceiling for the VM timeout in milliseconds to prevent
346
+ * a massive input from rendering the timeout useless.
347
+ */
348
+ UriNormalizer.REGEX_MAX_TIMEOUT_MS = 200;
349
+ // ─────────────────────────────────────────────────────────────────────────────
350
+ // Custom Errors
351
+ // ─────────────────────────────────────────────────────────────────────────────
352
+ /**
353
+ * Error thrown by {@link UriNormalizer.safeRegexCheck} when regex execution
354
+ * in the VM context exceeds the allocated timeout.
355
+ *
356
+ * This error allows the calling layer to distinguish a true ReDoS block
357
+ * from a legitimate `false` return (normal non-match), and to apply an
358
+ * appropriate security policy (log, alert, block the request...).
359
+ *
360
+ * @extends {Error}
361
+ *
362
+ * @example
363
+ * ```ts
364
+ * try {
365
+ * UriNormalizer.safeRegexCheck(/(a+)+$/, "a".repeat(10_000) + "!");
366
+ * } catch (e) {
367
+ * if (e instanceof UriNormalizerRegexTimeoutError) {
368
+ * console.error(`ReDoS detected (timeout=${e.timeoutMs}ms, len=${e.inputLength})`);
369
+ * }
370
+ * }
371
+ * ```
372
+ */
373
+ class UriNormalizerRegexTimeoutError extends Error {
374
+ /**
375
+ * @param {string} message - Descriptive error message.
376
+ * @param {number} timeoutMs - Exceeded effective timeout.
377
+ * @param {number} inputLength - Length of the tested input.
378
+ */
379
+ constructor(message, timeoutMs, inputLength) {
380
+ super(message);
381
+ /** Class name for reliable instanceof and logging. */
382
+ this.name = "UriNormalizerRegexTimeoutError";
383
+ this.timeoutMs = timeoutMs;
384
+ this.inputLength = inputLength;
385
+ // Proper prototype chain restoration in TypeScript/Babel
386
+ Object.setPrototypeOf(this, new.target.prototype);
387
+ }
388
+ }
389
+
390
+ export { UriNormalizer, UriNormalizerRegexTimeoutError };
391
+ //# sourceMappingURL=UriNormalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UriNormalizer.js","sources":["../../../../../../src/middleware/built-in/security/UriNormalizer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}