@arcis/node 1.2.0 → 1.4.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 (122) hide show
  1. package/dist/core/{index.d.mts → constants.d.ts} +21 -70
  2. package/dist/core/constants.d.ts.map +1 -0
  3. package/dist/core/errors.d.ts +53 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/index.d.ts +6 -168
  6. package/dist/core/index.d.ts.map +1 -0
  7. package/dist/{types-CsOFHoD9.d.mts → core/types.d.ts} +38 -31
  8. package/dist/core/types.d.ts.map +1 -0
  9. package/dist/index.d.ts +71 -166
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +151 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +145 -5
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/logging/index.d.ts +4 -36
  16. package/dist/logging/index.d.ts.map +1 -0
  17. package/dist/logging/{index.d.mts → redactor.d.ts} +5 -9
  18. package/dist/logging/redactor.d.ts.map +1 -0
  19. package/dist/middleware/bot-detection.d.ts +86 -0
  20. package/dist/middleware/bot-detection.d.ts.map +1 -0
  21. package/dist/middleware/cookies.d.ts +48 -0
  22. package/dist/middleware/cookies.d.ts.map +1 -0
  23. package/dist/middleware/cors.d.ts +65 -0
  24. package/dist/middleware/cors.d.ts.map +1 -0
  25. package/dist/middleware/csrf.d.ts +109 -0
  26. package/dist/middleware/csrf.d.ts.map +1 -0
  27. package/dist/middleware/error-handler.d.ts +43 -0
  28. package/dist/middleware/error-handler.d.ts.map +1 -0
  29. package/dist/middleware/headers.d.ts +29 -0
  30. package/dist/middleware/headers.d.ts.map +1 -0
  31. package/dist/middleware/hpp.d.ts +56 -0
  32. package/dist/middleware/hpp.d.ts.map +1 -0
  33. package/dist/middleware/index.d.ts +16 -3
  34. package/dist/middleware/index.d.ts.map +1 -0
  35. package/dist/middleware/index.js +28 -3
  36. package/dist/middleware/index.js.map +1 -1
  37. package/dist/middleware/index.mjs +28 -3
  38. package/dist/middleware/index.mjs.map +1 -1
  39. package/dist/middleware/main.d.ts +40 -0
  40. package/dist/middleware/main.d.ts.map +1 -0
  41. package/dist/middleware/rate-limit-sliding.d.ts +46 -0
  42. package/dist/middleware/rate-limit-sliding.d.ts.map +1 -0
  43. package/dist/middleware/rate-limit-token.d.ts +51 -0
  44. package/dist/middleware/rate-limit-token.d.ts.map +1 -0
  45. package/dist/middleware/rate-limit.d.ts +34 -0
  46. package/dist/middleware/rate-limit.d.ts.map +1 -0
  47. package/dist/sanitizers/command.d.ts +28 -0
  48. package/dist/sanitizers/command.d.ts.map +1 -0
  49. package/dist/sanitizers/encode.d.ts +46 -0
  50. package/dist/sanitizers/encode.d.ts.map +1 -0
  51. package/dist/sanitizers/headers.d.ts +46 -0
  52. package/dist/sanitizers/headers.d.ts.map +1 -0
  53. package/dist/sanitizers/index.d.ts +17 -22
  54. package/dist/sanitizers/index.d.ts.map +1 -0
  55. package/dist/sanitizers/index.js +72 -0
  56. package/dist/sanitizers/index.js.map +1 -1
  57. package/dist/sanitizers/index.mjs +68 -1
  58. package/dist/sanitizers/index.mjs.map +1 -1
  59. package/dist/sanitizers/jsonp.d.ts +34 -0
  60. package/dist/sanitizers/jsonp.d.ts.map +1 -0
  61. package/dist/sanitizers/nosql.d.ts +31 -0
  62. package/dist/sanitizers/nosql.d.ts.map +1 -0
  63. package/dist/sanitizers/path.d.ts +28 -0
  64. package/dist/sanitizers/path.d.ts.map +1 -0
  65. package/dist/sanitizers/pii.d.ts +80 -0
  66. package/dist/sanitizers/pii.d.ts.map +1 -0
  67. package/dist/sanitizers/prototype.d.ts +34 -0
  68. package/dist/sanitizers/prototype.d.ts.map +1 -0
  69. package/dist/sanitizers/sanitize.d.ts +51 -0
  70. package/dist/sanitizers/sanitize.d.ts.map +1 -0
  71. package/dist/sanitizers/sql.d.ts +28 -0
  72. package/dist/sanitizers/sql.d.ts.map +1 -0
  73. package/dist/sanitizers/ssti.d.ts +20 -0
  74. package/dist/sanitizers/ssti.d.ts.map +1 -0
  75. package/dist/sanitizers/utils.d.ts +19 -0
  76. package/dist/sanitizers/utils.d.ts.map +1 -0
  77. package/dist/sanitizers/xss.d.ts +35 -0
  78. package/dist/sanitizers/xss.d.ts.map +1 -0
  79. package/dist/sanitizers/xxe.d.ts +20 -0
  80. package/dist/sanitizers/xxe.d.ts.map +1 -0
  81. package/dist/stores/index.d.ts +6 -104
  82. package/dist/stores/index.d.ts.map +1 -0
  83. package/dist/stores/memory.d.ts +35 -0
  84. package/dist/stores/memory.d.ts.map +1 -0
  85. package/dist/stores/{index.d.mts → redis.d.ts} +6 -45
  86. package/dist/stores/redis.d.ts.map +1 -0
  87. package/dist/utils/duration.d.ts +34 -0
  88. package/dist/utils/duration.d.ts.map +1 -0
  89. package/dist/utils/fingerprint.d.ts +64 -0
  90. package/dist/utils/fingerprint.d.ts.map +1 -0
  91. package/dist/utils/index.d.ts +10 -0
  92. package/dist/utils/index.d.ts.map +1 -0
  93. package/dist/utils/index.js +188 -0
  94. package/dist/utils/index.js.map +1 -0
  95. package/dist/utils/index.mjs +182 -0
  96. package/dist/utils/index.mjs.map +1 -0
  97. package/dist/utils/ip.d.ts +70 -0
  98. package/dist/utils/ip.d.ts.map +1 -0
  99. package/dist/validation/email.d.ts +82 -0
  100. package/dist/validation/email.d.ts.map +1 -0
  101. package/dist/validation/file.d.ts +90 -0
  102. package/dist/validation/file.d.ts.map +1 -0
  103. package/dist/validation/index.d.ts +10 -3
  104. package/dist/validation/index.d.ts.map +1 -0
  105. package/dist/validation/redirect.d.ts +64 -0
  106. package/dist/validation/redirect.d.ts.map +1 -0
  107. package/dist/validation/schema.d.ts +36 -0
  108. package/dist/validation/schema.d.ts.map +1 -0
  109. package/dist/validation/url.d.ts +65 -0
  110. package/dist/validation/url.d.ts.map +1 -0
  111. package/package.json +8 -6
  112. package/dist/index-A-m-pPeW.d.mts +0 -340
  113. package/dist/index-CgK94hY_.d.mts +0 -532
  114. package/dist/index-Co5kPRZz.d.ts +0 -340
  115. package/dist/index-D_bdJcF0.d.ts +0 -532
  116. package/dist/index.d.mts +0 -175
  117. package/dist/middleware/index.d.mts +0 -3
  118. package/dist/pii-CXcHMlnX.d.mts +0 -438
  119. package/dist/pii-DhNpl7M3.d.ts +0 -438
  120. package/dist/sanitizers/index.d.mts +0 -24
  121. package/dist/types-CsOFHoD9.d.ts +0 -269
  122. package/dist/validation/index.d.mts +0 -3
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @module @arcis/node/middleware/main
3
+ * Main arcis() middleware factory
4
+ */
5
+ import type { ArcisOptions, ArcisFunction, ArcisMiddlewareStack } from '../core/types';
6
+ /**
7
+ * Create Arcis middleware with all protections enabled.
8
+ *
9
+ * @param options - Configuration options
10
+ * @returns Array of Express middleware
11
+ *
12
+ * @example
13
+ * // Full protection (recommended)
14
+ * app.use(arcis());
15
+ *
16
+ * @example
17
+ * // Custom configuration
18
+ * app.use(arcis({
19
+ * rateLimit: { max: 50 },
20
+ * headers: { frameOptions: 'SAMEORIGIN' }
21
+ * }));
22
+ *
23
+ * @example
24
+ * // Disable specific features
25
+ * app.use(arcis({
26
+ * rateLimit: false,
27
+ * sanitize: { sql: false }
28
+ * }));
29
+ *
30
+ * @example
31
+ * // Cleanup on shutdown
32
+ * const middleware = arcis();
33
+ * app.use(middleware);
34
+ * process.on('SIGTERM', () => middleware.close());
35
+ */
36
+ export declare function arcis(options?: ArcisOptions): ArcisMiddlewareStack;
37
+ declare const arcisWithMethods: ArcisFunction;
38
+ export { arcisWithMethods as arcisFunction };
39
+ export default arcisWithMethods;
40
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +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;AAQvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,oBAAoB,CAuCtE;AAGD,QAAA,MAAM,gBAAgB,EAAY,aAAa,CAAC;AAQhD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,CAAC;AAC7C,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @module @arcis/node/middleware/rate-limit-sliding
3
+ * Sliding window rate limiting middleware.
4
+ *
5
+ * More accurate than fixed window — uses a weighted sum of the previous
6
+ * and current window to approximate a true sliding window.
7
+ *
8
+ * Algorithm:
9
+ * weight = (windowMs - elapsed) / windowMs
10
+ * count = (prevWindow * weight) + currentWindow
11
+ * allow = count < limit
12
+ *
13
+ * @example
14
+ * app.use(createSlidingWindowLimiter({ max: 100, window: '15m' }));
15
+ */
16
+ import type { Request, RequestHandler } from 'express';
17
+ export interface SlidingWindowOptions {
18
+ /** Maximum requests per window. Default: 100 */
19
+ max?: number;
20
+ /** Window size in ms or duration string. Default: '1m' */
21
+ window?: string | number;
22
+ /** Error message when limit exceeded */
23
+ message?: string;
24
+ /** HTTP status code for rate limited responses. Default: 429 */
25
+ statusCode?: number;
26
+ /** Function to generate rate limit key from request */
27
+ keyGenerator?: (req: Request) => string;
28
+ /** Function to skip rate limiting for certain requests */
29
+ skip?: (req: Request) => boolean;
30
+ }
31
+ export interface SlidingWindowMiddleware extends RequestHandler {
32
+ close: () => void;
33
+ }
34
+ /**
35
+ * Create sliding window rate limiter middleware.
36
+ *
37
+ * @example
38
+ * // 100 requests per 15 minutes
39
+ * app.use(createSlidingWindowLimiter({ max: 100, window: '15m' }));
40
+ *
41
+ * @example
42
+ * // Strict API limit
43
+ * app.use('/api', createSlidingWindowLimiter({ max: 30, window: '1m' }));
44
+ */
45
+ export declare function createSlidingWindowLimiter(options?: SlidingWindowOptions): SlidingWindowMiddleware;
46
+ //# sourceMappingURL=rate-limit-sliding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-sliding.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit-sliding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA0B,cAAc,EAAE,MAAM,SAAS,CAAC;AAI/E,MAAM,WAAW,oBAAoB;IACnC,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,0DAA0D;IAC1D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;CAClC;AAOD,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,oBAAyB,GAAG,uBAAuB,CAiGtG"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @module @arcis/node/middleware/rate-limit-token
3
+ * Token bucket rate limiting middleware.
4
+ *
5
+ * Allows burst traffic while enforcing an average rate.
6
+ * Tokens refill at a steady rate. Each request costs 1 token.
7
+ *
8
+ * Algorithm:
9
+ * tokens = min(capacity, tokens + elapsed * refillRate)
10
+ * if tokens >= cost: allow, subtract cost
11
+ * else: deny
12
+ *
13
+ * @example
14
+ * app.use(createTokenBucketLimiter({ capacity: 50, refillRate: 10 }));
15
+ */
16
+ import type { Request, RequestHandler } from 'express';
17
+ export interface TokenBucketOptions {
18
+ /** Maximum tokens (burst size). Default: 100 */
19
+ capacity?: number;
20
+ /** Tokens added per second. Default: 10 */
21
+ refillRate?: number;
22
+ /** Tokens consumed per request. Default: 1 */
23
+ cost?: number;
24
+ /** Error message when limit exceeded */
25
+ message?: string;
26
+ /** HTTP status code for rate limited responses. Default: 429 */
27
+ statusCode?: number;
28
+ /** Function to generate rate limit key from request */
29
+ keyGenerator?: (req: Request) => string;
30
+ /** Function to skip rate limiting for certain requests */
31
+ skip?: (req: Request) => boolean;
32
+ }
33
+ export interface TokenBucketMiddleware extends RequestHandler {
34
+ close: () => void;
35
+ }
36
+ /**
37
+ * Create token bucket rate limiter middleware.
38
+ *
39
+ * @example
40
+ * // Allow bursts of 50, sustained rate of 10/sec
41
+ * app.use(createTokenBucketLimiter({ capacity: 50, refillRate: 10 }));
42
+ *
43
+ * @example
44
+ * // Strict API: 5 requests burst, 1/sec sustained
45
+ * app.use('/api/expensive', createTokenBucketLimiter({
46
+ * capacity: 5,
47
+ * refillRate: 1,
48
+ * }));
49
+ */
50
+ export declare function createTokenBucketLimiter(options?: TokenBucketOptions): TokenBucketMiddleware;
51
+ //# sourceMappingURL=rate-limit-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-token.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA0B,cAAc,EAAE,MAAM,SAAS,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,0DAA0D;IAC1D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;CAClC;AAOD,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,kBAAuB,GAAG,qBAAqB,CA2FhG"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @module @arcis/node/middleware/rate-limit
3
+ * Rate limiting middleware
4
+ */
5
+ import type { RateLimitOptions, RateLimiterMiddleware } from '../core/types';
6
+ /**
7
+ * Create Express middleware for rate limiting.
8
+ *
9
+ * @param options - Rate limit configuration
10
+ * @returns Express middleware with cleanup method
11
+ *
12
+ * @example
13
+ * app.use(createRateLimiter({ max: 100, windowMs: 60000 }));
14
+ *
15
+ * @example
16
+ * // Skip rate limiting for certain routes
17
+ * app.use(createRateLimiter({
18
+ * max: 50,
19
+ * skip: (req) => req.path === '/health'
20
+ * }));
21
+ *
22
+ * @example
23
+ * // Cleanup on shutdown
24
+ * const limiter = createRateLimiter();
25
+ * app.use(limiter);
26
+ * process.on('SIGTERM', () => limiter.close());
27
+ */
28
+ export declare function createRateLimiter(options?: RateLimitOptions): RateLimiterMiddleware;
29
+ /**
30
+ * Alias for createRateLimiter
31
+ * @see createRateLimiter
32
+ */
33
+ export declare const rateLimit: typeof createRateLimiter;
34
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAkB,MAAM,eAAe,CAAC;AAO7F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,gBAAqB,GAAG,qBAAqB,CAiHvF;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,0BAAoB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module @arcis/node/sanitizers/command
3
+ * Command injection prevention
4
+ */
5
+ import type { SanitizeResult } from '../core/types';
6
+ /**
7
+ * Sanitizes a string to prevent command injection attacks.
8
+ * Replaces shell metacharacters and dangerous commands with [BLOCKED].
9
+ *
10
+ * @param input - The string to sanitize
11
+ * @param collectThreats - Whether to collect threat information (default: false for performance)
12
+ * @returns Sanitized string or SanitizeResult if collectThreats is true
13
+ *
14
+ * @example
15
+ * sanitizeCommand("file.txt; rm -rf /")
16
+ * // Returns: "file.txt rm -rf /"
17
+ */
18
+ export declare function sanitizeCommand(input: string, collectThreats?: false): string;
19
+ export declare function sanitizeCommand(input: string, collectThreats: true): SanitizeResult;
20
+ /**
21
+ * Checks if a string contains command injection patterns.
22
+ * Does not sanitize — use sanitizeCommand() for that.
23
+ *
24
+ * @param input - The string to check
25
+ * @returns True if command injection patterns detected
26
+ */
27
+ export declare function detectCommandInjection(input: string): boolean;
28
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/sanitizers/command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,eAAe,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,cAAc,CAAC;AA4CrF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW7D"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @module @arcis/node/sanitizers/encode
3
+ * Context-aware output encoding for XSS prevention.
4
+ *
5
+ * Wrong-context encoding is the #1 cause of XSS bypasses in "protected" apps.
6
+ * A single sanitize() is not enough when output goes to JS, CSS, or attribute contexts.
7
+ */
8
+ /**
9
+ * Encodes for HTML body context. Entity-encodes & < > " '
10
+ *
11
+ * Use when outputting to HTML element content:
12
+ * `<p>${encodeForHtml(userInput)}</p>`
13
+ */
14
+ export declare function encodeForHtml(value: string): string;
15
+ /**
16
+ * Encodes for HTML attribute context.
17
+ * All non-alphanumeric characters are encoded as `&#xHH;` hex entities.
18
+ *
19
+ * Use when outputting to HTML attributes:
20
+ * `<div title="${encodeForAttribute(userInput)}">`
21
+ */
22
+ export declare function encodeForAttribute(value: string): string;
23
+ /**
24
+ * Encodes for JavaScript string context.
25
+ * Non-alphanumeric characters are escaped as `\xHH` (ASCII) or `\uHHHH` (Unicode).
26
+ *
27
+ * Use when embedding in JS string literals:
28
+ * `var x = '${encodeForJs(userInput)}';`
29
+ */
30
+ export declare function encodeForJs(value: string): string;
31
+ /**
32
+ * Encodes for URL parameter context. Percent-encodes all non-unreserved chars.
33
+ *
34
+ * Use when building query strings:
35
+ * `?q=${encodeForUrl(userInput)}`
36
+ */
37
+ export declare function encodeForUrl(value: string): string;
38
+ /**
39
+ * Encodes for CSS value context.
40
+ * Non-alphanumeric characters are hex-escaped as `\HH ` (trailing space per CSS spec).
41
+ *
42
+ * Use when embedding in CSS values:
43
+ * `content: '${encodeForCss(userInput)}';`
44
+ */
45
+ export declare function encodeForCss(value: string): string;
46
+ //# sourceMappingURL=encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/sanitizers/encode.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBxD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmBjD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBlD"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @module @arcis/node/sanitizers/headers
3
+ * HTTP Header Injection & CRLF Injection prevention
4
+ *
5
+ * Prevents attackers from injecting newline characters (\r\n) into HTTP header
6
+ * values, which can lead to response splitting, session fixation, XSS via
7
+ * injected headers, and cache poisoning.
8
+ */
9
+ import type { SanitizeResult } from '../core/types';
10
+ /**
11
+ * Sanitizes a header value by stripping CRLF sequences, bare CR/LF, and null bytes.
12
+ *
13
+ * @param input - The header value to sanitize
14
+ * @param collectThreats - Whether to collect threat information (default: false)
15
+ * @returns Sanitized string or SanitizeResult if collectThreats is true
16
+ *
17
+ * @example
18
+ * sanitizeHeaderValue("safe-value")
19
+ * // Returns: "safe-value"
20
+ *
21
+ * sanitizeHeaderValue("value\r\nX-Injected: evil")
22
+ * // Returns: "valueX-Injected: evil"
23
+ */
24
+ export declare function sanitizeHeaderValue(input: string, collectThreats?: false): string;
25
+ export declare function sanitizeHeaderValue(input: string, collectThreats: true): SanitizeResult;
26
+ /**
27
+ * Sanitizes an object of header key-value pairs.
28
+ * Strips CRLF/null bytes from both keys and values.
29
+ *
30
+ * @param headers - Object with header names as keys and header values as values
31
+ * @returns New object with sanitized header names and values
32
+ *
33
+ * @example
34
+ * sanitizeHeaders({ "X-Custom": "safe", "X-Bad\r\n": "value\r\ninjected" })
35
+ * // Returns: { "X-Custom": "safe", "X-Bad": "valueinjected" }
36
+ */
37
+ export declare function sanitizeHeaders(headers: Record<string, string>): Record<string, string>;
38
+ /**
39
+ * Checks if a string contains HTTP header injection patterns (CRLF, null bytes).
40
+ * Does not sanitize — use sanitizeHeaderValue() for that.
41
+ *
42
+ * @param input - The string to check
43
+ * @returns True if header injection patterns detected
44
+ */
45
+ export declare function detectHeaderInjection(input: string): boolean;
46
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/sanitizers/headers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,eAAe,CAAC;AAUhE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;AACnF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,cAAc,CAAC;AAuCzF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcvF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK5D"}
@@ -1,24 +1,19 @@
1
- export { c as createSanitizer, d as detectCommandInjection, a as detectHeaderInjection, b as detectJsonpInjection, e as detectNoSqlInjection, f as detectPathTraversal, g as detectPii, h as detectPrototypePollution, i as detectSql, j as detectSsti, k as detectXss, l as detectXxe, m as getDangerousOperators, n as getDangerousProtoKeys, o as isDangerousNoSqlKey, p as isDangerousProtoKey, r as redactObjectPii, q as redactPii, s as sanitizeCommand, t as sanitizeHeaderValue, u as sanitizeHeaders, v as sanitizeJsonpCallback, w as sanitizeObject, x as sanitizePath, y as sanitizeSql, z as sanitizeSsti, A as sanitizeString, B as sanitizeXss, C as sanitizeXxe, D as scanObjectPii, E as scanPii } from '../pii-DhNpl7M3.js';
2
- import 'express';
3
- import '../types-CsOFHoD9.js';
4
-
5
1
  /**
6
- * @module @arcis/node/sanitizers/utils
7
- * Shared utilities for sanitizers
2
+ * @module @arcis/node/sanitizers
3
+ * All sanitization functions for Arcis
8
4
  */
