report

package
v0.0.0-...-d3be009 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2025 License: BSD-3-Clause, CC-BY-4.0 Imports: 33 Imported by: 0

Documentation

Overview

Package report contains functionality for parsing and linting YAML reports in reports/.

Index

Constants

View Source
const (
	VersionTypeIntroduced   = "introduced"
	VersionTypeFixed        = "fixed"
	VersionTypeVulnerableAt = "vulnerable_at"
)
View Source
const PendingID = "GO-ID-PENDING"
View Source
const VulndbURL = "https://github.com/golang/vulndb"

Variables

View Source
var (
	// YAMLDir is the name of the directory in the vulndb repo that
	// contains reports.
	YAMLDir = filepath.Join(dataFolder, reportsFolder)

	// ExcludedDir is the name of the directory in the vulndb repo that
	// contains excluded reports.
	ExcludedDir = filepath.Join(dataFolder, excludedFolder)
)
View Source
var (
	// osvDir is the name of the directory in the vulndb repo that
	// contains reports.
	OSVDir = "data/osv"

	// SchemaVersion is used to indicate which version of the OSV schema a
	// particular vulnerability was exported with.
	SchemaVersion = "1.3.1"
)

ExcludedTypes are the set of reasons a report may be excluded from the database. These are described in detail at https://go.googlesource.com/vulndb/+/refs/heads/master/doc/format.md.

Functions

func GoID

func GoID(filename string) string

GoID returns the Go ID from the given filename, assuming the filename is of the form "*/<goID>.<ext>".

func IsYAMLReport

func IsYAMLReport(fname string) bool

func ModulesForEntry

func ModulesForEntry(entry osv.Entry) []string

ModulesForEntry returns the list of modules affected by an OSV entry.

func NewLinter

func NewLinter(prefix string) *linter

NewLinter creates a new linter. If prefix is set, all lints will have the given prefix when Errors is called.

func ParseFilepath

func ParseFilepath(path string) (folder, filename string, issueID int, err error)

func ReadOSV

func ReadOSV(filename string) (entry osv.Entry, err error)

ReadOSV reads an osv.Entry from a file.

func RemoveNewlines

func RemoveNewlines(s string) string

RemoveNewlines removes leading and trailing space characters and replaces inner newlines with spaces.

func UnmarshalFromFile

func UnmarshalFromFile(path string, v any) (err error)

func Vendor

func Vendor(modulePath string) string

Types

type CVEMeta

