@arcis/node 1.0.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 (52) hide show
  1. package/README.md +222 -0
  2. package/dist/core/index.d.mts +170 -0
  3. package/dist/core/index.d.ts +170 -0
  4. package/dist/core/index.js +327 -0
  5. package/dist/core/index.js.map +1 -0
  6. package/dist/core/index.mjs +307 -0
  7. package/dist/core/index.mjs.map +1 -0
  8. package/dist/headers-BJq2OA0i.d.ts +284 -0
  9. package/dist/headers-DBQedhrb.d.mts +284 -0
  10. package/dist/index-BgHPM7LC.d.ts +129 -0
  11. package/dist/index-BpT7flAQ.d.ts +255 -0
  12. package/dist/index-JaFOUKyK.d.mts +255 -0
  13. package/dist/index-nAgXexwD.d.mts +129 -0
  14. package/dist/index.d.mts +139 -0
  15. package/dist/index.d.ts +139 -0
  16. package/dist/index.js +1860 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/index.mjs +1797 -0
  19. package/dist/index.mjs.map +1 -0
  20. package/dist/logging/index.d.mts +38 -0
  21. package/dist/logging/index.d.ts +38 -0
  22. package/dist/logging/index.js +140 -0
  23. package/dist/logging/index.js.map +1 -0
  24. package/dist/logging/index.mjs +136 -0
  25. package/dist/logging/index.mjs.map +1 -0
  26. package/dist/middleware/index.d.mts +3 -0
  27. package/dist/middleware/index.d.ts +3 -0
  28. package/dist/middleware/index.js +1173 -0
  29. package/dist/middleware/index.js.map +1 -0
  30. package/dist/middleware/index.mjs +1156 -0
  31. package/dist/middleware/index.mjs.map +1 -0
  32. package/dist/sanitizers/index.d.mts +24 -0
  33. package/dist/sanitizers/index.d.ts +24 -0
  34. package/dist/sanitizers/index.js +610 -0
  35. package/dist/sanitizers/index.js.map +1 -0
  36. package/dist/sanitizers/index.mjs +587 -0
  37. package/dist/sanitizers/index.mjs.map +1 -0
  38. package/dist/stores/index.d.mts +106 -0
  39. package/dist/stores/index.d.ts +106 -0
  40. package/dist/stores/index.js +149 -0
  41. package/dist/stores/index.js.map +1 -0
  42. package/dist/stores/index.mjs +145 -0
  43. package/dist/stores/index.mjs.map +1 -0
  44. package/dist/types-BOdL3ZWo.d.mts +264 -0
  45. package/dist/types-BOdL3ZWo.d.ts +264 -0
  46. package/dist/validation/index.d.mts +3 -0
  47. package/dist/validation/index.d.ts +3 -0
  48. package/dist/validation/index.js +705 -0
  49. package/dist/validation/index.js.map +1 -0
  50. package/dist/validation/index.mjs +699 -0
  51. package/dist/validation/index.mjs.map +1 -0
  52. package/package.json +109 -0