9
- /**
10
- * Encodes HTML entities to prevent interpretation as markup.
11
- *
12
- * @param str - The string to encode
13
- * @returns The encoded string
14
- */
15
- declare function encodeHtmlEntities(str: string): string;
16
- /**
17
- * Checks if a value is a plain object (not null, array, Date, etc.)
18
- *
19
- * @param value - Value to check
20
- * @returns True if plain object
21
- */
22
- declare function isPlainObject(value: unknown): value is Record<string, unknown>;
23
-
24
- export { encodeHtmlEntities, isPlainObject };
5
+ export { sanitizeString, sanitizeObject, createSanitizer } from './sanitize';
6
+ export { sanitizeXss, detectXss } from './xss';
7
+ export { sanitizeSql, detectSql } from './sql';
8
+ export { sanitizePath, detectPathTraversal } from './path';
9
+ export { sanitizeCommand, detectCommandInjection } from './command';
10
+ export { isDangerousNoSqlKey, detectNoSqlInjection, getDangerousOperators } from './nosql';
11
+ export { isDangerousProtoKey, detectPrototypePollution, getDangerousProtoKeys } from './prototype';
12
+ export { sanitizeSsti, detectSsti } from './ssti';
13
+ export { sanitizeXxe, detectXxe } from './xxe';
14
+ export { sanitizeJsonpCallback, detectJsonpInjection } from './jsonp';
15
+ export { sanitizeHeaderValue, sanitizeHeaders, detectHeaderInjection } from './headers';
16
+ export { scanPii, detectPii, redactPii, scanObjectPii, redactObjectPii } from './pii';
17
+ export { encodeForHtml, encodeForAttribute, encodeForJs, encodeForUrl, encodeForCss } from './encode';
18
+ export { encodeHtmlEntities, isPlainObject } from './utils';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -901,6 +901,73 @@ function redactObjectPii(obj, options = {}) {
901
901
  return result;
902
902
  }
