xypriss 9.6.97 → 9.7.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 (171) hide show
  1. package/README.md +55 -22
  2. package/dist/cjs/src/index.js +0 -19
  3. package/dist/cjs/src/index.js.map +1 -1
  4. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  5. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  6. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js +510 -0
  7. package/dist/cjs/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  8. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  9. package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  10. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js +413 -0
  11. package/dist/cjs/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  12. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js +98 -0
  13. package/dist/cjs/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  14. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js +52 -0
  15. package/dist/cjs/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  16. package/dist/cjs/src/middleware/safe-json-middleware.js +0 -82
  17. package/dist/cjs/src/middleware/safe-json-middleware.js.map +1 -1
  18. package/dist/cjs/src/middleware/security-middleware.js +7 -4
  19. package/dist/cjs/src/middleware/security-middleware.js.map +1 -1
  20. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  21. package/dist/cjs/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  22. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  23. package/dist/cjs/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  24. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  25. package/dist/cjs/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  26. package/dist/cjs/src/plugins/const/XyprissTempDir.js +72 -9
  27. package/dist/cjs/src/plugins/const/XyprissTempDir.js.map +1 -1
  28. package/dist/cjs/src/plugins/core/manager/PluginLoader.js +8 -0
  29. package/dist/cjs/src/plugins/core/manager/PluginLoader.js.map +1 -1
  30. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js +87 -0
  31. package/dist/cjs/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  32. package/dist/cjs/src/server/FastServer/index.js +5 -0
  33. package/dist/cjs/src/server/FastServer/index.js.map +1 -1
  34. package/dist/cjs/src/server/ServerFactory.js +8 -13
  35. package/dist/cjs/src/server/ServerFactory.js.map +1 -1
  36. package/dist/cjs/src/server/components/fastapi/RedirectManager.js +8 -58
  37. package/dist/cjs/src/server/components/fastapi/RedirectManager.js.map +1 -1
  38. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  39. package/dist/cjs/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  40. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js +9 -1
  41. package/dist/cjs/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  42. package/dist/cjs/src/server/core/HttpServer.js +22 -0
  43. package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
  44. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js +33 -2
  45. package/dist/cjs/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  46. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  47. package/dist/cjs/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  48. package/dist/cjs/src/server/core/XyServerCreator.js +1 -0
  49. package/dist/cjs/src/server/core/XyServerCreator.js.map +1 -1
  50. package/dist/cjs/src/shared/logger/quickLogger.js +162 -0
  51. package/dist/cjs/src/shared/logger/quickLogger.js.map +1 -0
  52. package/dist/cjs/src/xhsc/PathApi.js +44 -3
  53. package/dist/cjs/src/xhsc/PathApi.js.map +1 -1
  54. package/dist/cjs/src/xhsc/System.js +2 -0
  55. package/dist/cjs/src/xhsc/System.js.map +1 -1
  56. package/dist/cjs/src/xhsc/UtilsApi.js +52 -0
  57. package/dist/cjs/src/xhsc/UtilsApi.js.map +1 -0
  58. package/dist/cjs/src/xhsc/XyPrissRunner.js +30 -2
  59. package/dist/cjs/src/xhsc/XyPrissRunner.js.map +1 -1
  60. package/dist/cjs/src/xhsc/fs/FSCore.js +148 -0
  61. package/dist/cjs/src/xhsc/fs/FSCore.js.map +1 -1
  62. package/dist/cjs/src/xhsc/fs/FileHandle.js +112 -0
  63. package/dist/cjs/src/xhsc/fs/FileHandle.js.map +1 -0
  64. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js +134 -0
  65. package/dist/cjs/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  66. package/dist/cjs/src/xhsc/utils/ArrayUtils.js +67 -0
  67. package/dist/cjs/src/xhsc/utils/ArrayUtils.js.map +1 -0
  68. package/dist/cjs/src/xhsc/utils/AsyncUtils.js +582 -0
  69. package/dist/cjs/src/xhsc/utils/AsyncUtils.js.map +1 -0
  70. package/dist/cjs/src/xhsc/utils/DateUtils.js +959 -0
  71. package/dist/cjs/src/xhsc/utils/DateUtils.js.map +1 -0
  72. package/dist/cjs/src/xhsc/utils/FunctionUtils.js +29 -0
  73. package/dist/cjs/src/xhsc/utils/FunctionUtils.js.map +1 -0
  74. package/dist/cjs/src/xhsc/utils/IdUtils.js +22 -0
  75. package/dist/cjs/src/xhsc/utils/IdUtils.js.map +1 -0
  76. package/dist/cjs/src/xhsc/utils/NumberUtils.js +79 -0
  77. package/dist/cjs/src/xhsc/utils/NumberUtils.js.map +1 -0
  78. package/dist/cjs/src/xhsc/utils/ObjectUtils.js +141 -0
  79. package/dist/cjs/src/xhsc/utils/ObjectUtils.js.map +1 -0
  80. package/dist/cjs/src/xhsc/utils/StringUtils.js +145 -0
  81. package/dist/cjs/src/xhsc/utils/StringUtils.js.map +1 -0
  82. package/dist/cjs/src/xhsc/utils/ValidationUtils.js +49 -0
  83. package/dist/cjs/src/xhsc/utils/ValidationUtils.js.map +1 -0
  84. package/dist/cjs/src/xhsc.js +5 -3
  85. package/dist/cjs/src/xhsc.js.map +1 -1
  86. package/dist/esm/src/index.js +0 -2
  87. package/dist/esm/src/index.js.map +1 -1
  88. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js +4 -4
  89. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  90. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js +508 -0
  91. package/dist/esm/src/middleware/built-in/security/HoneypotTarpit.js.map +1 -0
  92. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js +113 -34
  93. package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -1
  94. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js +391 -0
  95. package/dist/esm/src/middleware/built-in/security/UriNormalizer.js.map +1 -0
  96. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js +96 -0
  97. package/dist/esm/src/middleware/built-in/security/XyPrissCors.js.map +1 -0
  98. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js +50 -0
  99. package/dist/esm/src/middleware/built-in/security/XyPrissHPP.js.map +1 -0
  100. package/dist/esm/src/middleware/safe-json-middleware.js +1 -79
  101. package/dist/esm/src/middleware/safe-json-middleware.js.map +1 -1
  102. package/dist/esm/src/middleware/security-middleware.js +7 -4
  103. package/dist/esm/src/middleware/security-middleware.js.map +1 -1
  104. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js +33 -10
  105. package/dist/esm/src/plugins/builtin/xems/XemsBuiltinPlugin.js.map +1 -1
  106. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js +34 -3
  107. package/dist/esm/src/plugins/builtin/xems/XemsPlugin.js.map +1 -1
  108. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js +1 -1
  109. package/dist/esm/src/plugins/const/OFFICIAL_PLUGINS.js.map +1 -1
  110. package/dist/esm/src/plugins/const/XyprissTempDir.js +70 -9
  111. package/dist/esm/src/plugins/const/XyprissTempDir.js.map +1 -1
  112. package/dist/esm/src/plugins/core/manager/PluginLoader.js +8 -0
  113. package/dist/esm/src/plugins/core/manager/PluginLoader.js.map +1 -1
  114. package/dist/esm/src/plugins/core/manager/PluginSecurity.js +87 -0
  115. package/dist/esm/src/plugins/core/manager/PluginSecurity.js.map +1 -1
  116. package/dist/esm/src/server/FastServer/index.js +5 -0
  117. package/dist/esm/src/server/FastServer/index.js.map +1 -1
  118. package/dist/esm/src/server/ServerFactory.js +8 -1
  119. package/dist/esm/src/server/ServerFactory.js.map +1 -1
  120. package/dist/esm/src/server/components/fastapi/RedirectManager.js +8 -58
  121. package/dist/esm/src/server/components/fastapi/RedirectManager.js.map +1 -1
  122. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js +1 -1
  123. package/dist/esm/src/server/components/fastapi/upload/FileUploadManager.js.map +1 -1
  124. package/dist/esm/src/server/components/multi-server/MultiServerManager.js +9 -1
  125. package/dist/esm/src/server/components/multi-server/MultiServerManager.js.map +1 -1
  126. package/dist/esm/src/server/core/HttpServer.js +22 -0
  127. package/dist/esm/src/server/core/HttpServer.js.map +1 -1
  128. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js +33 -2
  129. package/dist/esm/src/server/core/XHSCBridge/EngineManager.js.map +1 -1
  130. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js +1 -1
  131. package/dist/esm/src/server/core/XHSCBridge/cmd/buildSecurityArgs.js.map +1 -1
  132. package/dist/esm/src/server/core/XyServerCreator.js +1 -0
  133. package/dist/esm/src/server/core/XyServerCreator.js.map +1 -1
  134. package/dist/esm/src/shared/logger/quickLogger.js +160 -0
  135. package/dist/esm/src/shared/logger/quickLogger.js.map +1 -0
  136. package/dist/esm/src/xhsc/PathApi.js +44 -3
  137. package/dist/esm/src/xhsc/PathApi.js.map +1 -1
  138. package/dist/esm/src/xhsc/System.js +2 -0
  139. package/dist/esm/src/xhsc/System.js.map +1 -1
  140. package/dist/esm/src/xhsc/UtilsApi.js +50 -0
  141. package/dist/esm/src/xhsc/UtilsApi.js.map +1 -0
  142. package/dist/esm/src/xhsc/XyPrissRunner.js +30 -2
  143. package/dist/esm/src/xhsc/XyPrissRunner.js.map +1 -1
  144. package/dist/esm/src/xhsc/fs/FSCore.js +148 -0
  145. package/dist/esm/src/xhsc/fs/FSCore.js.map +1 -1
  146. package/dist/esm/src/xhsc/fs/FileHandle.js +110 -0
  147. package/dist/esm/src/xhsc/fs/FileHandle.js.map +1 -0
  148. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js +113 -0
  149. package/dist/esm/src/xhsc/ipc/XHSCDirectIPC.js.map +1 -0
  150. package/dist/esm/src/xhsc/utils/ArrayUtils.js +65 -0
  151. package/dist/esm/src/xhsc/utils/ArrayUtils.js.map +1 -0
  152. package/dist/esm/src/xhsc/utils/AsyncUtils.js +580 -0
  153. package/dist/esm/src/xhsc/utils/AsyncUtils.js.map +1 -0
  154. package/dist/esm/src/xhsc/utils/DateUtils.js +957 -0
  155. package/dist/esm/src/xhsc/utils/DateUtils.js.map +1 -0
  156. package/dist/esm/src/xhsc/utils/FunctionUtils.js +27 -0
  157. package/dist/esm/src/xhsc/utils/FunctionUtils.js.map +1 -0
  158. package/dist/esm/src/xhsc/utils/IdUtils.js +20 -0
  159. package/dist/esm/src/xhsc/utils/IdUtils.js.map +1 -0
  160. package/dist/esm/src/xhsc/utils/NumberUtils.js +77 -0
  161. package/dist/esm/src/xhsc/utils/NumberUtils.js.map +1 -0
  162. package/dist/esm/src/xhsc/utils/ObjectUtils.js +139 -0
  163. package/dist/esm/src/xhsc/utils/ObjectUtils.js.map +1 -0
  164. package/dist/esm/src/xhsc/utils/StringUtils.js +143 -0
  165. package/dist/esm/src/xhsc/utils/StringUtils.js.map +1 -0
  166. package/dist/esm/src/xhsc/utils/ValidationUtils.js +47 -0
  167. package/dist/esm/src/xhsc/utils/ValidationUtils.js.map +1 -0
  168. package/dist/esm/src/xhsc.js +6 -5
  169. package/dist/esm/src/xhsc.js.map +1 -1
  170. package/dist/index.d.ts +1872 -234
  171. package/package.json +119 -137
