vaspera 2.10.1 → 2.12.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 (166) hide show
  1. package/dist/__tests__/audit-trail.test.d.ts +7 -0
  2. package/dist/__tests__/audit-trail.test.d.ts.map +1 -0
  3. package/dist/__tests__/audit-trail.test.js +336 -0
  4. package/dist/__tests__/audit-trail.test.js.map +1 -0
  5. package/dist/__tests__/property-test-helpers.d.ts +1 -1
  6. package/dist/action/pr-comment.test.js +9 -0
  7. package/dist/action/pr-comment.test.js.map +1 -1
  8. package/dist/action/sarif-upload.test.js +9 -0
  9. package/dist/action/sarif-upload.test.js.map +1 -1
  10. package/dist/autofix/ast/__tests__/typescript.test.d.ts +5 -0
  11. package/dist/autofix/ast/__tests__/typescript.test.d.ts.map +1 -0
  12. package/dist/autofix/ast/__tests__/typescript.test.js +210 -0
  13. package/dist/autofix/ast/__tests__/typescript.test.js.map +1 -0
  14. package/dist/autofix/ast/index.d.ts +11 -0
  15. package/dist/autofix/ast/index.d.ts.map +1 -0
  16. package/dist/autofix/ast/index.js +11 -0
  17. package/dist/autofix/ast/index.js.map +1 -0
  18. package/dist/autofix/ast/types.d.ts +77 -0
  19. package/dist/autofix/ast/types.d.ts.map +1 -0
  20. package/dist/autofix/ast/types.js +9 -0
  21. package/dist/autofix/ast/types.js.map +1 -0
  22. package/dist/autofix/ast/typescript.d.ts +17 -0
  23. package/dist/autofix/ast/typescript.d.ts.map +1 -0
  24. package/dist/autofix/ast/typescript.js +427 -0
  25. package/dist/autofix/ast/typescript.js.map +1 -0
  26. package/dist/autofix/constitution.schema.d.ts +21 -21
  27. package/dist/autofix/index.d.ts +1 -0
  28. package/dist/autofix/index.d.ts.map +1 -1
  29. package/dist/autofix/index.js +2 -0
  30. package/dist/autofix/index.js.map +1 -1
  31. package/dist/config/flags.d.ts +6 -6
  32. package/dist/history/store.d.ts +55 -1
  33. package/dist/history/store.d.ts.map +1 -1
  34. package/dist/history/store.js +152 -4
  35. package/dist/history/store.js.map +1 -1
  36. package/dist/history/types.d.ts +9 -5
  37. package/dist/history/types.d.ts.map +1 -1
  38. package/dist/history/verify.d.ts.map +1 -1
  39. package/dist/history/verify.js +5 -3
  40. package/dist/history/verify.js.map +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +627 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/integrations/siem/datadog.d.ts +44 -0
  45. package/dist/integrations/siem/datadog.d.ts.map +1 -0
  46. package/dist/integrations/siem/datadog.js +211 -0
  47. package/dist/integrations/siem/datadog.js.map +1 -0
  48. package/dist/integrations/siem/format.d.ts +59 -0
  49. package/dist/integrations/siem/format.d.ts.map +1 -0
  50. package/dist/integrations/siem/format.js +360 -0
  51. package/dist/integrations/siem/format.js.map +1 -0
  52. package/dist/integrations/siem/index.d.ts +56 -0
  53. package/dist/integrations/siem/index.d.ts.map +1 -0
  54. package/dist/integrations/siem/index.js +117 -0
  55. package/dist/integrations/siem/index.js.map +1 -0
  56. package/dist/integrations/siem/sentinel.d.ts +53 -0
  57. package/dist/integrations/siem/sentinel.d.ts.map +1 -0
  58. package/dist/integrations/siem/sentinel.js +231 -0
  59. package/dist/integrations/siem/sentinel.js.map +1 -0
  60. package/dist/integrations/siem/splunk.d.ts +46 -0
  61. package/dist/integrations/siem/splunk.d.ts.map +1 -0
  62. package/dist/integrations/siem/splunk.js +210 -0
  63. package/dist/integrations/siem/splunk.js.map +1 -0
  64. package/dist/integrations/siem/types.d.ts +210 -0
  65. package/dist/integrations/siem/types.d.ts.map +1 -0
  66. package/dist/integrations/siem/types.js +9 -0
  67. package/dist/integrations/siem/types.js.map +1 -0
  68. package/dist/persistence/__tests__/persistence.test.d.ts +5 -0
  69. package/dist/persistence/__tests__/persistence.test.d.ts.map +1 -0
  70. package/dist/persistence/__tests__/persistence.test.js +369 -0
  71. package/dist/persistence/__tests__/persistence.test.js.map +1 -0
  72. package/dist/persistence/db.d.ts +15 -0
  73. package/dist/persistence/db.d.ts.map +1 -0
  74. package/dist/persistence/db.js +79 -0
  75. package/dist/persistence/db.js.map +1 -0
  76. package/dist/persistence/index.d.ts +66 -0
  77. package/dist/persistence/index.d.ts.map +1 -0
  78. package/dist/persistence/index.js +143 -0
  79. package/dist/persistence/index.js.map +1 -0
  80. package/dist/persistence/migrations/index.d.ts +10 -0
  81. package/dist/persistence/migrations/index.d.ts.map +1 -0
  82. package/dist/persistence/migrations/index.js +125 -0
  83. package/dist/persistence/migrations/index.js.map +1 -0
  84. package/dist/persistence/repositories/findings.d.ts +41 -0
  85. package/dist/persistence/repositories/findings.d.ts.map +1 -0
  86. package/dist/persistence/repositories/findings.js +238 -0
  87. package/dist/persistence/repositories/findings.js.map +1 -0
  88. package/dist/persistence/repositories/projects.d.ts +22 -0
  89. package/dist/persistence/repositories/projects.d.ts.map +1 -0
  90. package/dist/persistence/repositories/projects.js +71 -0
  91. package/dist/persistence/repositories/projects.js.map +1 -0
  92. package/dist/persistence/repositories/scans.d.ts +30 -0
  93. package/dist/persistence/repositories/scans.d.ts.map +1 -0
  94. package/dist/persistence/repositories/scans.js +107 -0
  95. package/dist/persistence/repositories/scans.js.map +1 -0
  96. package/dist/persistence/repositories/trends.d.ts +42 -0
  97. package/dist/persistence/repositories/trends.d.ts.map +1 -0
  98. package/dist/persistence/repositories/trends.js +178 -0
  99. package/dist/persistence/repositories/trends.js.map +1 -0
  100. package/dist/persistence/types.d.ts +105 -0
  101. package/dist/persistence/types.d.ts.map +1 -0
  102. package/dist/persistence/types.js +13 -0
  103. package/dist/persistence/types.js.map +1 -0
  104. package/dist/plugins/types.d.ts +2 -2
  105. package/dist/scanners/ai-code/types.d.ts +12 -12
  106. package/dist/scanners/cache.d.ts.map +1 -1
  107. package/dist/scanners/cache.js +9 -0
  108. package/dist/scanners/cache.js.map +1 -1
  109. package/dist/scanners/dast.d.ts +40 -0
  110. package/dist/scanners/dast.d.ts.map +1 -0
  111. package/dist/scanners/dast.js +228 -0
  112. package/dist/scanners/dast.js.map +1 -0
  113. package/dist/scanners/deploy/types.d.ts +19 -19
  114. package/dist/scanners/detection/__tests__/detection.test.d.ts +5 -0
  115. package/dist/scanners/detection/__tests__/detection.test.d.ts.map +1 -0
  116. package/dist/scanners/detection/__tests__/detection.test.js +265 -0
  117. package/dist/scanners/detection/__tests__/detection.test.js.map +1 -0
  118. package/dist/scanners/detection/engines/ast-query.d.ts +23 -0
  119. package/dist/scanners/detection/engines/ast-query.d.ts.map +1 -0
  120. package/dist/scanners/detection/engines/ast-query.js +232 -0
  121. package/dist/scanners/detection/engines/ast-query.js.map +1 -0
  122. package/dist/scanners/detection/engines/data-flow.d.ts +12 -0
  123. package/dist/scanners/detection/engines/data-flow.d.ts.map +1 -0
  124. package/dist/scanners/detection/engines/data-flow.js +269 -0
  125. package/dist/scanners/detection/engines/data-flow.js.map +1 -0
  126. package/dist/scanners/detection/index.d.ts +29 -0
  127. package/dist/scanners/detection/index.d.ts.map +1 -0
  128. package/dist/scanners/detection/index.js +140 -0
  129. package/dist/scanners/detection/index.js.map +1 -0
  130. package/dist/scanners/detection/rules/builtin.d.ts +14 -0
  131. package/dist/scanners/detection/rules/builtin.d.ts.map +1 -0
  132. package/dist/scanners/detection/rules/builtin.js +307 -0
  133. package/dist/scanners/detection/rules/builtin.js.map +1 -0
  134. package/dist/scanners/detection/rules/loader.d.ts +19 -0
  135. package/dist/scanners/detection/rules/loader.d.ts.map +1 -0
  136. package/dist/scanners/detection/rules/loader.js +111 -0
  137. package/dist/scanners/detection/rules/loader.js.map +1 -0
  138. package/dist/scanners/detection/types.d.ts +171 -0
  139. package/dist/scanners/detection/types.d.ts.map +1 -0
  140. package/dist/scanners/detection/types.js +36 -0
  141. package/dist/scanners/detection/types.js.map +1 -0
  142. package/dist/scanners/index.d.ts +13 -5
  143. package/dist/scanners/index.d.ts.map +1 -1
  144. package/dist/scanners/index.js +197 -15
  145. package/dist/scanners/index.js.map +1 -1
  146. package/dist/scanners/index.test.js +6 -6
  147. package/dist/scanners/index.test.js.map +1 -1
  148. package/dist/scanners/openapi.d.ts +20 -0
  149. package/dist/scanners/openapi.d.ts.map +1 -0
  150. package/dist/scanners/openapi.js +226 -0
  151. package/dist/scanners/openapi.js.map +1 -0
  152. package/dist/scanners/runtime/types.d.ts +4 -4
  153. package/dist/scanners/rust.d.ts +22 -0
  154. package/dist/scanners/rust.d.ts.map +1 -0
  155. package/dist/scanners/rust.js +239 -0
  156. package/dist/scanners/rust.js.map +1 -0
  157. package/dist/scanners/scale/types.d.ts +19 -19
  158. package/dist/scanners/terraform.d.ts +23 -0
  159. package/dist/scanners/terraform.d.ts.map +1 -0
  160. package/dist/scanners/terraform.js +207 -0
  161. package/dist/scanners/terraform.js.map +1 -0
  162. package/dist/scanners/types.d.ts +1 -1
  163. package/dist/scanners/types.d.ts.map +1 -1
  164. package/dist/scanners/types.js +9 -0
  165. package/dist/scanners/types.js.map +1 -1
  166. package/package.json +5 -1
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Built-in Detection Rules
3
+ *
4
+ * Proprietary detection rules that differentiate Vaspera from Semgrep wrappers.
5
+ * These rules use data flow and control flow analysis for high-confidence detection.
6
+ *
7
+ * @module scanners/detection/rules/builtin
8
+ */
9
+ export const BUILTIN_RULES = [
10
+ {
11
+ id: "vaspera:idor:user-controlled-id",
12
+ name: "User-Controlled ID Without Ownership Check",
13
+ description: "API endpoint accepts user-controlled ID parameter without verifying the requesting user owns the referenced resource. This allows attackers to access other users' data by manipulating the ID.",
14
+ category: "idor",
15
+ severity: "high",
16
+ confidence: 85,
17
+ enabled: true,
18
+ engines: {
19
+ dataFlow: {
20
+ sources: [
21
+ { pattern: "req.params.$id", description: "URL path parameter" },
22
+ { pattern: "req.query.$id", description: "Query string parameter" },
23
+ { pattern: "req.body.$id", description: "Request body field" },
24
+ { pattern: "request.params.$id" },
25
+ { pattern: "ctx.params.$id" },
26
+ ],
27
+ sinks: [
28
+ { pattern: "findById($source)", description: "Direct ID lookup" },
29
+ { pattern: "findOne({ id: $source })" },
30
+ { pattern: "findUnique({ where: { id: $source } })" },
31
+ { pattern: "where({ id: $source })" },
32
+ { pattern: "get($source)" },
33
+ ],
34
+ sanitizers: [
35
+ { pattern: "verifyOwnership($source, $user)" },
36
+ { pattern: "checkAccess($source, $user)" },
37
+ { pattern: "belongsTo($source, $user)" },
38
+ { pattern: "isOwner($source)" },
39
+ { pattern: "canAccess($source)" },
40
+ ],
41
+ },
42
+ },
43
+ cweIds: ["CWE-639", "CWE-284"],
44
+ owaspRefs: ["API1:2023", "A01:2021"],
45
+ autofixPatternId: "add-ownership-check",
46
+ },
47
+ {
48
+ id: "vaspera:bola:mass-assignment",
49
+ name: "Broken Object Level Authorization via Mass Assignment",
50
+ description: "Endpoint accepts object updates without filtering sensitive fields or verifying authorization. Attackers can modify fields they shouldn't have access to (e.g., isAdmin, role, balance).",
51
+ category: "bola",
52
+ severity: "high",
53
+ confidence: 80,
54
+ enabled: true,
55
+ engines: {
56
+ dataFlow: {
57
+ sources: [
58
+ { pattern: "req.body", description: "Full request body" },
59
+ { pattern: "request.body" },
60
+ { pattern: "ctx.request.body" },
61
+ { pattern: "{ ...req.body }", description: "Spread request body" },
62
+ ],
63
+ sinks: [
64
+ { pattern: "update($source)" },
65
+ { pattern: "updateOne($source)" },
66
+ { pattern: "updateMany($source)" },
67
+ { pattern: "save($source)" },
68
+ { pattern: "Object.assign($target, $source)" },
69
+ { pattern: "{ ...$target, ...$source }" },
70
+ ],
71
+ sanitizers: [
72
+ { pattern: "pick($source, $fields)", description: "Whitelist fields" },
73
+ { pattern: "omit($source, $fields)", description: "Blacklist fields" },
74
+ { pattern: "sanitize($source)" },
75
+ { pattern: "allowedFields.filter" },
76
+ ],
77
+ },
78
+ },
79
+ cweIds: ["CWE-915", "CWE-284"],
80
+ owaspRefs: ["API3:2023", "A01:2021"],
81
+ autofixPatternId: "add-field-whitelist",
82
+ },
83
+ {
84
+ id: "vaspera:auth-bypass:missing-middleware",
85
+ name: "Missing Authentication Middleware",
86
+ description: "Route handler accesses sensitive operations without authentication middleware. The endpoint can be accessed by unauthenticated users.",
87
+ category: "auth-bypass",
88
+ severity: "critical",
89
+ confidence: 75,
90
+ enabled: true,
91
+ engines: {
92
+ astQuery: {
93
+ pattern: "router.$method($path, $handler)",
94
+ constraints: {
95
+ method: "get|post|put|patch|delete",
96
+ },
97
+ },
98
+ controlFlow: {
99
+ entryPoints: [
100
+ "router.get",
101
+ "router.post",
102
+ "router.put",
103
+ "router.patch",
104
+ "router.delete",
105
+ "app.get",
106
+ "app.post",
107
+ ],
108
+ mustReach: [
109
+ { pattern: "req.user", description: "Must access authenticated user" },
110
+ { pattern: "req.session", description: "Must check session" },
111
+ { pattern: "isAuthenticated", description: "Must verify authentication" },
112
+ { pattern: "requireAuth", description: "Must require authentication" },
113
+ ],
114
+ },
115
+ },
116
+ cweIds: ["CWE-306", "CWE-287"],
117
+ owaspRefs: ["API2:2023", "A07:2021"],
118
+ autofixPatternId: "add-auth-middleware",
119
+ },
120
+ {
121
+ id: "vaspera:ssrf:user-controlled-url",
122
+ name: "Server-Side Request Forgery via User-Controlled URL",
123
+ description: "User-controlled input is used to construct a URL for server-side HTTP requests. Attackers can make the server request internal resources or external malicious endpoints.",
124
+ category: "ssrf",
125
+ severity: "high",
126
+ confidence: 90,
127
+ enabled: true,
128
+ engines: {
129
+ dataFlow: {
130
+ sources: [
131
+ { pattern: "req.body.url" },
132
+ { pattern: "req.query.url" },
133
+ { pattern: "req.params.url" },
134
+ { pattern: "req.body.webhook" },
135
+ { pattern: "req.body.callback" },
136
+ { pattern: "req.body.redirect" },
137
+ { pattern: "req.body.target" },
138
+ { pattern: "req.body.host" },
139
+ { pattern: "req.query.redirect_uri" },
140
+ ],
141
+ sinks: [
142
+ { pattern: "fetch($source)" },
143
+ { pattern: "axios.get($source)" },
144
+ { pattern: "axios.post($source)" },
145
+ { pattern: "axios($source)" },
146
+ { pattern: "request($source)" },
147
+ { pattern: "http.get($source)" },
148
+ { pattern: "https.get($source)" },
149
+ { pattern: "got($source)" },
150
+ { pattern: "superagent.get($source)" },
151
+ { pattern: "new URL($source)" },
152
+ ],
153
+ sanitizers: [
154
+ { pattern: "validateUrl($source)" },
155
+ { pattern: "isAllowedUrl($source)" },
156
+ { pattern: "sanitizeUrl($source)" },
157
+ { pattern: "allowlist.includes($source)" },
158
+ { pattern: "ALLOWED_HOSTS.includes" },
159
+ ],
160
+ },
161
+ },
162
+ cweIds: ["CWE-918"],
163
+ owaspRefs: ["API8:2023", "A10:2021"],
164
+ autofixPatternId: "add-url-validation",
165
+ },
166
+ {
167
+ id: "vaspera:race:toctou-file",
168
+ name: "Time-of-Check to Time-of-Use Race Condition",
169
+ description: "File existence or permission is checked before use, but the file state may change between check and use. Attackers can exploit this window to manipulate the file.",
170
+ category: "race-condition",
171
+ severity: "medium",
172
+ confidence: 70,
173
+ enabled: true,
174
+ engines: {
175
+ astQuery: {
176
+ pattern: "existsSync($path)",
177
+ },
178
+ dataFlow: {
179
+ sources: [
180
+ { pattern: "fs.existsSync($path)" },
181
+ { pattern: "fs.accessSync($path)" },
182
+ { pattern: "fs.statSync($path)" },
183
+ { pattern: "path.exists($path)" },
184
+ ],
185
+ sinks: [
186
+ { pattern: "fs.readFileSync($path)" },
187
+ { pattern: "fs.writeFileSync($path)" },
188
+ { pattern: "fs.unlinkSync($path)" },
189
+ { pattern: "fs.readFile($path)" },
190
+ { pattern: "fs.writeFile($path)" },
191
+ { pattern: "fs.unlink($path)" },
192
+ { pattern: "require($path)" },
193
+ ],
194
+ sanitizers: [
195
+ { pattern: "fs.open($path, $flags)" },
196
+ { pattern: "flock($fd)" },
197
+ { pattern: "lockFile($path)" },
198
+ ],
199
+ },
200
+ },
201
+ cweIds: ["CWE-367", "CWE-362"],
202
+ owaspRefs: ["A04:2021"],
203
+ autofixPatternId: "use-atomic-operations",
204
+ },
205
+ {
206
+ id: "vaspera:sqli:template-literal",
207
+ name: "SQL Injection via Template Literal",
208
+ description: "User input is interpolated directly into SQL query using template literals. Attackers can inject malicious SQL to access, modify, or delete data.",
209
+ category: "sql-injection",
210
+ severity: "critical",
211
+ confidence: 95,
212
+ enabled: true,
213
+ engines: {
214
+ dataFlow: {
215
+ sources: [
216
+ { pattern: "req.params.$param" },
217
+ { pattern: "req.query.$param" },
218
+ { pattern: "req.body.$field" },
219
+ ],
220
+ sinks: [
221
+ { pattern: "query(`SELECT ... ${$source} ...`)" },
222
+ { pattern: "execute(`... ${$source} ...`)" },
223
+ { pattern: "raw(`... ${$source} ...`)" },
224
+ { pattern: "$connection.query(`... ${$source} ...`)" },
225
+ { pattern: "db.query(`... ${$source} ...`)" },
226
+ { pattern: "sql`... ${$source} ...`" },
227
+ ],
228
+ sanitizers: [
229
+ { pattern: "escape($source)" },
230
+ { pattern: "sanitize($source)" },
231
+ { pattern: "parseInt($source)" },
232
+ { pattern: "Number($source)" },
233
+ ],
234
+ },
235
+ },
236
+ cweIds: ["CWE-89"],
237
+ owaspRefs: ["API8:2023", "A03:2021"],
238
+ autofixPatternId: "parameterize-query",
239
+ },
240
+ {
241
+ id: "vaspera:xss:innerHTML",
242
+ name: "Cross-Site Scripting via innerHTML",
243
+ description: "User input is assigned to innerHTML without sanitization. Attackers can inject malicious scripts that execute in other users' browsers.",
244
+ category: "xss",
245
+ severity: "high",
246
+ confidence: 90,
247
+ enabled: true,
248
+ engines: {
249
+ dataFlow: {
250
+ sources: [
251
+ { pattern: "req.body.$field" },
252
+ { pattern: "req.query.$param" },
253
+ { pattern: "document.location.search" },
254
+ { pattern: "window.location.hash" },
255
+ { pattern: "searchParams.get($param)" },
256
+ ],
257
+ sinks: [
258
+ { pattern: "$el.innerHTML = $source" },
259
+ { pattern: "$el.outerHTML = $source" },
260
+ { pattern: "document.write($source)" },
261
+ { pattern: "insertAdjacentHTML($position, $source)" },
262
+ { pattern: "dangerouslySetInnerHTML={{ __html: $source }}" },
263
+ ],
264
+ sanitizers: [
265
+ { pattern: "DOMPurify.sanitize($source)" },
266
+ { pattern: "sanitizeHtml($source)" },
267
+ { pattern: "escape($source)" },
268
+ { pattern: "encodeURIComponent($source)" },
269
+ { pattern: "textContent = $source" },
270
+ ],
271
+ },
272
+ },
273
+ cweIds: ["CWE-79"],
274
+ owaspRefs: ["A03:2021"],
275
+ autofixPatternId: "use-textContent",
276
+ },
277
+ {
278
+ id: "vaspera:secrets:hardcoded-credential",
279
+ name: "Hardcoded Credential in Source Code",
280
+ description: "API key, password, or other secret is hardcoded in source code. Secrets in code are exposed through version control and can be extracted from compiled artifacts.",
281
+ category: "secrets",
282
+ severity: "critical",
283
+ confidence: 85,
284
+ enabled: true,
285
+ engines: {
286
+ astQuery: {
287
+ pattern: "const $name = $value",
288
+ constraints: {
289
+ name: "password|apiKey|secret|token|credential|auth",
290
+ },
291
+ },
292
+ },
293
+ cweIds: ["CWE-798", "CWE-259"],
294
+ owaspRefs: ["A02:2021"],
295
+ autofixPatternId: "use-env-variable",
296
+ },
297
+ ];
298
+ export function getBuiltinRules() {
299
+ return BUILTIN_RULES.filter((r) => r.enabled);
300
+ }
301
+ export function getBuiltinRuleById(id) {
302
+ return BUILTIN_RULES.find((r) => r.id === id);
303
+ }
304
+ export function getBuiltinRulesByCategory(category) {
305
+ return BUILTIN_RULES.filter((r) => r.category === category && r.enabled);
306
+ }
307
+ //# sourceMappingURL=builtin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../../src/scanners/detection/rules/builtin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Detection Rule Loader
3
+ *
4
+ * Loads and validates detection rules from YAML files or inline definitions.
5
+ *
6
+ * @module scanners/detection/rules/loader
7
+ */
8
+ import type { DetectionRule } from "../types.js";
9
+ export declare class RuleValidationError extends Error {
10
+ ruleId: string;
11
+ field: string;
12
+ constructor(ruleId: string, field: string, message: string);
13
+ }
14
+ export declare function loadRuleFromYAML(filePath: string): Promise<DetectionRule>;
15
+ export declare function loadRulesFromDirectory(dirPath: string): Promise<DetectionRule[]>;
16
+ export declare function createRule(config: Omit<DetectionRule, "enabled"> & {
17
+ enabled?: boolean;
18
+ }): DetectionRule;
19
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/scanners/detection/rules/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,qBAAa,mBAAoB,SAAQ,KAAK;IAEnC,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,MAAM;gBADb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;CAKlB;AA6ED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAI/E;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAmBtF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,CAExG"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Detection Rule Loader
3
+ *
4
+ * Loads and validates detection rules from YAML files or inline definitions.
5
+ *
6
+ * @module scanners/detection/rules/loader
7
+ */
8
+ import { readFile, readdir } from "fs/promises";
9
+ import { join, extname } from "path";
10
+ import { parse as parseYAML } from "yaml";
11
+ const VALID_SEVERITIES = ["critical", "high", "medium", "low", "info"];
12
+ const VALID_ENGINES = ["astQuery", "dataFlow", "controlFlow"];
13
+ export class RuleValidationError extends Error {
14
+ ruleId;
15
+ field;
16
+ constructor(ruleId, field, message) {
17
+ super(`Rule ${ruleId}: ${field} - ${message}`);
18
+ this.ruleId = ruleId;
19
+ this.field = field;
20
+ this.name = "RuleValidationError";
21
+ }
22
+ }
23
+ function validateRule(rule, source) {
24
+ if (typeof rule !== "object" || rule === null) {
25
+ throw new RuleValidationError(source, "root", "Rule must be an object");
26
+ }
27
+ const r = rule;
28
+ if (typeof r.id !== "string" || !r.id) {
29
+ throw new RuleValidationError(source, "id", "Required string field");
30
+ }
31
+ if (typeof r.name !== "string" || !r.name) {
32
+ throw new RuleValidationError(r.id, "name", "Required string field");
33
+ }
34
+ if (typeof r.description !== "string" || !r.description) {
35
+ throw new RuleValidationError(r.id, "description", "Required string field");
36
+ }
37
+ if (typeof r.category !== "string" || !r.category) {
38
+ throw new RuleValidationError(r.id, "category", "Required string field");
39
+ }
40
+ if (!VALID_SEVERITIES.includes(r.severity)) {
41
+ throw new RuleValidationError(r.id, "severity", `Must be one of: ${VALID_SEVERITIES.join(", ")}`);
42
+ }
43
+ if (typeof r.confidence !== "number" || r.confidence < 0 || r.confidence > 100) {
44
+ throw new RuleValidationError(r.id, "confidence", "Must be a number between 0 and 100");
45
+ }
46
+ if (typeof r.engines !== "object" || r.engines === null) {
47
+ throw new RuleValidationError(r.id, "engines", "Required object field");
48
+ }
49
+ const engines = r.engines;
50
+ const hasEngine = VALID_ENGINES.some((e) => engines[e] !== undefined);
51
+ if (!hasEngine) {
52
+ throw new RuleValidationError(r.id, "engines", `Must have at least one of: ${VALID_ENGINES.join(", ")}`);
53
+ }
54
+ if (engines.dataFlow) {
55
+ const df = engines.dataFlow;
56
+ if (!Array.isArray(df.sources) || df.sources.length === 0) {
57
+ throw new RuleValidationError(r.id, "engines.dataFlow.sources", "Required non-empty array");
58
+ }
59
+ if (!Array.isArray(df.sinks) || df.sinks.length === 0) {
60
+ throw new RuleValidationError(r.id, "engines.dataFlow.sinks", "Required non-empty array");
61
+ }
62
+ }
63
+ if (engines.astQuery) {
64
+ const aq = engines.astQuery;
65
+ if (typeof aq.pattern !== "string" || !aq.pattern) {
66
+ throw new RuleValidationError(r.id, "engines.astQuery.pattern", "Required string field");
67
+ }
68
+ }
69
+ return {
70
+ id: r.id,
71
+ name: r.name,
72
+ description: r.description,
73
+ category: r.category,
74
+ severity: r.severity,
75
+ confidence: r.confidence,
76
+ enabled: r.enabled !== false,
77
+ engines: r.engines,
78
+ cweIds: Array.isArray(r.cweIds) ? r.cweIds : undefined,
79
+ owaspRefs: Array.isArray(r.owaspRefs) ? r.owaspRefs : undefined,
80
+ autofixPatternId: typeof r.autofixPatternId === "string" ? r.autofixPatternId : undefined,
81
+ metadata: typeof r.metadata === "object" ? r.metadata : undefined,
82
+ };
83
+ }
84
+ export async function loadRuleFromYAML(filePath) {
85
+ const content = await readFile(filePath, "utf-8");
86
+ const parsed = parseYAML(content);
87
+ return validateRule(parsed, filePath);
88
+ }
89
+ export async function loadRulesFromDirectory(dirPath) {
90
+ const rules = [];
91
+ const entries = await readdir(dirPath, { withFileTypes: true });
92
+ for (const entry of entries) {
93
+ if (!entry.isFile())
94
+ continue;
95
+ const ext = extname(entry.name).toLowerCase();
96
+ if (ext !== ".yaml" && ext !== ".yml")
97
+ continue;
98
+ try {
99
+ const rule = await loadRuleFromYAML(join(dirPath, entry.name));
100
+ rules.push(rule);
101
+ }
102
+ catch (error) {
103
+ console.warn(`Failed to load rule ${entry.name}:`, error);
104
+ }
105
+ }
106
+ return rules;
107
+ }
108
+ export function createRule(config) {
109
+ return validateRule({ ...config, enabled: config.enabled ?? true }, config.id);
110
+ }
111
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/scanners/detection/rules/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Detection Engine Types
3
+ *
4
+ * Types for the custom detection engine that provides proprietary
5
+ * security analysis beyond wrapped tools like Semgrep.
6
+ *
7
+ * @module scanners/detection/types
8
+ */
9
+ import type { Severity } from "../../certification/types.js";
10
+ /**
11
+ * Supported detection engines
12
+ */
13
+ export type DetectionEngine = "ast-query" | "data-flow" | "control-flow" | "semantic";
14
+ /**
15
+ * A taint source - where untrusted data enters
16
+ */
17
+ export interface TaintSource {
18
+ pattern: string;
19
+ description?: string;
20
+ parameterIndex?: number;
21
+ }
22
+ /**
23
+ * A taint sink - dangerous operation that consumes data
24
+ */
25
+ export interface TaintSink {
26
+ pattern: string;
27
+ description?: string;
28
+ parameterIndex?: number;
29
+ }
30
+ /**
31
+ * A sanitizer that neutralizes tainted data
32
+ */
33
+ export interface Sanitizer {
34
+ pattern: string;
35
+ description?: string;
36
+ }
37
+ /**
38
+ * Data flow rule configuration
39
+ */
40
+ export interface DataFlowConfig {
41
+ sources: TaintSource[];
42
+ sinks: TaintSink[];
43
+ sanitizers?: Sanitizer[];
44
+ requireAllSources?: boolean;
45
+ }
46
+ /**
47
+ * Control flow rule configuration
48
+ */
49
+ export interface ControlFlowConfig {
50
+ entryPoints?: string[];
51
+ mustReach?: {
52
+ pattern: string;
53
+ description?: string;
54
+ }[];
55
+ mustNotReach?: {
56
+ pattern: string;
57
+ description?: string;
58
+ }[];
59
+ }
60
+ /**
61
+ * AST query rule configuration
62
+ */
63
+ export interface ASTQueryConfig {
64
+ pattern: string;
65
+ language?: "typescript" | "javascript" | "python" | "go" | "ruby";
66
+ capture?: string;
67
+ constraints?: Record<string, string>;
68
+ }
69
+ /**
70
+ * Detection rule definition
71
+ */
72
+ export interface DetectionRule {
73
+ id: string;
74
+ name: string;
75
+ description: string;
76
+ category: string;
77
+ severity: Severity;
78
+ confidence: number;
79
+ enabled?: boolean;
80
+ engines: {
81
+ astQuery?: ASTQueryConfig;
82
+ dataFlow?: DataFlowConfig;
83
+ controlFlow?: ControlFlowConfig;
84
+ };
85
+ cweIds?: string[];
86
+ owaspRefs?: string[];
87
+ autofixPatternId?: string;
88
+ metadata?: Record<string, unknown>;
89
+ }
90
+ /**
91
+ * A path from taint source to sink
92
+ */
93
+ export interface TaintPath {
94
+ source: {
95
+ pattern: string;
96
+ file: string;
97
+ line: number;
98
+ column?: number;
99
+ expression: string;
100
+ };
101
+ sink: {
102
+ pattern: string;
103
+ file: string;
104
+ line: number;
105
+ column?: number;
106
+ expression: string;
107
+ };
108
+ intermediateNodes: {
109
+ file: string;
110
+ line: number;
111
+ expression: string;
112
+ }[];
113
+ sanitized: boolean;
114
+ sanitizer?: string;
115
+ }
116
+ /**
117
+ * Result from running detection on a single file
118
+ */
119
+ export interface DetectionMatch {
120
+ ruleId: string;
121
+ file: string;
122
+ line: number;
123
+ column?: number;
124
+ endLine?: number;
125
+ endColumn?: number;
126
+ message: string;
127
+ severity: Severity;
128
+ confidence: number;
129
+ category: string;
130
+ evidence: string;
131
+ taintPath?: TaintPath;
132
+ cweIds?: string[];
133
+ owaspRefs?: string[];
134
+ autofixPatternId?: string;
135
+ }
136
+ /**
137
+ * Result from running detection engine
138
+ */
139
+ export interface DetectionResult {
140
+ success: boolean;
141
+ matches: DetectionMatch[];
142
+ rulesEvaluated: number;
143
+ filesAnalyzed: number;
144
+ duration: number;
145
+ errors?: string[];
146
+ }
147
+ /**
148
+ * Detection engine context
149
+ */
150
+ export interface DetectionContext {
151
+ projectPath: string;
152
+ files?: string[];
153
+ rules?: DetectionRule[];
154
+ include?: string[];
155
+ exclude?: string[];
156
+ timeout?: number;
157
+ }
158
+ /**
159
+ * Built-in detection categories
160
+ */
161
+ export declare const DETECTION_CATEGORIES: readonly ["sql-injection", "xss", "ssrf", "path-traversal", "command-injection", "idor", "bola", "auth-bypass", "race-condition", "secrets", "insecure-deserialization", "xxe", "open-redirect", "csrf"];
162
+ export type DetectionCategory = (typeof DETECTION_CATEGORIES)[number];
163
+ /**
164
+ * Default confidence thresholds
165
+ */
166
+ export declare const CONFIDENCE_THRESHOLDS: {
167
+ readonly high: 85;
168
+ readonly medium: 60;
169
+ readonly low: 40;
170
+ };
171
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/scanners/detection/types.ts"],"names":[],"mappings":"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"}