type CVEMeta struct {
	ID          string `yaml:",omitempty"`
	CWE         string `yaml:",omitempty"`
	Description string `yaml:",omitempty"`
	// Additional references that should be included in the CVE record
	// but not the OSV. This is used to preserve references that have been
	// added to a CVE by the CVE program that the Go team does not want
	// to display via OSV. An example that uses this is GO-2022-0476.
	References []string `yaml:",omitempty"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a client for accessing vulndb reports from a git repository.

func NewClient

func NewClient(repo *git.Repository) (*Client, error)

NewClient returns a Client for accessing the reports in the given repo, which must contain directories "data/reports" and "data/excluded".

func NewDefaultClient

func NewDefaultClient(ctx context.Context) (*Client, error)

NewDefaultClient returns a Client that reads reports from https://github.com/golang/vulndb.

func NewLocalClient

func NewLocalClient(ctx context.Context, path string) (*Client, error)

func NewTestClient

func NewTestClient(filesToReports map[string]*Report) (*Client, error)

NewTestClient returns a Client based on a map from filenames to reports.

Intended for testing.

func (*Client) AliasHasReport

func (c *Client) AliasHasReport(alias string) bool

AliasHasReport returns whether the given alias exists in vulndb.

func (*Client) HasReport

func (c *Client) HasReport(githubID int) (found bool)

HasReport returns whether the Github issue id has a corresponding report in vulndb.

func (*Client) List

func (c *Client) List() []*Report

List returns all reports (regular and excluded), in an indeterminate order.

func (*Client) Report

func (c *Client) Report(filename string) (r *Report, ok bool)

Report returns the report with the given filename in vulndb, or (nil, false) if not found.

func (*Client) ReportsByAlias

func (c *Client) ReportsByAlias(alias string) []*Report

ReportsByAlias returns a list of reports in vulndb with the given alias.

func (*Client) ReportsByModule

func (c *Client) ReportsByModule(module string) []*Report

ReportsByModule returns a list of reports in vulndb with the given module.

func (*Client) XRef

func (c *Client) XRef(r *Report) *Xrefs

XRef returns cross-references for a report.

type Description

type Description string

func (*Description) String

func (d *Description) String() string

type ExcludedType

type ExcludedType string

ExcludedType is the reason a report is excluded from the database.

It must be one of the values in ExcludedTypes.

const (
	ExcludedNotImportable         ExcludedType = "NOT_IMPORTABLE"
	ExcludedNotGoCode             ExcludedType = "NOT_GO_CODE"
	ExcludedNotAVulnerability     ExcludedType = "NOT_A_VULNERABILITY"
	ExcludedEffectivelyPrivate    ExcludedType = "EFFECTIVELY_PRIVATE"
	ExcludedDependentVulnerabilty ExcludedType = "DEPENDENT_VULNERABILITY"
	ExcludedLegacyFalsePositive   ExcludedType = "LEGACY_FALSE_POSITIVE"
	ExcludedWithdrawn             ExcludedType = "WITHDRAWN"
)

func FromLabel

func FromLabel(label string) (ExcludedType, bool)

func ToExcludedType

func ToExcludedType(s string) (ExcludedType, bool)

func (*ExcludedType) IsValid

func (e *ExcludedType) IsValid() bool

func (ExcludedType) ToLabel

func (e ExcludedType) ToLabel() string

type Fetcher

type Fetcher interface {
	Fetch(ctx context.Context, id string) (Source, error)
}

type File

type File struct {
	Filename string
	IssNum   int
	*Report
}

type Module

type Module struct {
	Module   string   `yaml:",omitempty"`
	Versions Versions `yaml:",omitempty"`
	// Versions that are not known to the module proxy, but
	// that may be useful to display to humans.
	NonGoVersions Versions `yaml:"non_go_versions,omitempty"`
	// Version types that exist in OSV, but we don't support.
	// These may be added when automatically creating a report,
	// but must be deleted in order to pass lint checks.
	UnsupportedVersions Versions `yaml:"unsupported_versions,omitempty"`
	// Known-vulnerable version, to use when performing static analysis or
	// other techniques on a vulnerable version of the package.
	//
	// In general, we want to use the most recent vulnerable version of
	// the package. Determining this programmatically is difficult, especially
	// for packages without tagged versions, so we specify it manually here.
	VulnerableAt *Version `yaml:"vulnerable_at,omitempty"`
	// Additional list of module@version to require when performing static analysis.
	// It is rare that we need to specify this.
	VulnerableAtRequires []string   `yaml:"vulnerable_at_requires,omitempty"`
	Packages             []*Package `yaml:",omitempty"`
	// Used to determine vulnerable symbols for a given module. If not populated,
	// the fix links found in the report's References field will be used.
	// Only auto-added if the -update flag is passed to vulnreport.
	FixLinks []string `yaml:"fix_links,omitempty"`
	// Do not lint this module.
	// Only for use in exceptional circumstances, such as when a malicious
	// module has been deleted from the proxy entirely.
	SkipLint bool `yaml:"skip_lint,omitempty"`
}

func (*Module) AllPackages

func (m *Module) AllPackages() map[string]*Package

AllPackages returns all affected packages in a given module.

func (*Module) FixVersions

func (m *Module) FixVersions(pc *proxy.Client)

FixVersions replaces each version with its canonical form (if possible), sorts version ranges, and moves versions to their proper spot.

func (*Module) IsFirstParty

func (m *Module) IsFirstParty() bool

type NewOption

type NewOption func(*cfg)

func WithAliases

func WithAliases(aliases []string) NewOption

func WithCreated

func WithCreated(created time.Time) NewOption

func WithGoID

func WithGoID(id string) NewOption

func WithModulePath

func WithModulePath(path string) NewOption

func WithReviewStatus

func WithReviewStatus(status ReviewStatus) NewOption

func WithUnexcluded

func WithUnexcluded(reason ExcludedType) NewOption

type Note

type Note struct {
	Body string
	Type NoteType
}

A Note is a note about the report. May be typed or untyped (with Type left blank).

func (*Note) MarshalYAML

func (n *Note) MarshalYAML() (any, error)

func (*Note) UnmarshalYAML

func (n *Note) UnmarshalYAML(node *yaml.Node) error

type NoteType

type NoteType string
const (
	NoteTypeNone   NoteType = ""
	NoteTypeLint   NoteType = "LINT"
	NoteTypeFix    NoteType = "FIX"
	NoteTypeCreate NoteType = "CREATE"
)

type Package

type Package struct {
	Package string   `yaml:",omitempty"`
	GOOS    []string `yaml:"goos,omitempty"`
	GOARCH  []string `yaml:"goarch,omitempty"`
	// Symbols originally identified as vulnerable.
	Symbols []string `yaml:",omitempty"`
	// Additional vulnerable symbols, computed from Symbols via static analysis
	// or other technique.
	DerivedSymbols []string `yaml:"derived_symbols,omitempty"`
	// Symbols that may be considered vulnerable by automated tools,
	// but have been determined (by a human) to actually not be vulnerable.
	// For now, this field is respected only by the tool that finds derived
	// symbols, but is not published to OSV or elsewhere (so, for example,
	// govulncheck cannot consume it).
	ExcludedSymbols []string `yaml:"excluded_symbols,omitempty"`
	// Reason the package's symbols are already considered fixed and should not
	// be checked or automatically updated.
	SkipFixSymbols string `yaml:"skip_fix,omitempty"`
}

func (*Package) AllSymbols

func (a *Package) AllSymbols() []string

AllSymbols returns both original and derived symbols.

type Reference

type Reference osv.Reference

A Reference is a link to some external resource.

For ease of typing, References are represented in the YAML as a single-element mapping of type to URL.

func ReferenceFromUrl

func ReferenceFromUrl(u string) *Reference

ReferenceFromUrl creates a new Reference from a url with Type inferred from the contents of the url.

func (*Reference) MarshalYAML

func (r *Reference) MarshalYAML() (any, error)

func (*Reference) UnmarshalYAML

func (r *Reference) UnmarshalYAML(n *yaml.Node) error

type Report

type Report struct {
	ID string `yaml:",omitempty"`

	// Excluded indicates an excluded report.
	Excluded ExcludedType `yaml:",omitempty"`

	Modules []*Module `yaml:",omitempty"`

	// Summary is a short phrase describing the vulnerability.
	Summary Summary `yaml:",omitempty"`

	// Description is the CVE description from an existing CVE. If we are
	// assigning a CVE ID ourselves, use CVEMetadata.Description instead.
	Description Description `yaml:",omitempty"`
	Published   time.Time   `yaml:",omitempty"`
	Withdrawn   *osv.Time   `yaml:",omitempty"`

	// CVE are CVE IDs for existing CVEs.
	// If we are assigning a CVE ID ourselves, use CVEMetadata.ID instead.
	CVEs []string `yaml:",omitempty"`
	// GHSAs are the IDs of GitHub Security Advisories that match
	// the above CVEs.
	GHSAs []string `yaml:",omitempty"`

	// Aliases from other databases that we don't (yet) know about.
	// Not published to OSV.
	UnknownAliases []string `yaml:"unknown_aliases,omitempty"`

	// Related is a list of identifiers (e.g. CVEs or GHSAs)
	// that are related to, but are not direct aliases of, this report.
	Related []string `yaml:",omitempty"`

	Credits    []string     `yaml:",omitempty"`
	References []*Reference `yaml:",omitempty"`

	// CVEMetadata is used to capture CVE information when we want to assign a
	// CVE ourselves. If a CVE already exists for an issue, use the CVE field
	// to fill in the ID string.
	CVEMetadata *CVEMeta `yaml:"cve_metadata,omitempty"`

	// Notes about the report. This field is ignored when creating
	// OSV and CVE records. It can be used to document decisions made when
	// creating the report, outstanding issues, or anything else worth
	// mentioning.
	Notes []*Note `yaml:",omitempty"`

	// Metadata about how this report was generated.
	// Not published to OSV.
	SourceMeta *SourceMeta `yaml:"source,omitempty"`

	ReviewStatus ReviewStatus `yaml:"review_status,omitempty"`
	// Allow this report to be UNREVIEWED regardless of it's modules'
	// priorities.
	UnreviewedOK bool `yaml:"unreviewed_ok,omitempty"`

	// (For unexcluded reports) The reason this report was previously
	// excluded. Not published to OSV.
	Unexcluded ExcludedType `yaml:"unexcluded,omitempty"`
}

Report represents a vulnerability report in the vulndb. Remember to update doc/format.md when this structure changes.

func New

func New(src Source, pc *proxy.Client, opts ...NewOption) *Report

func Read

func Read(filename string) (_ *Report, err error)

Read reads a Report in YAML format from filename.

func ReadStrict

func ReadStrict(fsys fs.FS, filename string) (*Report, error)

func (*Report) AddAliases

func (r *Report) AddAliases(aliases []string) (added int)

AddAliases adds any GHSAs and CVEs in aliases that were not already present to the report.

func (*Report) AddCVE

func (r *Report) AddCVE(cveID, cwe string, isGoCNA bool)

func (*Report) AddNote

func (r *Report) AddNote(t NoteType, format string, v ...any)

func (*Report) Aliases

func (r *Report) Aliases() []string

Aliases returns all aliases (e.g., CVEs, GHSAs) for a report.

func (*Report) AllCVEs

func (r *Report) AllCVEs() []string

AllCVEs returns all CVE IDs for a report.

func (*Report) CVEFilename

func (r *Report) CVEFilename() string

func (*Report) CheckFilename

func (r *Report) CheckFilename(filename string) (err error)

CheckFilename errors if the filename is inconsistent with the report.

func (*Report) CheckPackages

func (r *Report) CheckPackages(ctx context.Context, pkc *pkgsite.Client) (errs error)

CheckPackages returns an error if any of the packages listed in the report do not exist (according to pkgsite).

func (r *Report) CommitLinks() (links []string)

CommitLinks returns all commit fix links in report.References

func (*Report) Encode

func (r *Report) Encode(w io.Writer) error

func (*Report) Fix

func (r *Report) Fix(pc *proxy.Client)

func (*Report) FixModules

func (r *Report) FixModules(pc *proxy.Client) (errs error)

func (*Report) FixReferences

func (r *Report) FixReferences()

FixReferences deletes some unneeded references, and attempts to fix reference types. Modifies r.

Deletes:

  • "package"-type references
  • Go advisory references (these are redundant for us)
  • all advisories except the "best" one (if applicable)

Changes:

  • reference type to "advisory" for GHSA and CVE links.
  • reference type to "fix" for Github pull requests and commit links in one of the affected modules
  • reference type to "report" for Github issues in one of the affected modules

func (*Report) FixText

func (r *Report) FixText()

func (*Report) GoCVE

func (r *Report) GoCVE() string

GoCVE returns the CVE assigned to this report by the Go CNA, or the empty string if not applicable.

func (*Report) IsExcluded

func (r *Report) IsExcluded() bool

func (*Report) IsFirstParty

func (r *Report) IsFirstParty() bool

func (*Report) IsOriginal

func (r *Report) IsOriginal() bool

IsOriginal returns whether the source of this report is definitely the Go security team. (Many older reports do not have this metadata so other heuristics would have to be used).

func (*Report) IsReviewed

func (r *Report) IsReviewed() bool

func (*Report) IsUnreviewed

func (r *Report) IsUnreviewed() bool

func (*Report) Lint

func (r *Report) Lint(pc *proxy.Client) []string

Lint checks the content of a Report and outputs a list of strings representing lint errors. TODO: It might make sense to include warnings or informational things alongside errors, especially during for use during the triage process.

func (*Report) LintAsNotes

func (r *Report) LintAsNotes(pc *proxy.Client) bool

LintAsNotes works like Lint, but modifies r by adding any lints found to the notes section, instead of returning them. Removes any pre-existing lint notes. Returns true if any lints were found.

func (*Report) LintOffline

func (r *Report) LintOffline() []string

LintOffline performs all lint checks that don't require a network connection.

func (*Report) NeedsReview

func (r *Report) NeedsReview() bool

func (*Report) OSVFilename

func (r *Report) OSVFilename() string

func (*Report) ToOSV

func (r *Report) ToOSV(lastModified time.Time) (osv.Entry, error)

ToOSV creates an osv.Entry for a report. lastModified is the time the report should be considered to have been most recently modified.

func (*Report) ToString

func (r *Report) ToString() (string, error)

ToString encodes r to a YAML string.

func (*Report) Write

func (r *Report) Write(filename string) (err error)

Write writes r to filename in YAML format.

func (*Report) YAMLFilename

func (r *Report) YAMLFilename() (string, error)

type ReviewStatus

type ReviewStatus int
const (
	Reviewed ReviewStatus
	Unreviewed
	NeedsReview
)

func ToReviewStatus

func ToReviewStatus(s string) (ReviewStatus, bool)

func (ReviewStatus) IsValid

func (r ReviewStatus) IsValid() bool

func (ReviewStatus) MarshalYAML

func (r ReviewStatus) MarshalYAML() (any, error)

func (ReviewStatus) String

func (r ReviewStatus) String() string

func (ReviewStatus) ToOSV

func (r ReviewStatus) ToOSV() osv.ReviewStatus

func (*ReviewStatus) UnmarshalYAML

func (r *ReviewStatus) UnmarshalYAML(node *yaml.Node) error

type Source

type Source interface {
	// SourceID returns the ID of the source.
	// For example, the GHSA or CVE id.
	SourceID() string
	ToReport(pxc *proxy.Client, modulePath string) *Report
}

Source represents a vulnerability format (e.g., GHSA, CVE) that can be converted to our Report format.

func Original

func Original() Source

func OriginalCVE

func OriginalCVE(cveID string) Source

type SourceMeta

type SourceMeta struct {
	// The ID (GHSA or CVE) of the original source of this report.
	// If created by a human, this is "go-security-team".
	ID string `yaml:",omitempty"`
	// The time the auto-generated report was created (or re-generated
	// from source).
	Created *time.Time `yaml:",omitempty"`
}

type Summary

type Summary string

func (*Summary) String

func (s *Summary) String() string

type Version

type Version struct {
	Version string      `yaml:",omitempty"`
	Type    VersionType `yaml:",omitempty"`
}

func Fixed

func Fixed(v string) *Version

func Introduced

func Introduced(v string) *Version

func VulnerableAt

func VulnerableAt(v string) *Version

func (*Version) IsFixed

func (v *Version) IsFixed() bool

func (*Version) IsIntroduced

func (v *Version) IsIntroduced() bool

func (*Version) MarshalYAML

func (v *Version) MarshalYAML() (any, error)

func (*Version) ToRangeEvent

func (v *Version) ToRangeEvent() (osv.RangeEvent, error)

func (*Version) UnmarshalYAML

func (v *Version) UnmarshalYAML(n *yaml.Node) error

type VersionType

type VersionType string

type Versions

type Versions []*Version

func (Versions) MarshalYAML

func (vs Versions) MarshalYAML() (any, error)

func (Versions) String

func (vs Versions) String() string

func (Versions) ToRangesWithType

func (vs Versions) ToRangesWithType(t osv.RangeType) ([]osv.Range, error)

func (Versions) ToSemverRanges

func (vs Versions) ToSemverRanges() ([]osv.Range, error)

func (*Versions) UnmarshalYAML

func (vs *Versions) UnmarshalYAML(n *yaml.Node) error

type VulnerableAtVersion

type VulnerableAtVersion Version

type Xrefs

type Xrefs struct {
	// map from aliases to files
	Aliases map[string][]*File
	// map from modules to files
	Modules map[string][]*File
}

func (*Xrefs) ToString

func (xs *Xrefs) ToString(aliasTitle, moduleTitle, noneMessage string) string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL