report

package
v0.0.0-...-8a00423 Latest Latest
Warning

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

Go to latest
Published: May 17, 2024 License: BSD-3-Clause, CC-BY-4.0 Imports: 31 Imported by: 0

Documentation

Overview

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

Index

Constants

View Source
const (
	NISTPrefix = "https://nvd.nist.gov/vuln/detail/"
)
View Source
const PendingID = "GO-ID-PENDING"

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"
)
View Source
var ExcludedReasons = []ExcludedReason{
	"NOT_IMPORTABLE",
	"NOT_GO_CODE",
	"NOT_A_VULNERABILITY",
	"EFFECTIVELY_PRIVATE",
	"DEPENDENT_VULNERABILITY",
	"LEGACY_FALSE_POSITIVE",
}

ExcludedReasons 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 AffectedRanges

func AffectedRanges(versions []VersionRange) []osv.Range

func GoAdvisory

func GoAdvisory(id string) string

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 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 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) XRef

func (c *Client) XRef(r *Report) (matches map[string][]string)

XRef returns cross-references for a report. The output, matches, is a map from filenames to aliases (CVE & GHSA IDs) and modules (excluding std and cmd).

type Description

type Description string

func (*Description) String

func (d *Description) String() string

type ExcludedReason

type ExcludedReason string

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

It must be one of the values in ExcludedReasons.

func FromLabel

func FromLabel(label string) (ExcludedReason, bool)

func (ExcludedReason) ToLabel

func (er ExcludedReason) ToLabel() string

type Fetcher

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

type Module

type Module struct {
	Module   string         `yaml:",omitempty"`
	Versions []VersionRange `yaml:",omitempty"`
	// Versions that are not known to the module proxy, but
	// that may be useful to display to humans.
	NonGoVersions []VersionRange `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 []UnsupportedVersion `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 string `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"`
}

func (*Module) AllPackages

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

AllPkgs 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 collects version ranges into a compact form.

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

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 is already considered fixed and should not be automatically updated.
	SkipFix 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 ExcludedReason `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   *time.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"`
}

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(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 (r *Report) CommitLinks() (links []string)

CommitLinks returns all commit fix links in report.References

func (*Report) Fix

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

func (*Report) FixModules

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

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) 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) OSVFilename

func (r *Report) OSVFilename() string

func (*Report) ToOSV

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

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 Source

type Source interface {
	// SourceID returns the ID of the source.
	// For example, the GHSA or CVE id.
	SourceID() string
	ToReport(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

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 original auto-generated report was created.
	Created *time.Time `yaml:",omitempty"`
}

type Summary

type Summary string

func (*Summary) String

func (s *Summary) String() string

type UnsupportedVersion

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

type VersionRange

type VersionRange struct {
	Introduced string `yaml:"introduced,omitempty"`
	Fixed      string `yaml:"fixed,omitempty"`
}

Jump to

Keyboard shortcuts

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