@vulcn/plugin-report 0.2.0 → 0.5.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.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,142 @@
1
1
  import { z } from 'zod';
2
- import { Session, RunResult, Finding, VulcnPlugin } from '@vulcn/engine';
2
+ import { PayloadCategory, Session, RunResult, VulcnPlugin } from '@vulcn/engine';
3
+
4
+ /**
5
+ * Vulcn Report Model
6
+ *
7
+ * The canonical data model from which all output formats (HTML, JSON,
8
+ * YAML, SARIF) are derived. This is the single source of truth for
9
+ * CWE mappings, severity scores, fingerprinting, risk computation,
10
+ * and passive analysis categorisation.
11
+ *
12
+ * RunResult + Session
13
+ * ↓
14
+ * buildReport()
15
+ * ↓
16
+ * VulcnReport (canonical)
17
+ * ↓
18
+ * ┌──────┴──────────┬──────────┬──────────┐
19
+ * HTML JSON YAML SARIF
20
+ *
21
+ * Every output format is a projection of this model.
22
+ */
23
+
24
+ interface CweEntry {
25
+ id: number;
26
+ name: string;
27
+ }
28
+ type Severity = "critical" | "high" | "medium" | "low" | "info";
29
+ interface PassiveCheckDefinition {
30
+ id: string;
31
+ label: string;
32
+ icon: string;
33
+ color: string;
34
+ remedy: string;
35
+ checks: string[];
36
+ }
37
+ interface EnrichedFinding {
38
+ /** Original raw finding fields */
39
+ type: PayloadCategory;
40
+ severity: Severity;
41
+ title: string;
42
+ description: string;
43
+ stepId: string;
44
+ payload: string;
45
+ url: string;
46
+ evidence?: string;
47
+ metadata?: Record<string, unknown>;
48
+ /** Enriched fields — computed by buildReport() */
49
+ ruleId: string;
50
+ cwe: CweEntry;
51
+ securitySeverity: string;
52
+ fingerprint: string;
53
+ /** Detection classification */
54
+ detectionMethod: "active" | "passive";
55
+ /** Passive category (only set when detectionMethod === "passive") */
56
+ passiveCategory?: string;
57
+ }
58
+ interface ReportRule {
59
+ /** e.g. "VULCN-XSS" */
60
+ id: string;
61
+ /** Raw type name e.g. "xss" */
62
+ type: string;
63
+ /** CWE info */
64
+ cwe: CweEntry;
65
+ /** Severity of the first finding with this rule */
66
+ severity: Severity;
67
+ securitySeverity: string;
68
+ /** Description for help text */
69
+ description: string;
70
+ }
71
+ interface PassiveCategorySummary {
72
+ definition: PassiveCheckDefinition;
73
+ /** Findings in this category */
74
+ findings: EnrichedFinding[];
75
+ /** Issue count */
76
+ issueCount: number;
77
+ /** Number of checks that passed */
78
+ passedChecks: number;
79
+ /** Total checks for this category */
80
+ totalChecks: number;
81
+ /** PASS | WARN | FAIL */
82
+ status: "pass" | "warn" | "fail";
83
+ }
84
+ interface PassiveAnalysis {
85
+ totalIssues: number;
86
+ categories: PassiveCategorySummary[];
87
+ }
88
+ interface RiskAssessment {
89
+ score: number;
90
+ percent: number;
91
+ label: "Critical" | "High" | "Medium" | "Low" | "Clear";
92
+ }
93
+ type SeverityCounts = Record<Severity, number>;
94
+ interface VulcnReport {
95
+ /** Report format version */
96
+ reportVersion: "2.0";
97
+ /** Engine version that generated the scan */
98
+ engineVersion: string;
99
+ /** ISO timestamp when this report was generated */
100
+ generatedAt: string;
101
+ /** Session metadata */
102
+ session: {
103
+ name: string;
104
+ driver: string;
105
+ driverConfig: Record<string, unknown>;
106
+ stepsCount: number;
107
+ metadata?: Record<string, unknown>;
108
+ };
109
+ /** Execution statistics */
110
+ stats: {
111
+ stepsExecuted: number;
112
+ payloadsTested: number;
113
+ durationMs: number;
114
+ errors: string[];
115
+ };
116
+ /** Summary / overview data */
117
+ summary: {
118
+ totalFindings: number;
119
+ severityCounts: SeverityCounts;
120
+ risk: RiskAssessment;
121
+ vulnerabilityTypes: string[];
122
+ affectedUrls: string[];
123
+ };
124
+ /** Rule registry — one rule per unique finding type */
125
+ rules: ReportRule[];
126
+ /** All findings — enriched with CWE, fingerprints, classification */
127
+ findings: EnrichedFinding[];
128
+ /** Active findings (subset) */
129
+ activeFindings: EnrichedFinding[];
130
+ /** Passive analysis summary */
131
+ passiveAnalysis: PassiveAnalysis;
132
+ }
133
+ /**
134
+ * Build a VulcnReport from raw scan output.
135
+ *
136
+ * This is the single transformation point. All output formats
137
+ * (HTML, JSON, YAML, SARIF) operate on the returned model.
138
+ */
139
+ declare function buildReport(session: Session, result: RunResult, generatedAt: string, engineVersion: string): VulcnReport;
3
140
 
4
141
  /**
5
142
  * HTML Report Generator for Vulcn
@@ -12,33 +149,25 @@ import { Session, RunResult, Finding, VulcnPlugin } from '@vulcn/engine';
12
149
  * - Responsive design
13
150
  */
14
151
 
15
- interface HtmlReportData {
16
- session: Session;
17
- result: RunResult;
18
- generatedAt: string;
19
- engineVersion: string;
20
- }
21
- declare function generateHtml(data: HtmlReportData): string;
152
+ declare function generateHtml(report: VulcnReport): string;
22
153
 
23
154
  /**
24
155
  * JSON Report Generator for Vulcn
25
156
  *
26
- * Produces a structured, machine-readable JSON report.
157
+ * Projects the canonical VulcnReport into a clean JSON structure
158
+ * suitable for CI/CD pipelines and programmatic consumption.
27
159
  */
28
160
 
161
+ /**
162
+ * The JSON output shape — a clean projection of VulcnReport.
163
+ */
29
164
  interface JsonReport {
30
165
  vulcn: {
31
166
  version: string;
32
167
  reportVersion: string;
33
168
  generatedAt: string;
34
169
  };
35
- session: {
36
- name: string;
37
- driver: string;
38
- driverConfig: Record<string, unknown>;
39
- stepsCount: number;
40
- metadata?: Record<string, unknown>;
41
- };
170
+ session: VulcnReport["session"];
42
171
  execution: {
43
172
  stepsExecuted: number;
44
173
  payloadsTested: number;
@@ -49,34 +178,152 @@ interface JsonReport {
49
178
  summary: {
50
179
  totalFindings: number;
51
180
  riskScore: number;
52
- severityCounts: Record<string, number>;
181
+ riskLabel: string;
182
+ severityCounts: VulcnReport["summary"]["severityCounts"];
53
183
  vulnerabilityTypes: string[];
54
184
  affectedUrls: string[];
55
185
  };
56
- findings: Finding[];
186
+ findings: VulcnReport["findings"];
187
+ passiveAnalysis: {
188
+ totalIssues: number;
189
+ categories: Array<{
190
+ id: string;
191
+ label: string;
192
+ status: string;
193
+ issueCount: number;
194
+ passedChecks: number;
195
+ totalChecks: number;
196
+ remedy: string;
197
+ }>;
198
+ };
199
+ rules: VulcnReport["rules"];
57
200
  }
58
- declare function generateJson(session: Session, result: RunResult, generatedAt: string, engineVersion: string): JsonReport;
201
+ declare function generateJson(report: VulcnReport): JsonReport;
59
202
 
60
203
  /**
61
204
  * YAML Report Generator for Vulcn
62
205
  *
63
- * Produces a human-readable YAML report.
206
+ * Produces a human-readable YAML report from the canonical VulcnReport.
64
207
  */
65
208
 
66
- declare function generateYaml(session: Session, result: RunResult, generatedAt: string, engineVersion: string): string;
209
+ declare function generateYaml(report: VulcnReport): string;
210
+
211
+ /**
212
+ * SARIF Report Generator for Vulcn
213
+ *
214
+ * Projects the canonical VulcnReport into SARIF v2.1.0 (Static Analysis
215
+ * Results Interchange Format) compatible with GitHub Code Scanning,
216
+ * Azure DevOps, and other SARIF-consuming tools.
217
+ *
218
+ * @see https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html
219
+ * @see https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning
220
+ */
221
+
222
+ interface SarifLog {
223
+ $schema: string;
224
+ version: "2.1.0";
225
+ runs: SarifRun[];
226
+ }
227
+ interface SarifRun {
228
+ tool: SarifTool;
229
+ results: SarifResult[];
230
+ invocations: SarifInvocation[];
231
+ artifacts?: SarifArtifact[];
232
+ }
233
+ interface SarifTool {
234
+ driver: SarifToolComponent;
235
+ }
236
+ interface SarifToolComponent {
237
+ name: string;
238
+ version: string;
239
+ informationUri: string;
240
+ semanticVersion: string;
241
+ rules: SarifRule[];
242
+ }
243
+ interface SarifRule {
244
+ id: string;
245
+ name: string;
246
+ shortDescription: {
247
+ text: string;
248
+ };
249
+ fullDescription: {
250
+ text: string;
251
+ };
252
+ helpUri: string;
253
+ help: {
254
+ text: string;
255
+ markdown: string;
256
+ };
257
+ properties: {
258
+ tags: string[];
259
+ precision: "very-high" | "high" | "medium" | "low";
260
+ "security-severity": string;
261
+ };
262
+ defaultConfiguration: {
263
+ level: SarifLevel;
264
+ };
265
+ }
266
+ type SarifLevel = "error" | "warning" | "note" | "none";
267
+ interface SarifResult {
268
+ ruleId: string;
269
+ ruleIndex: number;
270
+ level: SarifLevel;
271
+ message: {
272
+ text: string;
273
+ };
274
+ locations: SarifLocation[];
275
+ fingerprints: Record<string, string>;
276
+ partialFingerprints: Record<string, string>;
277
+ properties: Record<string, unknown>;
278
+ }
279
+ interface SarifLocation {
280
+ physicalLocation: {
281
+ artifactLocation: {
282
+ uri: string;
283
+ uriBaseId?: string;
284
+ };
285
+ region?: {
286
+ startLine: number;
287
+ startColumn?: number;
288
+ };
289
+ };
290
+ logicalLocations?: Array<{
291
+ name: string;
292
+ kind: string;
293
+ }>;
294
+ }
295
+ interface SarifInvocation {
296
+ executionSuccessful: boolean;
297
+ startTimeUtc?: string;
298
+ endTimeUtc?: string;
299
+ properties?: Record<string, unknown>;
300
+ }
301
+ interface SarifArtifact {
302
+ location: {
303
+ uri: string;
304
+ };
305
+ length?: number;
306
+ }
307
+ /**
308
+ * Generate a SARIF v2.1.0 log from a VulcnReport.
309
+ *
310
+ * Usage:
311
+ * const report = buildReport(session, result, generatedAt, "0.5.0");
312
+ * const sarif = generateSarif(report);
313
+ * await writeFile("vulcn-report.sarif", JSON.stringify(sarif, null, 2));
314
+ */
315
+ declare function generateSarif(report: VulcnReport): SarifLog;
67
316
 
68
317
  /**
69
318
  * @vulcn/plugin-report
70
319
  * Report Generation Plugin for Vulcn
71
320
  *
72
- * Generates security reports in HTML, JSON, and YAML formats
73
- * after a run completes. Features:
74
- * - Modern dark-themed HTML report with Vulcn branding
75
- * - Machine-readable JSON for CI/CD integration
76
- * - Human-readable YAML for documentation
321
+ * Generates security reports in HTML, JSON, YAML, and SARIF formats
322
+ * after a run completes. All formats are projections of the canonical
323
+ * VulcnReport model, built once via buildReport().
77
324
  *
78
325
  * Configuration:
79
- * format: "html" | "json" | "yaml" | "all" (default: "html")
326
+ * format: "html" | "json" | "yaml" | "sarif" | "all" (default: "html")
80
327
  * outputDir: directory for reports (default: ".")
81
328
  * filename: base filename (no extension) (default: "vulcn-report")
82
329
  * open: auto-open HTML in browser (default: false)
@@ -91,10 +338,11 @@ declare const configSchema: z.ZodObject<{
91
338
  * - "html": Beautiful dark-themed HTML report
92
339
  * - "json": Machine-readable structured JSON
93
340
  * - "yaml": Human-readable YAML
94
- * - "all": Generate all three formats
341
+ * - "sarif": SARIF v2.1.0 for GitHub Code Scanning
342
+ * - "all": Generate all formats
95
343
  * @default "html"
96
344
  */
97
- format: z.ZodDefault<z.ZodEnum<["html", "json", "yaml", "all"]>>;
345
+ format: z.ZodDefault<z.ZodEnum<["html", "json", "yaml", "sarif", "all"]>>;
98
346
  /**
99
347
  * Output directory for report files
100
348
  * @default "."
@@ -111,12 +359,12 @@ declare const configSchema: z.ZodObject<{
111
359
  */
112
360
  open: z.ZodDefault<z.ZodBoolean>;
113
361
  }, "strip", z.ZodTypeAny, {
114
- format: "html" | "json" | "yaml" | "all";
362
+ format: "html" | "json" | "yaml" | "sarif" | "all";
115
363
  outputDir: string;
116
364
  filename: string;
117
365
  open: boolean;
118
366
  }, {
119
- format?: "html" | "json" | "yaml" | "all" | undefined;
367
+ format?: "html" | "json" | "yaml" | "sarif" | "all" | undefined;
120
368
  outputDir?: string | undefined;
121
369
  filename?: string | undefined;
122
370
  open?: boolean | undefined;
@@ -127,4 +375,4 @@ type ReportConfig = z.infer<typeof configSchema>;
127
375
  */
128
376
  declare const plugin: VulcnPlugin;
129
377
 
130
- export { type HtmlReportData, type JsonReport, type ReportConfig, configSchema, plugin as default, generateHtml, generateJson, generateYaml };
378
+ export { type CweEntry, type EnrichedFinding, type JsonReport, type PassiveAnalysis, type PassiveCategorySummary, type PassiveCheckDefinition, type ReportConfig, type ReportRule, type RiskAssessment, type SarifLog, type SeverityCounts, type VulcnReport, buildReport, configSchema, plugin as default, generateHtml, generateJson, generateSarif, generateYaml };