cerberauth/reportx

GitHub: cerberauth/reportx

一个 Go 库,用于将各类 DAST 工具的原始扫描发现转换为标准化的多格式安全报告,并提供去重、CWE 增强和 CVSS 评分能力。

Stars: 0 | Forks: 0

# reportx 一个 Go 库,用于将原始 DAST 工具的发现结果转换为标准化的报告输出。 可将其导入 OWASP ZAP 封装器、Nuclei 后处理器或自定义扫描器中。 ## 安装 ``` go get github.com/cerberauth/reportx ``` ## 快速开始 ``` package main import ( "log" "os" "github.com/cerberauth/reportx" "github.com/cerberauth/reportx/format" ) func main() { findings := []reportx.Finding{ { Title: "SQL Injection", Severity: reportx.SeverityCritical, CWEID: "CWE-89", URL: "https://api.example.com/users", Parameter: "id", Description: "User-controlled input passed to SQL query.", Remediation: "Use parameterized queries.", Status: reportx.StatusActive, }, } report, err := reportx.NewBuilder(). Tool("MyScanner", "1.0.0"). Target("https://api.example.com"). Title("Nightly scan"). Findings(findings). Enrich(). // auto-fill CWEName + OwaspTop10 Deduplicate(). // compute + apply fingerprints Build() if err != nil { log.Fatal(err) } data, err := format.NewSARIFFormatter().Format(report) if err != nil { log.Fatal(err) } os.Stdout.Write(data) } ``` ## 格式化器 | 格式 | MediaType | FileExtension | 最适用场景 | |--------|-----------|---------------|---------------| | JSON | `application/json` | `.json` | REST API、仪表盘 | | JSONL | `application/x-ndjson` | `.jsonl` | 流式 pipeline、`jq` | | SARIF | `application/sarif+json` | `.sarif.json` | GitHub 代码扫描、IDE | | Markdown | `text/markdown` | `.md` | PR 评论、维基 | | HTML | `text/html` | `.html` | 独立报告、电子邮件 | ### JSON ``` data, err := format.NewJSONFormatter().Format(report) // Writes: { "metadata": {...}, "findings": [...] } ``` ### JSONL ``` data, err := format.NewJSONLFormatter().Format(report) // One JSON object per line — pipe to jq or a SIEM ``` ### SARIF ``` data, err := format.NewSARIFFormatter().Format(report) // Valid SARIF 2.1.0 — upload to GitHub Code Scanning ``` ### Markdown ``` data, err := format.NewMarkdownFormatter().Format(report) // Post as a PR comment or embed in a wiki page ``` ### HTML ``` data, err := format.NewHTMLFormatter().Format(report) // Self-contained HTML file — no external CSS or JS // Includes print stylesheet for clean PDF export ``` ### 写入文件 ``` err := report.WriteToFile("report.sarif.json", format.NewSARIFFormatter()) ``` ### 写入任意 io.Writer ``` err := report.WriteTo(os.Stdout, format.NewJSONFormatter()) ``` ## CVSS 评分 `score` 子包根据向量字符串计算 CVSS 基础分数。 ### CVSS 3.1 ``` import "github.com/cerberauth/reportx/score" s, err := score.CalculateV31("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H") // s = 9.8 severity := score.Label(s) // reportx.SeverityCritical ``` ### CVSS 4.0 ``` s, err := score.CalculateV40("CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H") // s = 10.0 ``` ## 去重 `Builder.Deduplicate()` 会为每个发现结果计算稳定的 SHA-256 指纹并丢弃重复项,默认保留按索引排序时的首次出现项。 **指纹输入**(全部归一化为小写): - `CWEID` — 例如 `cwe-89` - `URL` — scheme + host + path,不包含查询字符串或 fragment,无尾随斜杠 - `Parameter` — 去除首尾空格 只要两个发现结果具有相同的 CWE、endpoint 和 parameter,无论其 title、description 或 evidence 如何,均视为重复项。 如果你的扫描器已经进行了去重,或者你故意希望每个 endpoint 有多个发现结果,可以选择**禁用此功能**: ``` report, err := reportx.NewBuilder(). Findings(findings). // no .Deduplicate() call Build() ``` ## CWE 增强 `Builder.Enrich()` 从内嵌的 CWE 数据库中填充 `Finding.CWEName` 和 `Finding.OwaspTop10`(无需网络调用)。它涵盖了 20 种常见的 Web 漏洞,包括 CWE-89、CWE-79、CWE-22、CWE-352、CWE-918 等。 当 `Finding.CWEID` 为空或未知时,增强操作不会执行任何动作——它绝不会因为数据缺失而返回错误。 你也可以直接对发现结果进行增强: ``` import "github.com/cerberauth/reportx/enrich" enriched := enrich.EnrichAll(findings) // returns new slice, original unchanged ``` ## 证据 使用 `evidence` 子包将证据附加到任何发现结果中。内置两种类型: ``` import "github.com/cerberauth/reportx/evidence" // HTTP request/response finding.Evidence = &evidence.HTTPEvidence{ RequestMethod: "POST", RequestURL: "https://api.example.com/login", ResponseStatus: 500, RequestBody: []byte(`{"username":"' OR 1=1--"}`), ResponseBody: []byte("SQLite error: syntax error"), } // Any non-HTTP data finding.Evidence = &evidence.CustomEvidence{ Data: map[string]any{ "payload": `{"__proto__":{"admin":true}}`, "timing": "4.2s", }, } ``` 如果结构化字段不可用,`HTTPEvidence` 也接受原始字符串: ``` finding.Evidence = &evidence.HTTPEvidence{ RawRequest: "GET /users?id=1' HTTP/1.1\r\nHost: api.example.com", RawResponse: "HTTP/1.1 500 Internal Server Error\r\n\r\nSQLite error: syntax error", } ``` 在任何 struct 上实现 `IsEmpty() bool` 方法,即可将其作为自定义证据类型使用。 ## 扩展 reportx 实现 `format.Formatter` 接口即可添加自定义输出格式: ``` package myformat import "github.com/cerberauth/reportx" type CSVFormatter struct{} func (f *CSVFormatter) Format(r *reportx.Report) ([]byte, error) { var buf bytes.Buffer buf.WriteString("id,title,severity,url,cwe\n") for _, finding := range r.Findings { fmt.Fprintf(&buf, "%s,%s,%s,%s,%s\n", finding.ID, finding.Title, finding.Severity, finding.URL, finding.CWEID, ) } return buf.Bytes(), nil } func (f *CSVFormatter) MediaType() string { return "text/csv" } func (f *CSVFormatter) FileExtension() string { return ".csv" } ``` 将其与任何 `Report` 结合使用: ``` data, err := new(myformat.CSVFormatter).Format(report) ``` 或者直接写入文件: ``` err := report.WriteToFile("findings.csv", new(myformat.CSVFormatter)) ``` ## 许可证 参见 [LICENSE](LICENSE)。
标签:DAST, EVTX分析, Go库, SARIF, 安全工具链, 恶意软件分析, 日志审计, 漏洞报告, 聊天机器人