@@ -0,0 +1,510 @@
1
+ 'use strict';
2
+
3
+ var UriNormalizer = require('./UriNormalizer.js');
4
+
5
+ /**
6
+ * @module HoneypotTarpit
7
+ * @version 2.0.0
8
+ *
9
+ * A hardened, zero-false-positive honeypot tarpit designed to instantly identify
10
+ * and neutralize connections from malicious bots, vulnerability scanners, and
11
+ * automated exploit frameworks (e.g. Shodan crawlers, Nuclei, WPScan, Metasploit).
12
+ *
13
+ * ### Architecture
14
+ * Detection is performed in a layered pipeline, ordered from cheapest to most
15
+ * specific, so the most common attacks are rejected at the very first check:
16
+ *
17
+ * ```
18
+ * raw path
19
+ * │
20
+ * ▼
21
+ * [1] sanitizeInput() — rejects null / non-string / oversized paths
22
+ * │
23
+ * ▼
24
+ * [2] normalizePath() — decodes percent-encoding, collapses traversal
25
+ * sequences, removes redundant slashes
26
+ * │
27
+ * ▼
28
+ * [3] matchesExactTrap() — O(1) Set lookup for highest-confidence paths
29
+ * │
30
+ * ▼
31
+ * [4] matchesPrefixTrap() — catches sub-paths under sensitive directories
32
+ * │
33
+ * ▼
34
+ * [5] matchesSuffixTrap() — catches files by dangerous extension
35
+ * │
36
+ * ▼
37
+ * [6] matchesSegmentTrap() — catches scanner-specific path segments
38
+ * │
39
+ * ▼
40
+ * result → true (trap) | false (safe)
41
+ * ```
42
+ *
43
+ * ### Design Principles
44
+ * - **Zero false positives**: every rule targets patterns that are *never* used
45
+ * by legitimate production applications. Generic extensions like `.php` are
46
+ * intentionally excluded; only high-signal, context-specific signatures are used.
47
+ * - **Bypass resistance**: the normalizer resolves URL encoding, path traversal
48
+ * (`../`), and duplicate slashes before any rule is evaluated.
49
+ * - **O(1) hot path**: the most common scanner payloads hit a `Set` lookup and
50
+ * return immediately with no iteration cost.
51
+ * - **No public surface expansion**: all detection helpers are `private static`,
52
+ * keeping the public API surface identical to v1.
53
+ *
54
+ * ### Security Benefits
55
+ * - Bypasses all expensive application routing, regex matching, and payload parsing.
56
+ * - Responds with a bare 403 before any middleware, session, or DB code runs.
57
+ * - Saves server CPU and Node.js event-loop headroom under automated attack.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // Middleware usage (Express / Fastify raw handler)
62
+ * app.use((req, res, next) => {
63
+ * if (HoneypotTarpit.isTrap(req.url)) {
64
+ * return HoneypotTarpit.handleTrap(req, res);
65
+ * }
66
+ * next();
67
+ * });
68
+ * ```
69
+ */
70
+ class HoneypotTarpit {
71
+ // ─────────────────────────────────────────────────────────────────────────
72
+ // Public API
73
+ // ─────────────────────────────────────────────────────────────────────────
74
+ /**
75
+ * Determines whether a raw URI path matches any known honeypot trap signature.
76
+ *
77
+ * The method is intentionally **stateless and synchronous** to guarantee
78
+ * sub-millisecond latency even under high-volume scanner floods. It applies
79
+ * a four-stage pipeline internally (see module-level docs) and returns as
80
+ * soon as the first positive match is found.
81
+ *
82
+ * #### False-positive safeguards
83
+ * - Input is sanitized and validated before any rule is evaluated.
84
+ * - Path normalization resolves all encoding tricks before matching.
85
+ * - All rules are scoped to patterns that are unambiguously malicious.
86
+ * - Broad wildcard rules (e.g. "all `.php` files") are deliberately absent.
87
+ *
88
+ * @param {string} rawPath - The raw, un-normalized URI path from the incoming
89
+ * request (e.g. `req.url` in Node.js `http.IncomingMessage`). Query strings
90
+ * and fragments are accepted but stripped before evaluation.
91
+ * @returns {boolean} `true` if the path matches a trap and the request should
92
+ * be handed to {@link handleTrap}; `false` if the path appears legitimate.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * HoneypotTarpit.isTrap("/.env"); // true
97
+ * HoneypotTarpit.isTrap("/.env%2elocal"); // true (encoded bypass)
98
+ * HoneypotTarpit.isTrap("/api/v1/users"); // false
99
+ * HoneypotTarpit.isTrap("/assets/logo.png"); // false
100
+ * HoneypotTarpit.isTrap("/../.env"); // true (traversal bypass)
101
+ * ```
102
+ */
103
+ static isTrap(rawPath) {
104
+ if (!HoneypotTarpit.sanitizeInput(rawPath)) {
105
+ // Malformed or oversized paths are themselves a signal of probing.
106
+ return true;
107
+ }
108
+ const pathPart = rawPath.split(/[?#]/)[0];
109
+ const normalized = UriNormalizer.UriNormalizer.normalizePath(pathPart).toLowerCase();
110
+ return (HoneypotTarpit.matchesExactTrap(normalized) ||
111
+ HoneypotTarpit.matchesPrefixTrap(normalized) ||
112
+ HoneypotTarpit.matchesSuffixTrap(normalized) ||
113
+ HoneypotTarpit.matchesSegmentTrap(normalized));
114
+ }
115
+ /**
116
+ * Sends a minimal HTTP 403 Forbidden response and terminates the connection.
117
+ *
118
+ * The response is intentionally bare — no body, no `Content-Type`, no
119
+ * application-level headers — to minimize bandwidth consumption and avoid
120
+ * leaking server fingerprint information to the scanner.
121
+ *
122
+ * #### Why 403 and not a socket destroy?
123
+ * Destroying the raw socket (`req.socket.destroy()`) is tempting but unsafe
124
+ * when the Node.js process sits behind a reverse proxy (nginx, Caddy, HAProxy)
125
+ * or uses keep-alive connection pooling, because the socket may be shared
126
+ * across multiple logical HTTP requests. A 403 + `res.end()` correctly closes
127
+ * only the current HTTP transaction without disrupting the underlying TCP
128
+ * connection pool.
129
+ *
130
+ * @param {object} req - The raw incoming request object. Compatible with
131
+ * `http.IncomingMessage`, `Http2ServerRequest`, and Fastify/Express
132
+ * request wrappers. Not used directly but accepted for API symmetry and
133
+ * future extensibility (e.g. logging, rate-limiting by IP).
134
+ * @param {object} res - The raw outgoing response object. Must expose
135
+ * `writeHead(statusCode: number): void` and `end(): void`. Compatible
136
+ * with `http.ServerResponse`, `Http2ServerResponse`, and most framework
137
+ * response wrappers.
138
+ * @returns {void}
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * app.use((req, res, next) => {
143
+ * if (HoneypotTarpit.isTrap(req.url)) {
144
+ * return HoneypotTarpit.handleTrap(req, res);
145
+ * }
146
+ * next();
147
+ * });
148
+ * ```
149
+ */
150
+ static handleTrap(req, res) {
151
+ try {
152
+ if (typeof res.writeHead === "function") {
153
+ res.writeHead(403);
154
+ }
155
+ if (typeof res.end === "function") {
156
+ res.end();
157
+ }
158
+ }
159
+ catch {
160
+ // Failsafe: swallow all errors — the goal is merely to drop the
161
+ // connection. Any exception here means the socket is already gone.
162
+ }
163
+ }
164
+ // ─────────────────────────────────────────────────────────────────────────
165
+ // Private — Input Validation
166
+ // ─────────────────────────────────────────────────────────────────────────
167
+ /**
168
+ * Validates that the raw path is a non-empty string within the accepted
169
+ * length budget.
170
+ *
171
+ * Paths that fail this check (wrong type, empty, or suspiciously long) are
172
+ * themselves indicators of malicious probing and should be treated as traps
173
+ * by the caller.
174
+ *
175
+ * @param {unknown} value - The raw value received from the request object.
176
+ * @returns {boolean} `true` if the value is a safe, processable string;
177
+ * `false` if it should be rejected immediately.
178
+ *
179
+ * @internal
180
+ */
181
+ static sanitizeInput(value) {
182
+ return (typeof value === "string" &&
183
+ value.length > 0 &&
184
+ value.length <= HoneypotTarpit.MAX_PATH_LENGTH);
185
+ }
186
+ // ─────────────────────────────────────────────────────────────────────────
187
+ // Private — Match Layers
188
+ // ─────────────────────────────────────────────────────────────────────────
189
+ /**
190
+ * Layer 1 — Exact path match.
191
+ *
192
+ * Performs an O(1) `Set` lookup against {@link EXACT_TRAPS}. This is the
193
+ * most performant check and handles the vast majority of scanner probes,
194
+ * which tend to request well-known canonical paths verbatim.
195
+ *
196
+ * @param {string} normalizedPath - The fully normalized, lowercase path.
197
+ * @returns {boolean} `true` if the path is an exact trap match.
198
+ *
199
+ * @internal
200
+ */
201
+ static matchesExactTrap(normalizedPath) {
202
+ return HoneypotTarpit.EXACT_TRAPS.has(normalizedPath);
203
+ }
204
+ /**
205
+ * Layer 2 — Directory prefix match.
206
+ *
207
+ * Tests whether the normalized path starts with any entry from
208
+ * {@link PREFIX_TRAPS}. This catches requests for any sub-resource within
209
+ * a sensitive directory (e.g. `/.git/logs/HEAD`, `/.ssh/known_hosts`).
210
+ *
211
+ * Each prefix entry is stored with a trailing `/` to prevent false positives
212
+ * from partial name collisions (e.g. `/.gitignore` must not match the
213
+ * `/.git/` prefix).
214
+ *
215
+ * @param {string} normalizedPath - The fully normalized, lowercase path.
216
+ * @returns {boolean} `true` if the path falls under a trapped directory.
217
+ *
218
+ * @internal
219
+ */
220
+ static matchesPrefixTrap(normalizedPath) {
221
+ for (const prefix of HoneypotTarpit.PREFIX_TRAPS) {
222
+ if (normalizedPath.startsWith(prefix)) {
223
+ return true;
224
+ }
225
+ }
226
+ return false;
227
+ }
228
+ /**
229
+ * Layer 3 — File extension (suffix) match.
230
+ *
231
+ * Extracts the file extension from the final path segment and checks it
232
+ * against {@link SUFFIX_TRAPS}. Only the extension of the *filename* is
233
+ * considered; directory components are ignored to prevent collisions like
234
+ * `/certs-info/page` matching `.certs`.
235
+ *
236
+ * The comparison is performed on the already-lowercased normalized path,
237
+ * so no additional case folding is required here.
238
+ *
239
+ * @param {string} normalizedPath - The fully normalized, lowercase path.
240
+ * @returns {boolean} `true` if the file extension is a known trap extension.
241
+ *
242
+ * @internal
243
+ */
244
+ static matchesSuffixTrap(normalizedPath) {
245
+ const lastSegment = normalizedPath.split("/").pop() ?? "";
246
+ const dotIndex = lastSegment.lastIndexOf(".");
247
+ if (dotIndex === -1) {
248
+ return false; // No extension present.
249
+ }
250
+ const extension = lastSegment.slice(dotIndex); // e.g. ".pem"
251
+ return HoneypotTarpit.SUFFIX_TRAPS.has(extension);
252
+ }
253
+ /**
254
+ * Layer 4 — Path segment match.
255
+ *
256
+ * Splits the normalized path into discrete segments and checks each one
257
+ * against {@link SEGMENT_TRAPS}. This catches scanner payloads embedded
258
+ * at arbitrary depths (e.g. `/api/v2/actuator`, `/proxy/wp-login.php`).
259
+ *
260
+ * Matching on full segments (rather than substrings) prevents false positives
261
+ * such as `/administration` matching a rule for `admin`.
262
+ *
263
+ * @param {string} normalizedPath - The fully normalized, lowercase path.
264
+ * @returns {boolean} `true` if any path segment matches a known trap segment.
265
+ *
266
+ * @internal
267
+ */
268
+ static matchesSegmentTrap(normalizedPath) {
269
+ const segments = normalizedPath.split("/").filter(Boolean);
270
+ for (const segment of segments) {
271
+ if (HoneypotTarpit.SEGMENT_TRAPS.has(segment)) {
272
+ return true;
273
+ }
274
+ }
275
+ return false;
276
+ }
277
+ }
278
+ // ─────────────────────────────────────────────────────────────────────────
279
+ // Constants
280
+ // ─────────────────────────────────────────────────────────────────────────
281
+ /**
282
+ * Maximum accepted path length (bytes).
283
+ * Paths exceeding this length are treated as traps to neutralize buffer-probing
284
+ * attacks before any string processing occurs.
285
+ *
286
+ * @internal
287
+ */
288
+ HoneypotTarpit.MAX_PATH_LENGTH = 2048;
289
+ // ─────────────────────────────────────────────────────────────────────────
290
+ // Trap Signatures — Exact Paths
291
+ // ─────────────────────────────────────────────────────────────────────────
292
+ /**
293
+ * High-confidence exact paths that are **never** legitimate in any modern
294
+ * web application. All entries are lowercase; comparison is performed against
295
+ * a lowercased, normalized path.
296
+ *
297
+ * Sources: OWASP Top-10 scanner payloads, Shodan query signatures,
298
+ * Nuclei template library, Metasploit auxiliary scanner modules.
299
+ *
300
+ * @internal
301
+ */
302
+ HoneypotTarpit.EXACT_TRAPS = new Set([
303
+ // ── Credentials & Secrets ─────────────────────────────────────────
304
+ "/.env",
305
+ "/.env.local",
306
+ "/.env.production",
307
+ "/.env.staging",
308
+ "/.env.development",
309
+ "/.env.test",
310
+ "/.env.backup",
311
+ "/.env.bak",
312
+ "/.env.old",
313
+ "/.env.orig",
314
+ "/.env.example", // may contain real secrets in misconfigured repos
315
+ "/.aws/credentials",
316
+ "/.aws/config",
317
+ "/.ssh/id_rsa",
318
+ "/.ssh/id_dsa",
319
+ "/.ssh/id_ecdsa",
320
+ "/.ssh/id_ed25519",
321
+ "/.ssh/authorized_keys",
322
+ "/.ssh/known_hosts",
323
+ "/.netrc",
324
+ "/.htpasswd",
325
+ "/.pgpass",
326
+ // ── Git / Version Control ─────────────────────────────────────────
327
+ "/.git",
328
+ "/.git/config",
329
+ "/.git/head",
330
+ "/.git/index",
331
+ "/.git/packed-refs",
332
+ "/.git/refs/heads/main",
333
+ "/.git/refs/heads/master",
334
+ "/.gitconfig",
335
+ "/.svn/entries",
336
+ "/.hg/hgrc",
337
+ // ── Cloud & Infrastructure Config ─────────────────────────────────
338
+ "/docker-compose.yml",
339
+ "/docker-compose.yaml",
340
+ "/.dockerenv",
341
+ "/dockerfile",
342
+ "/kubernetes.yml",
343
+ "/k8s.yml",
344
+ "/terraform.tfvars",
345
+ "/.terraform/terraform.tfstate",
346
+ // ── Application Config Files ──────────────────────────────────────
347
+ "/config.json",
348
+ "/config.yml",
349
+ "/config.yaml",
350
+ "/settings.json",
351
+ "/appsettings.json",
352
+ "/appsettings.production.json",
353
+ "/web.config",
354
+ "/app.config",
355
+ "/database.yml",
356
+ "/secrets.yml",
357
+ // ── Dependency & Build Artefacts ──────────────────────────────────
358
+ "/composer.lock",
359
+ "/composer.json",
360
+ "/package.json",
361
+ "/package-lock.json",
362
+ "/yarn.lock",
363
+ "/gemfile.lock",
364
+ "/pipfile.lock",
365
+ "/poetry.lock",
366
+ "/cargo.lock",
367
+ "/go.sum",
368
+ // ── IDE & Editor Files ────────────────────────────────────────────
369
+ "/.vscode/sftp.json",
370
+ "/.vscode/launch.json",
371
+ "/.idea/dataSources.xml",
372
+ "/.idea/workspace.xml",
373
+ // ── PHP / WordPress ───────────────────────────────────────────────
374
+ "/wp-login.php",
375
+ "/wp-admin",
376
+ "/wp-config.php",
377
+ "/wp-config.php.bak",
378
+ "/wp-config.php.orig",
379
+ "/wp-config.php.save",
380
+ "/wp-config-sample.php",
381
+ "/xmlrpc.php",
382
+ "/phpinfo.php",
383
+ "/php.ini",
384
+ "/php-fpm.conf",
385
+ // ── Spring Boot / Java Actuator ───────────────────────────────────
386
+ "/actuator",
387
+ "/actuator/env",
388
+ "/actuator/health",
389
+ "/actuator/info",
390
+ "/actuator/mappings",
391
+ "/actuator/beans",
392
+ "/actuator/configprops",
393
+ "/actuator/dump",
394
+ "/actuator/shutdown",
395
+ "/env", // standalone Spring env endpoint
396
+ "/heapdump",
397
+ "/trace",
398
+ // ── Common CMS / Admin Panels ─────────────────────────────────────
399
+ "/admin",
400
+ "/administrator",
401
+ "/phpmyadmin",
402
+ "/pma",
403
+ "/adminer",
404
+ "/adminer.php",
405
+ "/typo3",
406
+ "/joomla",
407
+ "/drupal",
408
+ "/magento",
409
+ "/manager/html", // Tomcat manager
410
+ // ── macOS / OS Artefacts ──────────────────────────────────────────
411
+ "/.ds_store",
412
+ "/thumbs.db",
413
+ "/desktop.ini",
414
+ // ── Backup & Dump Files ───────────────────────────────────────────
415
+ "/backup.sql",
416
+ "/dump.sql",
417
+ "/database.sql",
418
+ "/db.sql",
419
+ "/backup.zip",
420
+ "/backup.tar.gz",
421
+ "/www.zip",
422
+ "/site.tar.gz",
423
+ ]);
424
+ // ─────────────────────────────────────────────────────────────────────────
425
+ // Trap Signatures — Directory Prefixes
426
+ // ─────────────────────────────────────────────────────────────────────────
427
+ /**
428
+ * Path prefixes whose entire subtree should be considered traps.
429
+ * A request for `/.git/logs/HEAD` is just as dangerous as one for `/.git/config`.
430
+ *
431
+ * Rules are matched with a trailing-slash anchor to avoid collisions
432
+ * (e.g. `/.gitignore` must **not** match the `/.git/` prefix rule).
433
+ *
434
+ * @internal
435
+ */
436
+ HoneypotTarpit.PREFIX_TRAPS = new Set([
437
+ "/.git/",
438
+ "/.svn/",
439
+ "/.hg/",
440
+ "/.ssh/",
441
+ "/.aws/",
442
+ "/.vscode/",
443
+ "/.idea/",
444
+ "/wp-includes/",
445
+ "/wp-content/plugins/",
446
+ "/wp-admin/",
447
+ "/actuator/",
448
+ "/proc/", // Linux /proc LFI attempts
449
+ "/etc/", // /etc/passwd, /etc/shadow LFI attempts
450
+ "/var/log/", // log file LFI
451
+ ]);
452
+ // ─────────────────────────────────────────────────────────────────────────
453
+ // Trap Signatures — File Extensions
454
+ // ─────────────────────────────────────────────────────────────────────────
455
+ /**
456
+ * File extensions that are exclusively associated with scanner probes or
457
+ * sensitive file types that should **never** be served over HTTP in any
458
+ * legitimate modern application.
459
+ *
460
+ * Deliberately conservative — common extensions like `.php`, `.bak`, or
461
+ * `.log` are excluded because they *may* be intentionally served by some
462
+ * apps. Only zero-ambiguity extensions are listed here.
463
+ *
464
+ * @internal
465
+ */
466
+ HoneypotTarpit.SUFFIX_TRAPS = new Set([
467
+ ".pem", // TLS private keys / certificates
468
+ ".p12", // PKCS#12 keystores
469
+ ".pfx", // Personal Information Exchange (Windows keystore)
470
+ ".key", // Generic private keys
471
+ ".crt", // X.509 certificates (when accessed directly)
472
+ ".cer", // Alternative certificate extension
473
+ ".jks", // Java KeyStore
474
+ ".id_rsa", // SSH private key variants with compound extensions
475
+ ".htaccess", // Apache access control — never a user-facing resource
476
+ ".htpasswd", // Apache password file
477
+ ".DS_Store", // macOS metadata (case-normalised before comparison)
478
+ ".tfstate", // Terraform state (may contain secrets)
479
+ ".tfvars", // Terraform variable files (often contain secrets)
480
+ ]);
481
+ // ─────────────────────────────────────────────────────────────────────────
482
+ // Trap Signatures — Path Segments
483
+ // ─────────────────────────────────────────────────────────────────────────
484
+ /**
485
+ * Discrete path segments (surrounded by `/` boundaries or at string edges)
486
+ * that indicate well-known scanner probes regardless of their position in
487
+ * the path hierarchy.
488
+ *
489
+ * Each entry is matched as a full segment to prevent substring collisions
490
+ * (e.g. `"admin"` must not trap `/admin-panel` but must trap `/api/admin`).
491
+ *
492
+ * @internal
493
+ */
494
+ HoneypotTarpit.SEGMENT_TRAPS = new Set([
495
+ "phpmyadmin",
496
+ "pma",
497
+ "adminer",
498
+ "wp-login.php",
499
+ "xmlrpc.php",
500
+ "phpinfo.php",
501
+ ".env",
502
+ ".git",
503
+ ".svn",
504
+ ".hg",
505
+ "actuator",
506
+ "heapdump",
507
+ ]);
508
+
509
+ exports.HoneypotTarpit = HoneypotTarpit;
510
+ //# sourceMappingURL=HoneypotTarpit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HoneypotTarpit.js","sources":["../../../../../../src/middleware/built-in/security/HoneypotTarpit.ts"],"sourcesContent":[null],"names":["UriNormalizer"],"mappings":"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"}