@arcis/node 1.4.3 → 1.4.4

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 (45) hide show
  1. package/README.md +11 -3
  2. package/dist/cli/arcis.d.ts +23 -0
  3. package/dist/cli/arcis.d.ts.map +1 -0
  4. package/dist/cli/arcis.js +312 -0
  5. package/dist/cli/arcis.js.map +1 -0
  6. package/dist/cli/arcis.mjs +309 -0
  7. package/dist/cli/arcis.mjs.map +1 -0
  8. package/dist/core/constants.d.ts +1 -1
  9. package/dist/core/constants.d.ts.map +1 -1
  10. package/dist/core/index.js +4 -1
  11. package/dist/core/index.js.map +1 -1
  12. package/dist/core/index.mjs +4 -1
  13. package/dist/core/index.mjs.map +1 -1
  14. package/dist/core/types.d.ts +11 -0
  15. package/dist/core/types.d.ts.map +1 -1
  16. package/dist/index.js +253 -141
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +253 -141
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/logging/index.js.map +1 -1
  21. package/dist/logging/index.mjs.map +1 -1
  22. package/dist/middleware/bot-detection.d.ts.map +1 -1
  23. package/dist/middleware/csrf.d.ts.map +1 -1
  24. package/dist/middleware/index.js +224 -3
  25. package/dist/middleware/index.js.map +1 -1
  26. package/dist/middleware/index.mjs +224 -3
  27. package/dist/middleware/index.mjs.map +1 -1
  28. package/dist/middleware/main.d.ts.map +1 -1
  29. package/dist/sanitizers/index.d.ts +2 -1
  30. package/dist/sanitizers/index.d.ts.map +1 -1
  31. package/dist/sanitizers/index.js +213 -145
  32. package/dist/sanitizers/index.js.map +1 -1
  33. package/dist/sanitizers/index.mjs +213 -146
  34. package/dist/sanitizers/index.mjs.map +1 -1
  35. package/dist/sanitizers/sanitize.d.ts +13 -0
  36. package/dist/sanitizers/sanitize.d.ts.map +1 -1
  37. package/dist/stores/index.js.map +1 -1
  38. package/dist/stores/index.mjs.map +1 -1
  39. package/dist/telemetry/client.d.ts +3 -0
  40. package/dist/telemetry/client.d.ts.map +1 -1
  41. package/dist/telemetry/types.d.ts +12 -0
  42. package/dist/telemetry/types.d.ts.map +1 -1
  43. package/dist/validation/index.js.map +1 -1
  44. package/dist/validation/index.mjs.map +1 -1
  45. package/package.json +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/middleware/main.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,oBAAoB,EAIrB,MAAM,eAAe,CAAC;AAwCvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,oBAAoB,CAyDtE;AAGD,QAAA,MAAM,gBAAgB,EAAY,aAAa,CAAC;AAQhD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,CAAC;AAC7C,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/middleware/main.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,oBAAoB,EAIrB,MAAM,eAAe,CAAC;AAwCvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,oBAAoB,CA4DtE;AAGD,QAAA,MAAM,gBAAgB,EAAY,aAAa,CAAC;AAQhD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,CAAC;AAC7C,eAAe,gBAAgB,CAAC"}
@@ -2,7 +2,8 @@
2
2
  * @module @arcis/node/sanitizers
3
3
  * All sanitization functions for Arcis
4
4
  */
5
- export { sanitizeString, sanitizeObject, createSanitizer } from './sanitize';
5
+ export { sanitizeString, sanitizeObject, createSanitizer, scanThreats } from './sanitize';
6
+ export type { ThreatHit } from './sanitize';
6
7
  export { sanitizeXss, detectXss } from './xss';
7
8
  export { sanitizeSql, detectSql } from './sql';
