Documentation
¶
Overview ¶
Package remediate turns a vulnerable package into an instruction a developer can act on.
The gap this closes: a scanner says "lodash 4.17.11 is vulnerable, fixed in 4.17.21". But nothing in the project depends on lodash directly -- some build tool three levels up does. Telling somebody to upgrade a package that does not appear in their manifest is how security findings get closed as "won't fix".
What is actually needed is:
vulnerable lodash@4.17.11 introduced express@4.17.1 -> body-parser@1.19.0 -> lodash action upgrade express to 4.18.2
The direct dependency is the only thing the developer controls, so it is the only thing worth putting in a ticket.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Advice ¶
type Advice struct {
// Direct reports whether the vulnerable package is itself a direct
// dependency, in which case there is nothing to trace.
Direct bool `json:"direct"`
// Paths are the routes by which the vulnerable package is introduced.
// More than one means several direct dependencies must move.
Paths []Path `json:"paths,omitempty"`
// Action is the single sentence to put in front of a developer.
Action string `json:"action"`
// Confident reports whether a graph was actually resolved. Without it the
// advice falls back to naming the vulnerable package, which is honest but
// not necessarily actionable.
Confident bool `json:"confident"`
}
Advice is the remediation verdict for one finding.
type Inventory ¶
type Inventory struct {
// Direct maps "ecosystem\x00name" to the version resolved for a direct
// dependency.
Direct map[string]string
}
Inventory is the package list a scanner observed, used to identify which packages are direct dependencies of this project.
func NewInventory ¶
func NewInventory(findings []finding.Finding, g *scanner.PackageGraph) *Inventory
NewInventory builds an inventory of the project's direct dependencies.
The graph is the better source when a scanner supplied one: findings only cover packages that turned out to be vulnerable, so an inventory built from them alone would miss every direct dependency that happens to be healthy -- which is most of them, and exactly the ones a fix has to move.
type Path ¶
type Path struct {
// Direct is the dependency named in the project's own manifest.
Direct string `json:"direct"`
// DirectVersion is the version currently resolved for it.
DirectVersion string `json:"direct_version"`
// Via lists the intermediate packages, nearest-to-direct first.
Via []string `json:"via,omitempty"`
// Requirement is the version range the parent asked for, which decides
// whether a fix is reachable without a major bump.
Requirement string `json:"requirement,omitempty"`
}
Path is a resolved route from a direct dependency to a vulnerable package.
func LocalPaths ¶
func LocalPaths(g *scanner.PackageGraph, ecosystem, name, version string) []Path
LocalPaths traces routes to a vulnerable package using the dependency graph a scanner already read from the project's lockfiles.
Preferred over the network graph whenever it is available: it is instant, it works offline, and crucially it describes what this project actually resolved rather than what a public registry would resolve today. A lockfile pinned two years ago does not resolve the way deps.dev says it would.
type Resolver ¶
type Resolver struct {
Client *depsdev.Client
// Offline skips every network call.
Offline bool
// Graph is the dependency graph a scanner already read from this
// project's lockfiles. When present it is used in preference to the
// network: it is instant, works offline, and describes what this project
// actually resolved rather than what a registry would resolve today.
Graph *scanner.PackageGraph
}
Resolver computes remediation advice from a resolved dependency graph.
func (*Resolver) Apply ¶
func (r *Resolver) Apply(ctx context.Context, findings []finding.Finding, inv *Inventory) map[string]Advice
Apply computes advice for every finding with a package and writes the result back onto Analysis.MinimalUpgrade and Package.IntroducedBy.
Findings whose graph cannot be resolved keep whatever the scanner said. Degrading to the scanner's answer is the right failure mode: a slightly less useful instruction beats an empty one.