From 73190ac6a76b27aa487c9569ad40b02a5f687700 Mon Sep 17 00:00:00 2001 From: Tatiana Bradley Date: Fri, 23 Aug 2024 12:43:09 -0400 Subject: [PATCH] internal/report: add new excluded reason WITHDRAWN Add new excluded reason, WITHDRAWN, which indicates that a report was withdrawn before we got a chance to publish it in vulndb. This allows us to keep better track of withdrawn reports (as opposed to completely omitting them from our records). Change-Id: I7209edc88e903787b0c79556177af8f34fed8a4e Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/607818 LUCI-TryBot-Result: Go LUCI Auto-Submit: Tatiana Bradley Reviewed-by: Damien Neil --- cmd/vulnreport/creator.go | 5 +++-- cmd/vulnreport/unexclude.go | 6 +++++- doc/format.md | 3 +++ internal/report/lint.go | 2 +- internal/report/report.go | 2 ++ .../lint/TestLintOffline/missing_fields_excluded.txtar | 6 +++--- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cmd/vulnreport/creator.go b/cmd/vulnreport/creator.go index f9f50120..29d0eb3e 100644 --- a/cmd/vulnreport/creator.go +++ b/cmd/vulnreport/creator.go @@ -96,8 +96,9 @@ func skip(iss *issues.Issue, x *xrefer) string { } func (c *creator) newReportFromIssue(ctx context.Context, iss *issues.Issue) error { + id := iss.NewGoID() r, err := c.reportFromMeta(ctx, &reportMeta{ - id: iss.NewGoID(), + id: id, excluded: excludedReason(iss), modulePath: modulePath(iss), aliases: aliases(iss), @@ -108,7 +109,7 @@ func (c *creator) newReportFromIssue(ctx context.Context, iss *issues.Issue) err return err } if r.Withdrawn != nil { - return fmt.Errorf("new report should not be created for withdrawn vulnerability; close issue #%d as excluded:OUT_OF_SCOPE instead", iss.Number) + return fmt.Errorf("new regular report should not be created for withdrawn vulnerability; %s", withdrawnGuidance(id, iss.Number)) } return c.write(ctx, r) } diff --git a/cmd/vulnreport/unexclude.go b/cmd/vulnreport/unexclude.go index 42d286ff..2d9b856b 100644 --- a/cmd/vulnreport/unexclude.go +++ b/cmd/vulnreport/unexclude.go @@ -55,6 +55,10 @@ func (u *unexclude) skip(input any) string { return "" } +func withdrawnGuidance(id string, issNum int) string { + return fmt.Sprintf("classify report %s as %s and mark issue #%d as %s", id, report.ExcludedWithdrawn, issNum, report.ExcludedWithdrawn.ToLabel()) +} + // unexclude converts an excluded report into a regular report. func (u *unexclude) run(ctx context.Context, input any) (err error) { oldR := input.(*yamlReport) @@ -75,7 +79,7 @@ func (u *unexclude) run(ctx context.Context, input any) (err error) { } if r.Withdrawn != nil { _, _, issNum, _ := report.ParseFilepath(oldR.Filename) - return fmt.Errorf("unexcluded report should not be created for withdrawn vulnerability; delete excluded report %s and mark issue #%d as excluded:OUT_OF_SCOPE instead", oldR.Filename, issNum) + return fmt.Errorf("unexcluded report should not be created for withdrawn vulnerability; %s", withdrawnGuidance(oldR.Filename, issNum)) } r.Unexcluded = oldR.Excluded if err := u.write(ctx, r); err != nil { diff --git a/doc/format.md b/doc/format.md index 40676a0a..b9003ed2 100644 --- a/doc/format.md +++ b/doc/format.md @@ -468,6 +468,9 @@ Valid values are: vulnerability entirely superseded by the report for A. * `NOT_A_VULNERABILITY`: While a CVE or GHSA has been assigned, there is no known vulnerability associated with it. +* `WITHDRAWN`: The source report for this vulnerability was withdrawn + before a report was published in vulndb. (If a source report is withdrawn + after a report is published, we withdraw the report too). * `LEGACY_FALSE_POSITIVE`: This is the label used for excluded reports that were marked as false positive in the initial triage process (in 2020), before we stored excluded reports in the repo. This label must not be used diff --git a/internal/report/lint.go b/internal/report/lint.go index 72f58a39..924e081a 100644 --- a/internal/report/lint.go +++ b/internal/report/lint.go @@ -530,7 +530,7 @@ func (r *Report) lint(pc *proxy.Client) []string { r.CVEMetadata.lint(l.Group("cve_metadata"), r) if r.IsExcluded() && len(r.Aliases()) == 0 { - l.Group("cves,ghsas").Error() + l.Group("cves,ghsas").Error(missing) } r.lintCVEs(l) diff --git a/internal/report/report.go b/internal/report/report.go index c79739d0..65d1c47e 100644 --- a/internal/report/report.go +++ b/internal/report/report.go @@ -210,6 +210,7 @@ const ( ExcludedEffectivelyPrivate ExcludedType = "EFFECTIVELY_PRIVATE" ExcludedDependentVulnerabilty ExcludedType = "DEPENDENT_VULNERABILITY" ExcludedLegacyFalsePositive ExcludedType = "LEGACY_FALSE_POSITIVE" + ExcludedWithdrawn ExcludedType = "WITHDRAWN" ) // ExcludedTypes are the set of reasons a report may be excluded from the database. @@ -222,6 +223,7 @@ var ExcludedTypes = []ExcludedType{ ExcludedEffectivelyPrivate, ExcludedDependentVulnerabilty, ExcludedLegacyFalsePositive, + ExcludedWithdrawn, } func (e *ExcludedType) IsValid() bool { diff --git a/internal/report/testdata/lint/TestLintOffline/missing_fields_excluded.txtar b/internal/report/testdata/lint/TestLintOffline/missing_fields_excluded.txtar index 74bac3e1..a12c4cbf 100644 --- a/internal/report/testdata/lint/TestLintOffline/missing_fields_excluded.txtar +++ b/internal/report/testdata/lint/TestLintOffline/missing_fields_excluded.txtar @@ -1,4 +1,4 @@ -Copyright 2023 The Go Authors. All rights reserved. +Copyright 2024 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. @@ -10,6 +10,6 @@ id: GO-0000-0000 excluded: not a real reason -- golden -- -excluded: excluded reason ("not a real reason") is not a valid excluded reason (accepted: [NOT_IMPORTABLE NOT_GO_CODE NOT_A_VULNERABILITY EFFECTIVELY_PRIVATE DEPENDENT_VULNERABILITY LEGACY_FALSE_POSITIVE]) +excluded: excluded reason ("not a real reason") is not a valid excluded reason (accepted: [NOT_IMPORTABLE NOT_GO_CODE NOT_A_VULNERABILITY EFFECTIVELY_PRIVATE DEPENDENT_VULNERABILITY LEGACY_FALSE_POSITIVE WITHDRAWN]) modules: missing -cves,ghsas: +cves,ghsas: missing