@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
@@ -88,7 +88,16 @@ var SQL_PATTERNS = [
88
88
  /** Time-based blind: PostgreSQL pg_sleep() */
89
89
  /\bpg_sleep\s*\(/gi,
90
90
  /** Time-based blind: MSSQL WAITFOR DELAY */
91
- /\bWAITFOR\s+DELAY\b/gi
91
+ /\bWAITFOR\s+DELAY\b/gi,
92
+ /**
93
+ * Oracle DBMS_* stdlib packages used for time-based blind SQLi
94
+ * (DBMS_LOCK.SLEEP, DBMS_PIPE.RECEIVE_MESSAGE) and other Oracle
95
+ * abuse paths. No legitimate user input contains these. Mirrors
96
+ * `sqli-oracle-dbms-packages` in packages/core/patterns.json —
97
+ * improvements.md §1.1.e Q3. Must stay in sync until Node
98
+ * migrates to patterns.json-at-runtime (planned v1.7).
99
+ */
100
+ /\bDBMS_(?:LOCK|PIPE|UTILITY|XSLPROCESSOR|JAVA|OUTPUT|SCHEDULER)\b/gi
92
101
  ];
93
102
  var PATH_PATTERNS = [
94
103
  /** Unix path traversal */
@@ -126,6 +135,15 @@ var COMMAND_PATTERNS = [
126
135
  /[;&|`]/g,
127
136
  /** Command substitution: $( ... ) — matched as a pair to reduce false positives */
128
137
  /\$\(/g,
138
+ /**
139
+ * POSIX shell IFS-substitution: ${IFS} or ${IFS%??}.
140
+ * Attackers use this to inject spaces past metacharacter filters
141
+ * in payloads like `;cat${IFS}/etc/passwd`. Mirrors
142
+ * `cmdi-ifs-bypass` in packages/core/patterns.json — improvements.md
143
+ * §1.1.e Q5. Must stay in sync until Node migrates to
144
+ * patterns.json-at-runtime (planned v1.7).
145
+ */
146
+ /\$\{IFS(?:%[^}]*)?\}/g,
129
147
  /** URL-encoded control characters (%00-%0F): null, tab, vtab, formfeed, LF, CR */
130
148
  /%0[0-9a-f]/gi
131
149
  ];
@@ -369,6 +387,40 @@ function detectCommandInjection(input) {
369
387
  }
370
388
 
371
389
  // src/sanitizers/sanitize.ts
390
+ function multiDecode(value, maxPasses = 4) {
391
+ for (let i = 0; i < maxPasses; i++) {
392
+ const prev = value;
393
+ try {
394
+ value = decodeURIComponent(value);
395
+ } catch {
396
+ }
397
+ value = htmlEntityDecode(value);
398
+ if (value === prev) break;
399
+ }
400
+ return value;
401
+ }
402
+ function htmlEntityDecode(s) {
403
+ s = s.replace(/&#(\d+);/g, (_m, n) => {
404
+ const code = parseInt(n, 10);
405
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
406
+ });
407
+ s = s.replace(/&#x([0-9a-fA-F]+);/g, (_m, h) => {
408
+ const code = parseInt(h, 16);
409
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
410
+ });
411
+ const named = {
412
+ "&lt;": "<",
413
+ "&gt;": ">",
414
+ "&amp;": "&",
415
+ "&quot;": '"',
416
+ "&apos;": "'",
417
+ "&nbsp;": " "
418
+ };
419
+ for (const [entity, ch] of Object.entries(named)) {
420
+ s = s.split(entity).join(ch);
421
+ }
422
+ return s;
423
+ }
372
424
  function sanitizeString(value, options = {}) {
373
425
  if (typeof value !== "string") return value;
374
426
  const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
@@ -376,7 +428,8 @@ function sanitizeString(value, options = {}) {
376
428
  throw new InputTooLargeError(maxSize, value.length);
377
429
  }
378
430
  const reject = options.mode === "reject";
379
- let result = value;
431
+ let result = value.normalize("NFKC");
432
+ result = multiDecode(result);
380
433
  if (options.sql !== false) {
381
434
  if (reject) {
382
435
  if (detectSql(result)) {