@@ -0,0 +1,610 @@
1
+ 'use strict';
2
+
3
+ // src/core/constants.ts
4
+ var INPUT = {
5
+ /** Default maximum input size (1MB) */
6
+ DEFAULT_MAX_SIZE: 1e6,
7
+ /** Maximum recursion depth for nested objects */
8
+ MAX_RECURSION_DEPTH: 10
9
+ };
10
+ var XSS_PATTERNS = [
11
+ /** Script tags (ReDoS-safe version) */
12
+ /<script[^>]*>[\s\S]*?<\/script>/gi,
13
+ /** javascript: protocol (allow optional spaces before colon) */
14
+ /javascript\s*:/gi,
15
+ /** vbscript: protocol */
16
+ /vbscript\s*:/gi,
17
+ /** Event handlers (onclick, onerror, etc.) — any separator before attribute */
18
+ /(?:[\s/])on\w+\s*=/gi,
19
+ /** iframe tags */
20
+ /<iframe/gi,
21
+ /** object tags */
22
+ /<object/gi,
23
+ /** embed tags */
24
+ /<embed/gi,
25
+ /** data: URIs (only dangerous ones, avoid false positives) */
26
+ /(?:^|[\s"'=])data:/gi,
27
+ /** URL-encoded script tags */
28
+ /%3Cscript/gi,
29
+ /** SVG with onload */
30
+ /<svg[^>]*onload/gi
31
+ ];
32
+ var XSS_REMOVE_PATTERNS = [
33
+ /** Full script blocks (content + tags) */
34
+ /<script[^>]*>[\s\S]*?<\/script>/gi,
35
+ /** Standalone/unclosed script tags */
36
+ /<script[^>]*>/gi,
37
+ /** iframe — full block and partial/unclosed */
38
+ /<iframe[^>]*>[\s\S]*?<\/iframe>/gi,
39
+ /<iframe[^>]*/gi,
40
+ /** object — full block and partial/unclosed */
41
+ /<object[^>]*>[\s\S]*?<\/object>/gi,
42
+ /<object[^>]*/gi,
43
+ /** embed tags */
44
+ /<embed[^>]*/gi,
45
+ /** SVG with inline event handlers */
46
+ /<svg[^>]*onload[^>]*>/gi,
47
+ /** URL-encoded script tags */
48
+ /%3Cscript/gi,
49
+ /** Event handlers with quoted values: onclick="...", onerror='...' */
50
+ /(?:[\s/])on\w+\s*=\s*["'][^"']*["']/gi,
51
+ /** Event handlers with unquoted values: onload=value */
52
+ /(?:[\s/])on\w+\s*=\s*[^\s>]*/gi,
53
+ /** javascript: and vbscript: protocols (allow optional spaces before colon) */
54
+ /javascript\s*:/gi,
55
+ /vbscript\s*:/gi,
56
+ /** data: URIs with HTML/script content */
57
+ /data\s*:\s*text\/html[^>\s]*/gi
58
+ ];
59
+ var SQL_PATTERNS = [
60
+ /** SQL keywords */
61
+ /(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|TRUNCATE|EXEC|EXECUTE)\b)/gi,
62
+ /** SQL comments: ANSI (--), C-style (slash-star ... star-slash), MySQL (#) */
63
+ /(--|\/\*|\*\/|#)/g,
64
+ /** SQL statement separators */
65
+ /(;|\|\||&&)/g,
66
+ /** Boolean injection: OR 1=1 */
67
+ /\bOR\s+\d+\s*=\s*\d+/gi,
68
+ /** Boolean injection: OR 'a'='a' or OR "a"="a" (including mixed quotes) */
69
+ /\bOR\s+(['"])[^'"]*\1\s*=\s*(['"])[^'"]*\2/gi,
70
+ /\bOR\s+('[^']*'|"[^"]*")\s*=\s*('[^']*'|"[^"]*")/gi,
71
+ /** Boolean injection: AND 1=1 */
72
+ /\bAND\s+\d+\s*=\s*\d+/gi,
73
+ /** Boolean injection: AND 'a'='a' or AND "a"="a" (including mixed quotes) */
74
+ /\bAND\s+(['"])[^'"]*\1\s*=\s*(['"])[^'"]*\2/gi,
75
+ /\bAND\s+('[^']*'|"[^"]*")\s*=\s*('[^']*'|"[^"]*")/gi,
76
+ /** Time-based blind: SLEEP() */
77
+ /\bSLEEP\s*\(\s*\d+\s*\)/gi,
78
+ /** Time-based blind: BENCHMARK() */
79
+ /\bBENCHMARK\s*\(/gi
80
+ ];
81
+ var PATH_PATTERNS = [
82
+ /** Unix path traversal */
83
+ /\.\.\//g,
84
+ /** Windows path traversal */
85
+ /\.\.\\/g,
86
+ /** URL-encoded traversal (%2e%2e) */
87
+ /%2e%2e/gi,
88
+ /** Double URL-encoded traversal (%252e) */
89
+ /%252e/gi,
90
+ /** Mixed encoding: ..%2F */
91
+ /\.\.%2F/gi,
92
+ /** Mixed encoding: %2e./ and .%2e/ */
93
+ /%2e\.[\\/]/gi,
94
+ /\.%2e[\\/]/gi,
95
+ /** Fully URL-encoded: %2e%2e%2f */
96
+ /%2e%2e%2f/gi,
97
+ /** Null byte injection in paths */
98
+ /\0/g
99
+ ];
100
+ var COMMAND_PATTERNS = [
101
+ /**
102
+ * Shell metacharacters that enable command chaining/substitution.
103
+ * Bare ( and ) are excluded — they appear in common legitimate values
104
+ * (function calls in code fields, math expressions, etc.).
105
+ * Command substitution is caught by the $( combined pattern below.
106
+ * NOTE: ';', '&', '|' may appear in legitimate URL query strings
107
+ * and Markdown; consider disabling command checking (command: false)
108
+ * for fields that intentionally allow those characters.
109
+ */
110
+ /[;&|`]/g,
111
+ /** Command substitution: $( ... ) — matched as a pair to reduce false positives */
112
+ /\$\(/g
113
+ ];
114
+ var DANGEROUS_PROTO_KEYS = /* @__PURE__ */ new Set([
115
+ "__proto__",
116
+ "constructor",
117
+ "prototype",
118
+ "__definegetter__",
119
+ "__definesetter__",
120
+ "__lookupgetter__",
121
+ "__lookupsetter__"
122
+ ]);
123
+ var NOSQL_DANGEROUS_KEYS = /* @__PURE__ */ new Set([
124
+ // Comparison
125
+ "$gt",
126
+ "$gte",
127
+ "$lt",
128
+ "$lte",
129
+ "$ne",
130
+ "$eq",
131
+ "$in",
132
+ "$nin",
133
+ // Logical
134
+ "$and",
135
+ "$or",
136
+ "$not",
137
+ "$nor",
138
+ // Element / evaluation
139
+ "$exists",
140
+ "$type",
141
+ "$regex",
142
+ "$where",
143
+ "$expr",
144
+ "$mod",
145
+ "$text",
146
+ // Array
147
+ "$elemMatch",
148
+ "$all",
149
+ "$size",
150
+ // JavaScript execution (critical)
151
+ "$function",
152
+ "$accumulator",
153
+ // Aggregation pipeline operators (injectable via $lookup etc.)
154
+ "$lookup",
155
+ "$match",
156
+ "$project",
157
+ "$group",
158
+ "$sort",
159
+ "$limit",
160
+ "$skip",
161
+ "$unwind",
162
+ "$addFields",
163
+ "$replaceRoot"
164
+ ]);
165
+
166
+ // src/core/errors.ts
167
+ var ArcisError = class extends Error {
168
+ constructor(message, statusCode = 500, code = "ARCIS_ERROR") {
169
+ super(message);
170
+ this.name = "ArcisError";
171
+ this.statusCode = statusCode;
172
+ this.code = code;
173
+ this.expose = statusCode < 500;
174
+ if (Error.captureStackTrace) {
175
+ Error.captureStackTrace(this, this.constructor);
176
+ }
177
+ }
178
+ };
179
+ var InputTooLargeError = class extends ArcisError {
180
+ constructor(maxSize, actualSize) {
181
+ super(`Input exceeds maximum size of ${maxSize} bytes`, 413, "INPUT_TOO_LARGE");
182
+ this.name = "InputTooLargeError";
183
+ this.maxSize = maxSize;
184
+ this.actualSize = actualSize;
185
+ }
186
+ };
187
+ var SecurityThreatError = class extends ArcisError {
188
+ constructor(threatType, pattern) {
189
+ super("Request blocked for security reasons", 400, "SECURITY_THREAT");
190
+ this.name = "SecurityThreatError";
191
+ this.threatType = threatType;
192
+ this.pattern = pattern;
193
+ }
194
+ };
195
+
196
+ // src/sanitizers/utils.ts
197
+ function encodeHtmlEntities(str) {
198
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
199
+ }
200
+ function isPlainObject(value) {
201
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
202
+ return false;
203
+ }
204
+ const proto = Object.getPrototypeOf(value);
205
+ return proto === Object.prototype || proto === null;
206
+ }
207
+
208
+ // src/sanitizers/xss.ts
209
+ function sanitizeXss(input, collectThreats = false, htmlEncode = false) {
210
+ if (typeof input !== "string") {
211
+ return collectThreats ? { value: String(input), wasSanitized: false, threats: [] } : String(input);
212
+ }
213
+ const threats = [];
214
+ let value = input;
215
+ let wasSanitized = false;
216
+ for (const pattern of XSS_REMOVE_PATTERNS) {
217
+ pattern.lastIndex = 0;
218
+ if (pattern.test(value)) {
219
+ pattern.lastIndex = 0;
220
+ if (collectThreats) {
221
+ const matches = value.match(pattern);
222
+ if (matches) {
223
+ for (const match of matches) {
224
+ threats.push({
225
+ type: "xss",
226
+ pattern: pattern.source,
227
+ original: match
228
+ });
229
+ }
230
+ }
231
+ }
232
+ value = value.replace(pattern, "");
233
+ wasSanitized = true;
234
+ }
235
+ }
236
+ if (htmlEncode) {
237
+ const encoded = encodeHtmlEntities(value);
238
+ if (encoded !== value) {
239
+ wasSanitized = true;
240
+ }
241
+ value = encoded;
242
+ }
243
+ if (collectThreats) {
244
+ return { value, wasSanitized, threats };
245
+ }
246
+ return value;
247
+ }
248
+ function detectXss(input) {
249
+ if (typeof input !== "string") return false;
250
+ if (/\s+on\w+\s*=/i.test(input)) return true;
251
+ if (/javascript\s*:/i.test(input)) return true;
252
+ if (/vbscript\s*:/i.test(input)) return true;
253
+ if (/data\s*:\s*text\/html/i.test(input)) return true;
254
+ for (const pattern of XSS_PATTERNS) {
255
+ pattern.lastIndex = 0;
256
+ if (pattern.test(input)) {
257
+ return true;
258
+ }
259
+ }
260
+ return false;
261
+ }
262
+
263
+ // src/sanitizers/sql.ts
264
+ function sanitizeSql(input, collectThreats = false) {
265
+ if (typeof input !== "string") {
266
+ return collectThreats ? { value: String(input), wasSanitized: false, threats: [] } : String(input);
267
+ }
268
+ const threats = [];
269
+ let value = input;
270
+ let wasSanitized = false;
271
+ for (const pattern of SQL_PATTERNS) {
272
+ pattern.lastIndex = 0;
273
+ if (pattern.test(value)) {
274
+ pattern.lastIndex = 0;
275
+ if (collectThreats) {
276
+ const matches = value.match(pattern);
277
+ if (matches) {
278
+ for (const match of matches) {
279
+ threats.push({
280
+ type: "sql_injection",
281
+ pattern: pattern.source,
282
+ original: match
283
+ });
284
+ }
285
+ }
286
+ }
287
+ value = value.replace(pattern, " ");
288
+ wasSanitized = true;
289
+ }
290
+ }
291
+ if (collectThreats) {
292
+ return { value, wasSanitized, threats };
293
+ }
294
+ return value;
295
+ }
296
+ function detectSql(input) {
297
+ if (typeof input !== "string") return false;
298
+ for (const pattern of SQL_PATTERNS) {
299
+ pattern.lastIndex = 0;
300
+ if (pattern.test(input)) {
301
+ return true;
302
+ }
303
+ }
304
+ return false;
305
+ }
306
+
307
+ // src/sanitizers/path.ts
308
+ function sanitizePath(input, collectThreats = false) {
309
+ if (typeof input !== "string") {
310
+ return collectThreats ? { value: String(input), wasSanitized: false, threats: [] } : String(input);
311
+ }
312
+ const threats = [];
313
+ let value = input;
314
+ let wasSanitized = false;
315
+ for (const pattern of PATH_PATTERNS) {
316
+ pattern.lastIndex = 0;
317
+ if (pattern.test(value)) {
318
+ pattern.lastIndex = 0;
319
+ if (collectThreats) {
320
+ const matches = value.match(pattern);
321
+ if (matches) {
322
+ for (const match of matches) {
323
+ threats.push({
324
+ type: "path_traversal",
325
+ pattern: pattern.source,
326
+ original: match
327
+ });
328
+ }
329
+ }
330
+ }
331
+ value = value.replace(pattern, "");
332
+ wasSanitized = true;
333
+ }
334
+ }
335
+ if (collectThreats) {
336
+ return { value, wasSanitized, threats };
337
+ }
338
+ return value;
339
+ }
340
+ function detectPathTraversal(input) {
341
+ if (typeof input !== "string") return false;
342
+ for (const pattern of PATH_PATTERNS) {
343
+ pattern.lastIndex = 0;
344
+ if (pattern.test(input)) {
345
+ return true;
346
+ }
347
+ }
348
+ return false;
349
+ }
350
+
351
+ // src/sanitizers/command.ts
352
+ function sanitizeCommand(input, collectThreats = false) {
353
+ if (typeof input !== "string") {
354
+ return collectThreats ? { value: String(input), wasSanitized: false, threats: [] } : String(input);
355
+ }
356
+ const threats = [];
357
+ let value = input;
358
+ let wasSanitized = false;
359
+ for (const pattern of COMMAND_PATTERNS) {
360
+ pattern.lastIndex = 0;
361
+ if (pattern.test(value)) {
362
+ pattern.lastIndex = 0;
363
+ if (collectThreats) {
364
+ const matches = value.match(pattern);
365
+ if (matches) {
366
+ for (const match of matches) {
367
+ threats.push({
368
+ type: "command_injection",
369
+ pattern: pattern.source,
370
+ original: match
371
+ });
372
+ }
373
+ }
374
+ }
375
+ value = value.replace(pattern, " ");
376
+ wasSanitized = true;
377
+ }
378
+ }
379
+ if (collectThreats) {
380
+ return { value, wasSanitized, threats };
381
+ }
382
+ return value;
383
+ }
384
+ function detectCommandInjection(input) {
385
+ if (typeof input !== "string") return false;
386
+ for (const pattern of COMMAND_PATTERNS) {
387
+ pattern.lastIndex = 0;
388
+ if (pattern.test(input)) {
389
+ return true;
390
+ }
391
+ }
392
+ return false;
393
+ }
394
+
395
+ // src/sanitizers/sanitize.ts
396
+ function sanitizeString(value, options = {}) {
397
+ if (typeof value !== "string") return value;
398
+ const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
399
+ if (value.length > maxSize) {
400
+ throw new InputTooLargeError(maxSize, value.length);
401
+ }
402
+ const reject = options.mode !== "sanitize";
403
+ let result = value;
404
+ if (options.sql !== false) {
405
+ if (reject) {
406
+ if (detectSql(result)) {
407
+ throw new SecurityThreatError("sql_injection", "SQL pattern detected in input");
408
+ }
409
+ } else {
410
+ result = sanitizeSql(result);
411
+ }
412
+ }
413
+ if (options.path !== false) {
414
+ result = sanitizePath(result);
415
+ }
416
+ if (options.command !== false) {
417
+ if (reject) {
418
+ if (detectCommandInjection(result)) {
419
+ throw new SecurityThreatError("command_injection", "Shell metacharacter detected in input");
420
+ }
421
+ } else {
422
+ result = sanitizeCommand(result);
423
+ }
424
+ }
425
+ if (options.xss !== false) {
426
+ result = sanitizeXss(result, false, options.htmlEncode ?? false);
427
+ }
428
+ return result;
429
+ }
430
+ function sanitizeObject(obj, options = {}) {
431
+ if (obj === null || obj === void 0) return obj;
432
+ if (typeof obj === "string") return sanitizeString(obj, options);
433
+ if (typeof obj !== "object") return obj;
434
+ if (Array.isArray(obj)) return obj.map((item) => sanitizeObject(item, options));
435
+ return sanitizeObjectDepth(obj, options, 0);
436
+ }
437
+ function sanitizeObjectDepth(obj, options, depth) {
438
+ if (depth >= INPUT.MAX_RECURSION_DEPTH) return obj;
439
+ const result = {};
440
+ for (const key of Object.keys(obj)) {
441
+ if (options.proto !== false && DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
442
+ continue;
443
+ }
444
+ if (options.nosql !== false && NOSQL_DANGEROUS_KEYS.has(key)) {
445
+ continue;
446
+ }
447
+ const sanitizedKey = sanitizeString(key, options);
448
+ const value = obj[key];
449
+ if (value === null || value === void 0) {
450
+ result[sanitizedKey] = value;
451
+ } else if (typeof value === "string") {
452
+ result[sanitizedKey] = sanitizeString(value, options);
453
+ } else if (Array.isArray(value)) {
454
+ result[sanitizedKey] = value.map((item) => sanitizeObject(item, options));
455
+ } else if (typeof value === "object") {
456
+ result[sanitizedKey] = sanitizeObjectDepth(value, options, depth + 1);
457
+ } else {
458
+ result[sanitizedKey] = value;
459
+ }
460
+ }
461
+ return result;
462
+ }
463
+ function createSanitizer(options = {}) {
464
+ return (req, _res, next) => {
465
+ try {
466
+ if (req.body && typeof req.body === "object") {
467
+ req.body = sanitizeObject(req.body, options);
468
+ }
469
+ if (req.query && typeof req.query === "object") {
470
+ const sanitizedQuery = sanitizeObject(req.query, options);
471
+ Object.defineProperty(req, "query", { value: sanitizedQuery, writable: true, configurable: true });
472
+ }
473
+ if (req.params && typeof req.params === "object") {
474
+ const sanitizedParams = sanitizeObject(req.params, options);
475
+ Object.defineProperty(req, "params", { value: sanitizedParams, writable: true, configurable: true });
476
+ }
477
+ next();
478
+ } catch (err) {
479
+ next(err);
480
+ }
481
+ };
482
+ }
483
+
484
+ // src/sanitizers/nosql.ts
485
+ function isDangerousNoSqlKey(key) {
486
+ return NOSQL_DANGEROUS_KEYS.has(key);
487
+ }
488
+ function detectNoSqlInjection(obj, maxDepth = 10) {
489
+ if (maxDepth <= 0) return false;
490
+ if (obj === null || typeof obj !== "object") return false;
491
+ if (Array.isArray(obj)) {
492
+ return obj.some((item) => detectNoSqlInjection(item, maxDepth - 1));
493
+ }
494
+ for (const key of Object.keys(obj)) {
495
+ if (isDangerousNoSqlKey(key)) {
496
+ return true;
497
+ }
498
+ const value = obj[key];
499
+ if (typeof value === "object" && value !== null) {
500
+ if (detectNoSqlInjection(value, maxDepth - 1)) {
501
+ return true;
502
+ }
503
+ }
504
+ }
505
+ return false;
506
+ }
507
+ function getDangerousOperators() {
508
+ return Array.from(NOSQL_DANGEROUS_KEYS);
509
+ }
510
+
511
+ // src/sanitizers/prototype.ts
512
+ function isDangerousProtoKey(key) {
513
+ return DANGEROUS_PROTO_KEYS.has(key.toLowerCase());
514
+ }
515
+ function detectPrototypePollution(obj, maxDepth = 10) {
516
+ if (maxDepth <= 0) return false;
517
+ if (obj === null || typeof obj !== "object") return false;
518
+ if (Array.isArray(obj)) {
519
+ return obj.some((item) => detectPrototypePollution(item, maxDepth - 1));
520
+ }
521
+ for (const key of Object.keys(obj)) {
522
+ if (DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
523
+ return true;
524
+ }
525
+ const value = obj[key];
526
+ if (typeof value === "object" && value !== null) {
527
+ if (detectPrototypePollution(value, maxDepth - 1)) {
528
+ return true;
529
+ }
530
+ }
531
+ }
532
+ return false;
533
+ }
534
+ function getDangerousProtoKeys() {
535
+ return Array.from(DANGEROUS_PROTO_KEYS);
536
+ }
537
+
538
+ // src/sanitizers/headers.ts
539
+ var HEADER_INJECTION_PATTERN = /\r\n|\r|\n|\0/g;
540
+ function sanitizeHeaderValue(input, collectThreats = false) {
541
+ if (typeof input !== "string") {
542
+ return collectThreats ? { value: String(input), wasSanitized: false, threats: [] } : String(input);
543
+ }
544
+ const threats = [];
545
+ let wasSanitized = false;
546
+ if (HEADER_INJECTION_PATTERN.test(input)) {
547
+ HEADER_INJECTION_PATTERN.lastIndex = 0;
548
+ wasSanitized = true;
549
+ if (collectThreats) {
550
+ const matches = input.match(HEADER_INJECTION_PATTERN);
551
+ if (matches) {
552
+ for (const match of matches) {
553
+ threats.push({
554
+ type: "header_injection",
555
+ pattern: HEADER_INJECTION_PATTERN.source,
556
+ original: match
557
+ });
558
+ }
559
+ }
560
+ }
561
+ }
562
+ HEADER_INJECTION_PATTERN.lastIndex = 0;
563
+ const value = input.replace(HEADER_INJECTION_PATTERN, "");
564
+ if (collectThreats) {
565
+ return { value, wasSanitized, threats };
566
+ }
567
+ return value;
568
+ }
569
+ function sanitizeHeaders(headers) {
570
+ if (!headers || typeof headers !== "object") {
571
+ return {};
572
+ }
573
+ const result = {};
574
+ for (const [key, value] of Object.entries(headers)) {
575
+ const sanitizedKey = sanitizeHeaderValue(String(key));
576
+ const sanitizedValue = sanitizeHeaderValue(String(value));
577
+ result[sanitizedKey] = sanitizedValue;
578
+ }
579
+ return result;
580
+ }
581
+ function detectHeaderInjection(input) {
582
+ if (typeof input !== "string") return false;
583
+ HEADER_INJECTION_PATTERN.lastIndex = 0;
584
+ return HEADER_INJECTION_PATTERN.test(input);
585
+ }
586
+
587
+ exports.createSanitizer = createSanitizer;
588
+ exports.detectCommandInjection = detectCommandInjection;
589
+ exports.detectHeaderInjection = detectHeaderInjection;
590
+ exports.detectNoSqlInjection = detectNoSqlInjection;
591
+ exports.detectPathTraversal = detectPathTraversal;
592
+ exports.detectPrototypePollution = detectPrototypePollution;
593
+ exports.detectSql = detectSql;
594
+ exports.detectXss = detectXss;
595
+ exports.encodeHtmlEntities = encodeHtmlEntities;
596
+ exports.getDangerousOperators = getDangerousOperators;
597
+ exports.getDangerousProtoKeys = getDangerousProtoKeys;
598
+ exports.isDangerousNoSqlKey = isDangerousNoSqlKey;
599
+ exports.isDangerousProtoKey = isDangerousProtoKey;
600
+ exports.isPlainObject = isPlainObject;
601
+ exports.sanitizeCommand = sanitizeCommand;
602
+ exports.sanitizeHeaderValue = sanitizeHeaderValue;
603
+ exports.sanitizeHeaders = sanitizeHeaders;
604
+ exports.sanitizeObject = sanitizeObject;
605
+ exports.sanitizePath = sanitizePath;
606
+ exports.sanitizeSql = sanitizeSql;
607
+ exports.sanitizeString = sanitizeString;
608
+ exports.sanitizeXss = sanitizeXss;
609
+ //# sourceMappingURL=index.js.map
610
+ //# sourceMappingURL=index.js.map