Skip to content

Commit 6b0fd56

Browse files
committed
internal/sarif,cmd/govulncheck: publicize sarif
Also, add and improve documentation. Fixes golang/go#61347 Change-Id: Ia631615b40b9d23be6efa615b573be6c465fa36b Reviewed-on: https://go-review.googlesource.com/c/vuln/+/580955 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com> Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
1 parent 7b455ee commit 6b0fd56

File tree

4 files changed

+73
-36
lines changed

4 files changed

+73
-36
lines changed

cmd/govulncheck/doc.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ only those that could affect the application.
99
1010
By default, govulncheck makes requests to the Go vulnerability database at
1111
https://vuln.go.dev. Requests to the vulnerability database contain only module
12-
paths, not code or other properties of your program. See
13-
https://vuln.go.dev/privacy.html for more. Use the -db flag to specify a
14-
different database, which must implement the specification at
15-
https://go.dev/security/vuln/database.
12+
paths with vulnerabilities already known to the database, not code or other
13+
properties of your program. See https://vuln.go.dev/privacy.html for more.
14+
Use the -db flag to specify a different database, which must implement the
15+
specification at https://go.dev/security/vuln/database.
1616
1717
Govulncheck looks for vulnerabilities in Go programs using a specific build
1818
configuration. For analyzing source code, that configuration is the Go version
@@ -59,12 +59,21 @@ information needed to analyze the binary. This will produce a blob, typically mu
5959
smaller than the binary, that can also be passed to govulncheck as an argument with
6060
'-mode binary'. The users should not rely on the contents or representation of the blob.
6161
62-
Govulncheck exits successfully (exit code 0) if there are no vulnerabilities,
63-
and exits unsuccessfully if there are. It also exits successfully if the -json flag
64-
(or '-format json') is provided, regardless of the number of detected vulnerabilities.
62+
# Integrations
6563
6664
Govulncheck supports streaming JSON. For more details, please see [golang.org/x/vuln/internal/govulncheck].
6765
66+
Govulncheck also supports Static Analysis Results Interchange Format (SARIF) output
67+
format, following the specification at https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif.
68+
For more details, please see [golang.org/x/vuln/internal/sarif].
69+
70+
# Exit codes
71+
72+
Govulncheck exits successfully (exit code 0) if there are no vulnerabilities,
73+
and exits unsuccessfully if there are. It also exits successfully if the
74+
'format -json' ('-json') or '-format sarif' is provided, regardless of the number
75+
of detected vulnerabilities.
76+
6877
# Limitations
6978
7079
Govulncheck has these limitations:

cmd/govulncheck/testdata/common/testfiles/usage/usage.ct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Usage:
1414
vulnerability database url (default "https://vuln.go.dev")
1515
-format value
1616
specify format output
17-
The supported values are 'text' and 'json' (default 'text')
17+
The supported values are 'text', 'json', and 'sarif' (default 'text')
1818
-json
1919
output JSON (Go compatible legacy flag, see format flag)
2020
-mode value

internal/sarif/sarif.go

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,41 @@
88
// The implementation covers the subset of the specification available
99
// at https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif.
1010
//
11-
// If govulncheck is used in source mode, the locations will include a
12-
// physical location implemented as a path relative to either the source
13-
// module (%SRCROOT%), Go root (%GOROOT%), or Go module cache (%GOMODCACHE%)
14-
// URI base id.
11+
// The sarif encoding models govulncheck findings as Results. Each
12+
// Result encodes findings for a unique OSV entry at the most precise
13+
// detected level only. CodeFlows summarize call stacks, similar to govulncheck
14+
// textual output, while Stacks contain call stack information verbatim.
15+
//
16+
// The result Levels are defined by the govulncheck.ScanLevel and the most
17+
// precise level at which the finding was detected. Result error is produced
18+
// when the finding level matches the user desired level of scan precision;
19+
// all other finding levels are then classified as progressively weaker.
20+
// For instance, if the user specified symbol scan level and govulncheck
21+
// detected a use of a vulnerable symbol, then the Result will have error
22+
// Level. If the symbol was not used but its package was imported, then the
23+
// Result Level is warning, and so on.
24+
//
25+
// Each Result is attached to the first line of the go.mod file. Other
26+
// ArtifactLocations are paths relative to their enclosing modules.
27+
// Similar to JSON output format, this makes govulncheck sarif locations
28+
// portable.
29+
//
30+
// The relative paths in PhysicalLocations also come with a URIBaseID offset.
31+
// Paths for the source module analyzed, the Go standard library, and third-party
32+
// dependencies are relative to %SRCROOT%, %GOROOT%, and %GOMODCACHE% offsets,
33+
// resp. We note that the URIBaseID offsets are not explicitly defined in
34+
// the sarif output. It is the clients responsibility to set them to resolve
35+
// paths at their local machines.
36+
//
37+
// All paths use "/" delimiter for portability.
38+
//
39+
// Properties field of a Tool.Driver is a govulncheck.Config used for the
40+
// invocation of govulncheck producing the Results. Properties field of
41+
// a Rule contains information on CVE and GHSA aliases for the corresponding
42+
// rule OSV. Clients can use this information to, say, supress and filter
43+
// vulnerabilities.
44+
//
45+
// Please see the definition of types below for more information.
1546
package sarif
1647

