@arcis/node 1.5.2 → 1.6.1

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 (80) hide show
  1. package/README.md +48 -7
  2. package/dist/astro/index.js.map +1 -1
  3. package/dist/astro/index.mjs.map +1 -1
  4. package/dist/bun/index.js.map +1 -1
  5. package/dist/bun/index.mjs.map +1 -1
  6. package/dist/core/constants.d.ts +2 -2
  7. package/dist/core/constants.d.ts.map +1 -1
  8. package/dist/core/index.js +19 -1
  9. package/dist/core/index.js.map +1 -1
  10. package/dist/core/index.mjs +19 -1
  11. package/dist/core/index.mjs.map +1 -1
  12. package/dist/fastify/index.js.map +1 -1
  13. package/dist/fastify/index.mjs.map +1 -1
  14. package/dist/hono/index.js.map +1 -1
  15. package/dist/hono/index.mjs.map +1 -1
  16. package/dist/index.d.ts +3 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +407 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +407 -9
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/koa/index.js.map +1 -1
  23. package/dist/koa/index.mjs.map +1 -1
  24. package/dist/logging/index.js.map +1 -1
  25. package/dist/logging/index.mjs.map +1 -1
  26. package/dist/middleware/astro.d.ts +6 -1
  27. package/dist/middleware/astro.d.ts.map +1 -1
  28. package/dist/middleware/bun.d.ts +8 -1
  29. package/dist/middleware/bun.d.ts.map +1 -1
  30. package/dist/middleware/correlation.d.ts +87 -0
  31. package/dist/middleware/correlation.d.ts.map +1 -0
  32. package/dist/middleware/graphql.d.ts.map +1 -1
  33. package/dist/middleware/hono.d.ts +6 -0
  34. package/dist/middleware/hono.d.ts.map +1 -1
  35. package/dist/middleware/index.d.ts +3 -1
  36. package/dist/middleware/index.d.ts.map +1 -1
  37. package/dist/middleware/index.js +366 -8
  38. package/dist/middleware/index.js.map +1 -1
  39. package/dist/middleware/index.mjs +366 -9
  40. package/dist/middleware/index.mjs.map +1 -1
  41. package/dist/middleware/koa.d.ts +5 -0
  42. package/dist/middleware/koa.d.ts.map +1 -1
  43. package/dist/middleware/nextjs.d.ts +9 -1
  44. package/dist/middleware/nextjs.d.ts.map +1 -1
  45. package/dist/middleware/nuxt.d.ts +6 -1
  46. package/dist/middleware/nuxt.d.ts.map +1 -1
  47. package/dist/middleware/protect.d.ts +32 -0
  48. package/dist/middleware/protect.d.ts.map +1 -1
  49. package/dist/middleware/sveltekit.d.ts +6 -1
  50. package/dist/middleware/sveltekit.d.ts.map +1 -1
  51. package/dist/nestjs/index.js +55 -2
  52. package/dist/nestjs/index.js.map +1 -1
  53. package/dist/nestjs/index.mjs +55 -2
  54. package/dist/nestjs/index.mjs.map +1 -1
  55. package/dist/nextjs/index.js.map +1 -1
  56. package/dist/nextjs/index.mjs.map +1 -1
  57. package/dist/nuxt/index.js.map +1 -1
  58. package/dist/nuxt/index.mjs.map +1 -1
  59. package/dist/sanitizers/deserialization.d.ts +30 -0
  60. package/dist/sanitizers/deserialization.d.ts.map +1 -0
  61. package/dist/sanitizers/graphql.d.ts +20 -3
  62. package/dist/sanitizers/graphql.d.ts.map +1 -1
  63. package/dist/sanitizers/index.d.ts +2 -0
  64. package/dist/sanitizers/index.d.ts.map +1 -1
  65. package/dist/sanitizers/index.js +150 -7
  66. package/dist/sanitizers/index.js.map +1 -1
  67. package/dist/sanitizers/index.mjs +149 -8
  68. package/dist/sanitizers/index.mjs.map +1 -1
  69. package/dist/sanitizers/prompt-injection.d.ts.map +1 -1
  70. package/dist/sanitizers/sanitize.d.ts +0 -20
  71. package/dist/sanitizers/sanitize.d.ts.map +1 -1
  72. package/dist/stores/index.js.map +1 -1
  73. package/dist/stores/index.mjs.map +1 -1
  74. package/dist/sveltekit/index.js.map +1 -1
  75. package/dist/sveltekit/index.mjs.map +1 -1
  76. package/dist/validation/index.js +55 -2
  77. package/dist/validation/index.js.map +1 -1
  78. package/dist/validation/index.mjs +55 -2
  79. package/dist/validation/index.mjs.map +1 -1
  80. package/package.json +11 -11