903
903
 
904
+ // src/sanitizers/encode.ts
905
+ var HTML_ENTITIES = {
906
+ "&": "&amp;",
907
+ "<": "&lt;",
908
+ ">": "&gt;",
909
+ '"': "&quot;",
910
+ "'": "&#x27;"
911
+ };
912
+ var HTML_ENCODE_RE = /[&<>"']/g;
913
+ function encodeForHtml(value) {
914
+ if (!value) return "";
915
+ return value.replace(HTML_ENCODE_RE, (ch) => HTML_ENTITIES[ch]);
916
+ }
917
+ function encodeForAttribute(value) {
918
+ if (!value) return "";
919
+ let result = "";
920
+ for (let i = 0; i < value.length; i++) {
921
+ const ch = value.charCodeAt(i);
922
+ if (ch >= 48 && ch <= 57 || // 0-9
923
+ ch >= 65 && ch <= 90 || // A-Z
924
+ ch >= 97 && ch <= 122) {
925
+ result += value[i];
926
+ } else {
927
+ result += `&#x${ch.toString(16).toUpperCase()};`;
928
+ }
929
+ }
930
+ return result;
931
+ }
932
+ function encodeForJs(value) {
933
+ if (!value) return "";
934
+ let result = "";
935
+ for (let i = 0; i < value.length; i++) {
936
+ const ch = value.charCodeAt(i);
937
+ if (ch >= 48 && ch <= 57 || // 0-9
938
+ ch >= 65 && ch <= 90 || // A-Z
939
+ ch >= 97 && ch <= 122) {
940
+ result += value[i];
941
+ } else if (ch < 256) {
942
+ result += `\\x${ch.toString(16).toUpperCase().padStart(2, "0")}`;
943
+ } else {
944
+ result += `\\u${ch.toString(16).toUpperCase().padStart(4, "0")}`;
945
+ }
946
+ }
947
+ return result;
948
+ }
949
+ function encodeForUrl(value) {
950
+ if (!value) return "";
951
+ return encodeURIComponent(value).replace(/[!'()*]/g, (ch) => {
952
+ return `%${ch.charCodeAt(0).toString(16).toUpperCase()}`;
953
+ });
954
+ }
955
+ function encodeForCss(value) {
956
+ if (!value) return "";
957
+ let result = "";
958
+ for (let i = 0; i < value.length; i++) {
959
+ const ch = value.charCodeAt(i);
960
+ if (ch >= 48 && ch <= 57 || // 0-9
961
+ ch >= 65 && ch <= 90 || // A-Z
962
+ ch >= 97 && ch <= 122) {
963
+ result += value[i];
964
+ } else {
965
+ result += `\\${ch.toString(16).toUpperCase()} `;
966
+ }
967
+ }
968
+ return result;
969
+ }
970
+
904
971
  exports.createSanitizer = createSanitizer;
905
972
  exports.detectCommandInjection = detectCommandInjection;
906
973
  exports.detectHeaderInjection = detectHeaderInjection;
@@ -913,6 +980,11 @@ exports.detectSql = detectSql;
913
980
  exports.detectSsti = detectSsti;
914
981
  exports.detectXss = detectXss;
915
982
  exports.detectXxe = detectXxe;
983
+ exports.encodeForAttribute = encodeForAttribute;
984
+ exports.encodeForCss = encodeForCss;
985
+ exports.encodeForHtml = encodeForHtml;
986
+ exports.encodeForJs = encodeForJs;
987
+ exports.encodeForUrl = encodeForUrl;
916
988
  exports.encodeHtmlEntities = encodeHtmlEntities;
917
989
  exports.getDangerousOperators = getDangerousOperators;
918
990
  exports.getDangerousProtoKeys = getDangerousProtoKeys;