8
9
  export { sanitizePath, detectPathTraversal } from './path';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sanitizers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG3F,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGnG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGxF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAGtF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGtG,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sanitizers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG3F,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGnG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGxF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAGtF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGtG,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -35,7 +35,10 @@ var XSS_PATTERNS = [
35
35
  /** base href hijacking — redirects all relative URLs to attacker domain */
36
36
  /<base[\s>]/gi,
37
37
  /** link tag injection — stylesheet or preload CSRF attacks */
38
- /<link[\s>]/gi
38
+ /<link[\s>]/gi,
39
+ /** style tag — CSS expression() / behavior: / IE-era attacks. Mirrors
40
+ * Python's xss-style-tag from packages/core/patterns.json. */
41
+ /<style[\s>]/gi
39
42
  ];
40
43
  var XSS_REMOVE_PATTERNS = [
41
44
  /** Full script blocks (content + tags) */
@@ -428,150 +431,6 @@ function detectCommandInjection(input) {
428
431
  return false;
429
432
  }
430
433
 
431
- // src/sanitizers/sanitize.ts
432
- function sanitizeString(value, options = {}) {
433
- if (typeof value !== "string") return value;
434
- const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
435
- if (value.length > maxSize) {
436
- throw new InputTooLargeError(maxSize, value.length);
437
- }
438
- const reject = options.mode === "reject";
439
- let result = value;
440
- if (options.sql !== false) {
441
- if (reject) {
442
- if (detectSql(result)) {
443
- throw new SecurityThreatError("sql_injection", "SQL pattern detected in input");
444
- }
445
- } else {
446
- result = sanitizeSql(result);
447
- }
448
- }
449
- if (options.path !== false) {
450
- result = sanitizePath(result);
451
- }
452
- if (options.command !== false) {
453
- if (reject) {
454
- if (detectCommandInjection(result)) {
455
- throw new SecurityThreatError("command_injection", "Shell metacharacter detected in input");
456
- }
457
- } else {
458
- result = sanitizeCommand(result);
459
- }
460
- }
461
- if (options.xss !== false) {
462
- result = sanitizeXss(result, false, options.htmlEncode ?? false);
463
- }
464
- return result;
465
- }
466
- function sanitizeObject(obj, options = {}) {
467
- if (obj === null || obj === void 0) return obj;
468
- if (typeof obj === "string") return sanitizeString(obj, options);
469
- if (typeof obj !== "object") return obj;
470
- if (Array.isArray(obj)) return obj.map((item) => sanitizeObject(item, options));
471
- const result = sanitizeObjectDepth(obj, options, 0);
472
- return options.freeze ? Object.freeze(result) : result;
473
- }
474
- function sanitizeObjectDepth(obj, options, depth) {
475
- if (depth >= INPUT.MAX_RECURSION_DEPTH) return obj;
476
- const result = {};
477
- for (const key of Object.keys(obj)) {
478
- if (options.proto !== false && DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
479
- continue;
480
- }
481
- if (options.nosql !== false && NOSQL_DANGEROUS_KEYS.has(key)) {
482
- continue;
483
- }
484
- const sanitizedKey = sanitizeString(key, options);
485
- const value = obj[key];
486
- if (value === null || value === void 0) {
487
- result[sanitizedKey] = value;
488
- } else if (typeof value === "string") {
489
- result[sanitizedKey] = sanitizeString(value, options);
490
- } else if (Array.isArray(value)) {
491
- result[sanitizedKey] = value.map((item) => sanitizeObject(item, options));
492
- } else if (typeof value === "object") {
493
- result[sanitizedKey] = sanitizeObjectDepth(value, options, depth + 1);
494
- } else {
495
- result[sanitizedKey] = value;
496
- }
497
- }
498
- return result;
499
- }
500
- function createSanitizer(options = {}) {
501
- return (req, _res, next) => {
502
- try {
503
- if (req.body && typeof req.body === "object") {
504
- req.body = sanitizeObject(req.body, options);
505
- }
506
- if (req.query && typeof req.query === "object") {
507
- const sanitizedQuery = sanitizeObject(req.query, options);
508
- Object.defineProperty(req, "query", { value: sanitizedQuery, writable: true, configurable: true });
509
- }
510
- if (req.params && typeof req.params === "object") {
511
- const sanitizedParams = sanitizeObject(req.params, options);
512
- Object.defineProperty(req, "params", { value: sanitizedParams, writable: true, configurable: true });
513
- }
514
- next();
515
- } catch (err) {
516
- next(err);
517
- }
518
- };
519
- }
520
-
521
- // src/sanitizers/nosql.ts
522
- function isDangerousNoSqlKey(key) {
523
- return NOSQL_DANGEROUS_KEYS.has(key);
524
- }
525
- function detectNoSqlInjection(obj, maxDepth = 10) {
526
- if (maxDepth <= 0) return false;
527
- if (obj === null || typeof obj !== "object") return false;
528
- if (Array.isArray(obj)) {
529
- return obj.some((item) => detectNoSqlInjection(item, maxDepth - 1));
530
- }
531
- for (const key of Object.keys(obj)) {
532
- if (isDangerousNoSqlKey(key)) {
533
- return true;
534
- }
535
- const value = obj[key];
536
- if (typeof value === "object" && value !== null) {
537
- if (detectNoSqlInjection(value, maxDepth - 1)) {
538
- return true;
539
- }
540
- }
541
- }
542
- return false;
543
- }
544
- function getDangerousOperators() {
545
- return Array.from(NOSQL_DANGEROUS_KEYS);
546
- }
547
-
548
- // src/sanitizers/prototype.ts
549
- function isDangerousProtoKey(key) {
550
- return DANGEROUS_PROTO_KEYS.has(key.toLowerCase());
551
- }
552
- function detectPrototypePollution(obj, maxDepth = 10) {
553
- if (maxDepth <= 0) return false;
554
- if (obj === null || typeof obj !== "object") return false;
555
- if (Array.isArray(obj)) {
556
- return obj.some((item) => detectPrototypePollution(item, maxDepth - 1));
557
- }
558
- for (const key of Object.keys(obj)) {
559
- if (DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
560
- return true;
561
- }
562
- const value = obj[key];
563
- if (typeof value === "object" && value !== null) {
564
- if (detectPrototypePollution(value, maxDepth - 1)) {
565
- return true;
566
- }
567
- }
568
- }
569
- return false;
570
- }
571
- function getDangerousProtoKeys() {
572
- return Array.from(DANGEROUS_PROTO_KEYS);
573
- }
574
-
575
434
  // src/sanitizers/ssti.ts
576
435
  var SSTI_DETECT_PATTERNS = [
577
436
  /** Jinja2 / Twig / Nunjucks: {{ ... }} */
@@ -734,6 +593,214 @@ function detectXxe(input) {
734
593
  return false;
735
594
  }
736
595
 
596
+ // src/sanitizers/sanitize.ts
597
+ function sanitizeString(value, options = {}) {
598
+ if (typeof value !== "string") return value;
599
+ const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
600
+ if (value.length > maxSize) {
601
+ throw new InputTooLargeError(maxSize, value.length);
602
+ }
603
+ const reject = options.mode === "reject";
604
+ let result = value;
605
+ if (options.sql !== false) {
606
+ if (reject) {
607
+ if (detectSql(result)) {
608
+ throw new SecurityThreatError("sql_injection", "SQL pattern detected in input");
609
+ }
610
+ } else {
611
+ result = sanitizeSql(result);
612
+ }
613
+ }
614
+ if (options.path !== false) {
615
+ result = sanitizePath(result);
616
+ }
617
+ if (options.command !== false) {
618
+ if (reject) {
619
+ if (detectCommandInjection(result)) {
620
+ throw new SecurityThreatError("command_injection", "Shell metacharacter detected in input");
621
+ }
622
+ } else {
623
+ result = sanitizeCommand(result);
624
+ }
625
+ }
626
+ if (options.xss !== false) {
627
+ result = sanitizeXss(result, false, options.htmlEncode ?? false);
628
+ }
629
+ return result;
630
+ }
631
+ function sanitizeObject(obj, options = {}) {
632
+ if (obj === null || obj === void 0) return obj;
633
+ if (typeof obj === "string") return sanitizeString(obj, options);
634
+ if (typeof obj !== "object") return obj;
635
+ if (Array.isArray(obj)) return obj.map((item) => sanitizeObject(item, options));
636
+ const result = sanitizeObjectDepth(obj, options, 0);
637
+ return options.freeze ? Object.freeze(result) : result;
638
+ }
639
+ function sanitizeObjectDepth(obj, options, depth) {
640
+ if (depth >= INPUT.MAX_RECURSION_DEPTH) return obj;
641
+ const result = {};
642
+ for (const key of Object.keys(obj)) {
643
+ if (options.proto !== false && DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
644
+ continue;
645
+ }
646
+ if (options.nosql !== false && NOSQL_DANGEROUS_KEYS.has(key)) {
647
+ continue;
648
+ }
649
+ const sanitizedKey = sanitizeString(key, options);
650
+ const value = obj[key];
651
+ if (value === null || value === void 0) {
652
+ result[sanitizedKey] = value;
653
+ } else if (typeof value === "string") {
654
+ result[sanitizedKey] = sanitizeString(value, options);
655
+ } else if (Array.isArray(value)) {
656
+ result[sanitizedKey] = value.map((item) => sanitizeObject(item, options));
657
+ } else if (typeof value === "object") {
658
+ result[sanitizedKey] = sanitizeObjectDepth(value, options, depth + 1);
659
+ } else {
660
+ result[sanitizedKey] = value;
661
+ }
662
+ }
663
+ return result;
664
+ }
665
+ function scanThreats(data, depth = 0) {
666
+ if (depth > INPUT.MAX_RECURSION_DEPTH) return null;
667
+ if (data && typeof data === "object" && !Array.isArray(data)) {
668
+ for (const key of Object.keys(data)) {
669
+ const lower = key.toLowerCase();
670
+ if (DANGEROUS_PROTO_KEYS.has(lower)) {
671
+ return { vector: "prototype", rule: "prototype/match", matchedPattern: key };
672
+ }
673
+ if (NOSQL_DANGEROUS_KEYS.has(key)) {
674
+ return { vector: "nosql", rule: "nosql/match", matchedPattern: key };
675
+ }
676
+ const inner = scanThreats(data[key], depth + 1);
677
+ if (inner) return inner;
678
+ }
679
+ return null;
680
+ }
681
+ if (Array.isArray(data)) {
682
+ for (const item of data) {
683
+ const inner = scanThreats(item, depth + 1);
684
+ if (inner) return inner;
685
+ }
686
+ return null;
687
+ }
688
+ if (typeof data !== "string") return null;
689
+ const sample = data.slice(0, 80);
690
+ if (detectXss(data)) {
691
+ return { vector: "xss", rule: "xss/match", matchedPattern: sample };
692
+ }
693
+ if (detectSsti(data)) {
694
+ return { vector: "ssti", rule: "ssti/match", matchedPattern: sample };
695
+ }
696
+ if (detectXxe(data)) {
697
+ return { vector: "xxe", rule: "xxe/match", matchedPattern: sample };
698
+ }
699
+ if (detectSql(data)) {
700
+ return { vector: "sql", rule: "sql/match", matchedPattern: sample };
701
+ }
702
+ if (detectPathTraversal(data)) {
703
+ return { vector: "path", rule: "path/match", matchedPattern: sample };
704
+ }
705
+ if (detectCommandInjection(data)) {
706
+ return { vector: "command", rule: "command/match", matchedPattern: sample };
707
+ }
708
+ return null;
709
+ }
710
+ function createSanitizer(options = {}) {
711
+ return (req, res, next) => {
712
+ try {
713
+ if (options.block) {
714
+ const hit = scanThreats(req.body) || scanThreats(req.query) || scanThreats(req.params) || scanThreats(req.path);
715
+ if (hit) {
716
+ req.__arcis = {
717
+ vector: hit.vector,
718
+ rule: hit.rule,
719
+ severity: "high",
720
+ matchedPattern: hit.matchedPattern,
721
+ reason: `${hit.vector} pattern detected in request`,
722
+ decision: "deny"
723
+ };
724
+ res.status(403).json({
725
+ error: "Request blocked for security reasons",
726
+ code: "SECURITY_THREAT",
727
+ vector: hit.vector
728
+ });
729
+ return;
730
+ }
731
+ }
732
+ if (req.body && typeof req.body === "object") {
733
+ req.body = sanitizeObject(req.body, options);
734
+ }
735
+ if (req.query && typeof req.query === "object") {
736
+ const sanitizedQuery = sanitizeObject(req.query, options);
737
+ Object.defineProperty(req, "query", { value: sanitizedQuery, writable: true, configurable: true });
738
+ }
739
+ if (req.params && typeof req.params === "object") {
740
+ const sanitizedParams = sanitizeObject(req.params, options);
741
+ Object.defineProperty(req, "params", { value: sanitizedParams, writable: true, configurable: true });
742
+ }
743
+ next();
744
+ } catch (err) {
745
+ next(err);
746
+ }
747
+ };
748
+ }
749
+
750
+ // src/sanitizers/nosql.ts
751
+ function isDangerousNoSqlKey(key) {
752
+ return NOSQL_DANGEROUS_KEYS.has(key);
753
+ }
754
+ function detectNoSqlInjection(obj, maxDepth = 10) {
755
+ if (maxDepth <= 0) return false;
756
+ if (obj === null || typeof obj !== "object") return false;
757
+ if (Array.isArray(obj)) {
758
+ return obj.some((item) => detectNoSqlInjection(item, maxDepth - 1));
759
+ }
760
+ for (const key of Object.keys(obj)) {
761
+ if (isDangerousNoSqlKey(key)) {
762
+ return true;
763
+ }
764
+ const value = obj[key];
765
+ if (typeof value === "object" && value !== null) {
766
+ if (detectNoSqlInjection(value, maxDepth - 1)) {
767
+ return true;
768
+ }
769
+ }
770
+ }
771
+ return false;
772
+ }
773
+ function getDangerousOperators() {
774
+ return Array.from(NOSQL_DANGEROUS_KEYS);
775
+ }
776
+
777
+ // src/sanitizers/prototype.ts
778
+ function isDangerousProtoKey(key) {
779
+ return DANGEROUS_PROTO_KEYS.has(key.toLowerCase());
780
+ }
781
+ function detectPrototypePollution(obj, maxDepth = 10) {
782
+ if (maxDepth <= 0) return false;
783
+ if (obj === null || typeof obj !== "object") return false;
784
+ if (Array.isArray(obj)) {
785
+ return obj.some((item) => detectPrototypePollution(item, maxDepth - 1));
786
+ }
787
+ for (const key of Object.keys(obj)) {
788
+ if (DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {
789
+ return true;
790
+ }
791
+ const value = obj[key];
792
+ if (typeof value === "object" && value !== null) {
793
+ if (detectPrototypePollution(value, maxDepth - 1)) {
794
+ return true;
795
+ }
796
+ }
797
+ }
798
+ return false;
799
+ }
800
+ function getDangerousProtoKeys() {
801
+ return Array.from(DANGEROUS_PROTO_KEYS);
802
+ }
803
+
737
804
  // src/sanitizers/jsonp.ts
738
805
  var SAFE_CALLBACK_PATTERN = /^[a-zA-Z_$][a-zA-Z0-9_$.]*$/;
739
806
  var DANGEROUS_CALLBACK_PATTERNS = [
@@ -1082,5 +1149,6 @@ exports.sanitizeXss = sanitizeXss;
1082
1149
  exports.sanitizeXxe = sanitizeXxe;
1083
1150
  exports.scanObjectPii = scanObjectPii;
1084
1151
  exports.scanPii = scanPii;
1152
+ exports.scanThreats = scanThreats;
1085
1153
  //# sourceMappingURL=index.js.map
1086
1154
  //# sourceMappingURL=index.js.map