@@ -135,7 +135,16 @@ var SQL_PATTERNS = [
135
135
  /** Time-based blind: PostgreSQL pg_sleep() */
136
136
  /\bpg_sleep\s*\(/gi,
137
137
  /** Time-based blind: MSSQL WAITFOR DELAY */
138
- /\bWAITFOR\s+DELAY\b/gi
138
+ /\bWAITFOR\s+DELAY\b/gi,
139
+ /**
140
+ * Oracle DBMS_* stdlib packages used for time-based blind SQLi
141
+ * (DBMS_LOCK.SLEEP, DBMS_PIPE.RECEIVE_MESSAGE) and other Oracle
142
+ * abuse paths. No legitimate user input contains these. Mirrors
143
+ * `sqli-oracle-dbms-packages` in packages/core/patterns.json —
144
+ * improvements.md §1.1.e Q3. Must stay in sync until Node
145
+ * migrates to patterns.json-at-runtime (planned v1.7).
146
+ */
147
+ /\bDBMS_(?:LOCK|PIPE|UTILITY|XSLPROCESSOR|JAVA|OUTPUT|SCHEDULER)\b/gi
139
148
  ];
140
149
  var PATH_PATTERNS = [
141
150
  /** Unix path traversal */
@@ -173,6 +182,15 @@ var COMMAND_PATTERNS = [
173
182
  /[;&|`]/g,
174
183
  /** Command substitution: $( ... ) — matched as a pair to reduce false positives */
175
184
  /\$\(/g,
185
+ /**
186
+ * POSIX shell IFS-substitution: ${IFS} or ${IFS%??}.
187
+ * Attackers use this to inject spaces past metacharacter filters
188
+ * in payloads like `;cat${IFS}/etc/passwd`. Mirrors
189
+ * `cmdi-ifs-bypass` in packages/core/patterns.json — improvements.md
190
+ * §1.1.e Q5. Must stay in sync until Node migrates to
191
+ * patterns.json-at-runtime (planned v1.7).
192
+ */
193
+ /\$\{IFS(?:%[^}]*)?\}/g,
176
194
  /** URL-encoded control characters (%00-%0F): null, tab, vtab, formfeed, LF, CR */
177
195
  /%0[0-9a-f]/gi
178
196
  ];
@@ -943,6 +961,40 @@ function detectHeaderInjection(input) {
943
961
  }
944
962
 
945
963
  // src/sanitizers/sanitize.ts
964
+ function multiDecode(value, maxPasses = 4) {
965
+ for (let i = 0; i < maxPasses; i++) {
966
+ const prev = value;
967
+ try {
968
+ value = decodeURIComponent(value);
969
+ } catch {
970
+ }
971
+ value = htmlEntityDecode(value);
972
+ if (value === prev) break;
973
+ }
974
+ return value;
975
+ }
976
+ function htmlEntityDecode(s) {
977
+ s = s.replace(/&#(\d+);/g, (_m, n) => {
978
+ const code = parseInt(n, 10);
979
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
980
+ });
981
+ s = s.replace(/&#x([0-9a-fA-F]+);/g, (_m, h) => {
982
+ const code = parseInt(h, 16);
983
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
984
+ });
985
+ const named = {
986
+ "&lt;": "<",
987
+ "&gt;": ">",
988
+ "&amp;": "&",
989
+ "&quot;": '"',
990
+ "&apos;": "'",
991
+ "&nbsp;": " "
992
+ };
993
+ for (const [entity, ch] of Object.entries(named)) {
994
+ s = s.split(entity).join(ch);
995
+ }
996
+ return s;
997
+ }
946
998
  function sanitizeString(value, options = {}) {
947
999
  if (typeof value !== "string") return value;
948
1000
  const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
@@ -950,7 +1002,8 @@ function sanitizeString(value, options = {}) {
950
1002
  throw new InputTooLargeError(maxSize, value.length);
951
1003
  }
952
1004
  const reject = options.mode === "reject";
953
- let result = value;
1005
+ let result = value.normalize("NFKC");
1006
+ result = multiDecode(result);
954
1007
  if (options.sql !== false) {
955
1008
  if (reject) {
956
1009
  if (detectSql(result)) {