1748
import "golang.org/x/vuln/internal/govulncheck"
@@ -34,7 +65,7 @@ type Log struct {
3465
type Run struct {
3566
Tool Tool `json:"tool,omitempty"`
3667
// Results contain govulncheck findings. There should be exactly one
37-
// Result per a detected OSV.
68+
// Result per a detected use of an OSV.
3869
Results []Result `json:"results,omitempty"`
3970
}
4071

@@ -45,11 +76,11 @@ type Tool struct {
4576

4677
// Driver provides details about the govulncheck binary being executed.
4778
type Driver struct {
48-
// Name should be "govulncheck"
79+
// Name is "govulncheck"
4980
Name string `json:"name,omitempty"`
50-
// Version should be the govulncheck version
81+
// Version is the govulncheck version
5182
Version string `json:"semanticVersion,omitempty"`
52-
// InformationURI should point to the description of govulncheck tool
83+
// InformationURI points to the description of govulncheck tool
5384
InformationURI string `json:"informationUri,omitempty"`
5485
// Properties are govulncheck run metadata, such as vuln db, Go version, etc.
5586
Properties govulncheck.Config `json:"properties,omitempty"`
@@ -66,9 +97,9 @@ type Rule struct {
6697
FullDescription Description `json:"fullDescription,omitempty"`
6798
Help Description `json:"help,omitempty"`
6899
HelpURI string `json:"helpUri,omitempty"`
69-
// Properties should contain OSV.Aliases (CVEs and GHSAs) as tags.
100+
// Properties contain OSV.Aliases (CVEs and GHSAs) as tags.
70101
// Consumers of govulncheck SARIF can use these tags to filter
71-
// results based on, say, CVEs.
102+
// results.
72103
Properties RuleTags `json:"properties,omitempty"`
73104
}
74105

@@ -85,27 +116,28 @@ type Description struct {
85116

86117
// Result is a set of govulncheck findings for an OSV. For call stack
87118
// mode, it will contain call stacks for the OSV. There is exactly
88-
// one Result per detected OSV. Only findings at the lowest possible
89-
// level appear in the Result. For instance, if there are findings
90-
// with call stacks for an OSV, those findings will be in the Result,
91-
// but not the “imports” and “requires” findings for the same OSV.
119+
// one Result per detected OSV. Only findings at the most precise
120+
// detected level appear in the Result. For instance, if there are
121+
// symbol findings for an OSV, those findings will be in the Result,
122+
// but not the package and module level findings for the same OSV.
92123
type Result struct {
93124
// RuleID is the Rule.ID/OSV producing the finding.
94125
RuleID string `json:"ruleId,omitempty"`
95-
// Level is one of "error", "warning", "note", and "none".
126+
// Level is one of "error", "warning", and "note".
96127
Level string `json:"level,omitempty"`
97128
// Message explains the overall findings.
98129
Message Description `json:"message,omitempty"`
99-
// Locations to which the findings are associated.
130+
// Locations to which the findings are associated. Always
131+
// a single location pointing to the first line of the go.mod
132+
// file. The path to the file is "go.mod".
100133
Locations []Location `json:"locations,omitempty"`
101-
// CodeFlows can encode call stacks produced by govulncheck.
134+
// CodeFlows summarize call stacks produced by govulncheck.
102135
CodeFlows []CodeFlow `json:"codeFlows,omitempty"`
103-
// Stacks can encode call stacks produced by govulncheck.
136+
// Stacks encode call stacks produced by govulncheck.
104137
Stacks []Stack `json:"stacks,omitempty"`
105-
// TODO: support Fixes when integration points to the same
106138
}
107139

108-
// CodeFlow describes a detected offending flow of information in terms of
140+
// CodeFlow summarizes a detected offending flow of information in terms of
109141
// code locations. More precisely, it can contain several related information
110142
// flows, keeping them together. In govulncheck, those can be all call stacks
111143
// for, say, a particular symbol or package.
@@ -128,8 +160,6 @@ type ThreadFlowLocation struct {
128160
Module string `json:"module,omitempty"`
129161
// Location also contains a Message field.
130162
Location Location `json:"location,omitempty"`
131-
// Can also contain Stack field that encodes a call stack
132-
// leading to this thread flow location.
133163
}
134164

135165
// Stack is a sequence of frames and can encode a govulncheck call stack.
@@ -167,12 +197,10 @@ const (
167197

168198
// ArtifactLocation is a path to an offending file.
169199
type ArtifactLocation struct {
170-
// URI is a path to the artifact. If URIBaseID is empty, then
171-
// URI is absolute and it needs to start with, say, "file://."
200+
// URI is a path relative to URIBaseID.
172201
URI string `json:"uri,omitempty"`
173-
// URIBaseID is offset for URI. An example is %SRCROOT%, used by
174-
// Github Code Scanning to point to the root of the target repo.
175-
// Its value must be defined in URIBaseIDs of a Run.
202+
// URIBaseID is offset for URI, one of %SRCROOT%, %GOROOT%,
203+
// and %GOMODCACHE%.
176204
URIBaseID string `json:"uriBaseId,omitempty"`
177205
}
178206

internal/scan/flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func parseFlags(cfg *config, stderr io.Writer, args []string) error {
4242
flags.Var(&modeFlag, "mode", "supports 'source', 'binary', and 'extract' (default 'source')")
4343
flags.Var(&cfg.tags, "tags", "comma-separated `list` of build tags")
4444
flags.Var(&cfg.show, "show", "enable display of additional information specified by the comma separated `list`\nThe supported values are 'traces','color', 'version', and 'verbose'")
45-
flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text' and 'json' (default 'text')")
45+
flags.Var(&cfg.format, "format", "specify format output\nThe supported values are 'text', 'json', and 'sarif' (default 'text')")
4646
flags.BoolVar(&version, "version", false, "print the version information")
4747
flags.Var(&scanFlag, "scan", "set the scanning level desired, one of 'module', 'package', or 'symbol' (default 'symbol')")
4848

0 commit comments

Comments
 (0)