@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
@@ -67,7 +67,16 @@ var SQL_PATTERNS = [
67
67
  /** Time-based blind: PostgreSQL pg_sleep() */
68
68
  /\bpg_sleep\s*\(/gi,
69
69
  /** Time-based blind: MSSQL WAITFOR DELAY */
70
- /\bWAITFOR\s+DELAY\b/gi
70
+ /\bWAITFOR\s+DELAY\b/gi,
71
+ /**
72
+ * Oracle DBMS_* stdlib packages used for time-based blind SQLi
73
+ * (DBMS_LOCK.SLEEP, DBMS_PIPE.RECEIVE_MESSAGE) and other Oracle
74
+ * abuse paths. No legitimate user input contains these. Mirrors
75
+ * `sqli-oracle-dbms-packages` in packages/core/patterns.json —
76
+ * improvements.md §1.1.e Q3. Must stay in sync until Node
77
+ * migrates to patterns.json-at-runtime (planned v1.7).
78
+ */
79
+ /\bDBMS_(?:LOCK|PIPE|UTILITY|XSLPROCESSOR|JAVA|OUTPUT|SCHEDULER)\b/gi
71
80
  ];
72
81
  var PATH_PATTERNS = [
73
82
  /** Unix path traversal */
@@ -105,6 +114,15 @@ var COMMAND_PATTERNS = [
105
114
  /[;&|`]/g,
106
115
  /** Command substitution: $( ... ) — matched as a pair to reduce false positives */
107
116
  /\$\(/g,
117
+ /**
118
+ * POSIX shell IFS-substitution: ${IFS} or ${IFS%??}.
119
+ * Attackers use this to inject spaces past metacharacter filters
120
+ * in payloads like `;cat${IFS}/etc/passwd`. Mirrors
121
+ * `cmdi-ifs-bypass` in packages/core/patterns.json — improvements.md
122
+ * §1.1.e Q5. Must stay in sync until Node migrates to
123
+ * patterns.json-at-runtime (planned v1.7).
124
+ */
125
+ /\$\{IFS(?:%[^}]*)?\}/g,
108
126
  /** URL-encoded control characters (%00-%0F): null, tab, vtab, formfeed, LF, CR */
109
127
  /%0[0-9a-f]/gi
110
128
  ];
@@ -348,6 +366,40 @@ function detectCommandInjection(input) {
348
366
  }
349
367
 
350
368
  // src/sanitizers/sanitize.ts
369
+ function multiDecode(value, maxPasses = 4) {
370
+ for (let i = 0; i < maxPasses; i++) {
371
+ const prev = value;
372
+ try {
373
+ value = decodeURIComponent(value);
374
+ } catch {
375
+ }
376
+ value = htmlEntityDecode(value);
377
+ if (value === prev) break;
378
+ }
379
+ return value;
380
+ }
381
+ function htmlEntityDecode(s) {
382
+ s = s.replace(/&#(\d+);/g, (_m, n) => {
383
+ const code = parseInt(n, 10);
384
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
385
+ });
386
+ s = s.replace(/&#x([0-9a-fA-F]+);/g, (_m, h) => {
387
+ const code = parseInt(h, 16);
388
+ return Number.isFinite(code) && code >= 0 && code <= 1114111 ? String.fromCodePoint(code) : _m;
389
+ });
390
+ const named = {
391
+ "&lt;": "<",
392
+ "&gt;": ">",
393
+ "&amp;": "&",
394
+ "&quot;": '"',
395
+ "&apos;": "'",
396
+ "&nbsp;": " "
397
+ };
398
+ for (const [entity, ch] of Object.entries(named)) {
399
+ s = s.split(entity).join(ch);
400
+ }
401
+ return s;
402
+ }
351
403
  function sanitizeString(value, options = {}) {
352
404
  if (typeof value !== "string") return value;
353
405
  const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;
@@ -355,7 +407,8 @@ function sanitizeString(value, options = {}) {
355
407
  throw new InputTooLargeError(maxSize, value.length);
356
408
  }
357
409
  const reject = options.mode === "reject";
358
- let result = value;
410
+ let result = value.normalize("NFKC");
411
+ result = multiDecode(result);
359
412
  if (options.sql !== false) {
360
413
  if (reject) {
361
414
  if (detectSql(result)) {