Skip to content

Commit c27f855

Browse files
committed
internal/sarif: add sarif types
Updates golang/go#61347 Change-Id: Ia7690a83b3476d4de843c8d90060812f2d9d0432 Reviewed-on: https://go-review.googlesource.com/c/vuln/+/543875 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com> Reviewed-by: Maceo Thompson <maceothompson@google.com>
1 parent 244182b commit c27f855

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

internal/sarif/sarif.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Package sarif defines Static Analysis Results Interchange Format
6+
// (SARIF) types supported by govulncheck.
7+
//
8+
// See https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif
9+
// for more information on the SARIF format.
10+
package sarif
11+
12+
import "golang.org/x/vuln/internal/govulncheck"
13+
14+
// Log is the top-level SARIF object encoded in UTF-8.
15+
type Log struct {
16+
// Version should always be "2.1.0"
17+
Version string `json:"version,omitempty"`
18+
19+
// Schema should always be "https://json.schemastore.org/sarif-2.1.0.json"
20+
Schema string `json:"$schema,omitempty"`
21+
22+
// Runs describes executions of static analysis tools. For govulncheck,
23+
// there will be only one run object.
24+
Runs []Run `json:"runs,omitempty"`
25+
}
26+
27+
// Run summarizes results of a single invocation of a static analysis tool,
28+
// in this case govulncheck.
29+
type Run struct {
30+
Tool Tool `json:"tool,omitempty"`
31+
// Results contain govulncheck findings. There should be exactly one
32+
// Result per a detected OSV.
33+
Results []Result `json:"results,omitempty"`
34+
35+
// URIBaseIDs encodes the SARIF originalUriBaseIds property
36+
URIBaseIDs map[string]ArtifactLocation `json:"originalUriBaseIds,omitempty"`
37+
}
38+
39+
// Tool captures information about govulncheck analysis that was run.
40+
type Tool struct {
41+
Driver Driver `json:"driver,omitempty"`
42+
}
43+
44+
// Driver provides details about the govulncheck binary being executed.
45+
type Driver struct {
46+
// Name should be "govulncheck"
47+
Name string `json:"name,omitempty"`
48+
// Version should be the govulncheck version
49+
Version string `json:"semanticVersion,omitempty"`
50+
// InformationURI should point to the description of govulncheck tool
51+
InformationURI string `json:"informationUri,omitempty"`
52+
// Properties are govulncheck run metadata, such as vuln db, Go version, etc.
53+
Properties govulncheck.Config `json:"properties,omitempty"`
54+
55+
Rules []Rule `json:"rules,omitempty"`
56+
}
57+
58+
// Rule corresponds to the static analysis rule/analyzer that
59+
// produces findings. For govulncheck, rules are OSVs.
60+
type Rule struct {
61+
// ID is OSV.ID
62+
ID string `json:"id,omitempty"`
63+
ShortDescription Description `json:"shortDescription,omitempty"`
64+
FullDescription Description `json:"fullDescription,omitempty"`
65+
Help Description `json:"help,omitempty"`
66+
HelpURI string `json:"helpUri,omitempty"`
67+
// Properties should contain OSV.Aliases (CVEs and GHSAs) as tags.
68+
// Consumers of govulncheck SARIF can use these tags to filter
69+
// results based on, say, CVEs.
70+
Properties RuleTags `json:"properties,omitempty"`
71+
}
72+
73+
// RuleTags defines properties.tags.
74+
type RuleTags struct {
75+
Tags []string `json:"tags,omitempty"`
76+
}
77+
78+
// Description is a text in its raw or markdown form.
79+
type Description struct {
80+
Text string `json:"text,omitempty"`
81+
Markdown string `json:"markdown,omitempty"`
82+
}
83+
84+
// Result is a set of govulncheck findings for an OSV. For call stack
85+
// mode, it will contain call stacks for the OSV. There is exactly
86+
// one Result per detected OSV. Only findings at the lowest possible
87+
// level appear in the Result. For instance, if there are findings
88+
// with call stacks for an OSV, those findings will be in the Result,
89+
// but not the “imports” and “requires” findings for the same OSV.
90+
type Result struct {
91+
// RuleID is the Rule.ID/OSV producing the finding.
92+
RuleID string `json:"ruleId,omitempty"`
93+
// Level is one of "error", "warning", "note", and "none".
94+
Level string `json:"level,omitempty"`
95+
// Message explains the overall findings.
96+
Message Description `json:"message,omitempty"`
97+
// Locations to which the findings are associated.
98+
Locations []Location `json:"locations,omitempty"`
99+
// CodeFlows can encode call stacks produced by govulncheck.
100+
CodeFlows []CodeFlow `json:"codeFlows,omitempty"`
101+
// Stacks can encode call stacks produced by govulncheck.
102+
Stacks []Stack `json:"stacks,omitempty"`
103+
// TODO: support Fixes when integration points to the same
104+
}
105+
106+
// CodeFlow describes a detected offending flow of information in terms of
107+
// code locations. More precisely, it can contain several related information
108+
// flows, keeping them together. In govulncheck, those can be all call stacks
109+
// for, say, a particular symbol or package.
110+
type CodeFlow struct {
111+
// ThreadFlows is effectively a set of related information flows.
112+
ThreadFlows []ThreadFlow `json:"threadFlows,omitempty"`
113+
}
114+
115+
// ThreadFlow encodes an information flow as a sequence of locations.
116+
// For govulncheck, it can encode a call stack.
117+
type ThreadFlow struct {
118+
Locations []ThreadFlowLocation `json:"locations,omitempty"`
119+
}
120+
121+
type ThreadFlowLocation struct {
122+
Module string `json:"module,omitempty"`
123+
// Location also contains a Message field.
124+
Location Location `json:"location,omitempty"`
125+
// Can also contain Stack field that encodes a call stack
126+
// leading to this thread flow location.
127+
}
128+
129+
// Stack is a sequence of frames and can encode a govulncheck call stack.
130+
type Stack struct {
131+
Message Description `json:"message,omitempty"`
132+
Frames []Frame `json:"frames,omitempty"`
133+
}
134+
135+
// Frame is effectively a module location. It can also contain thread and
136+
// parameter info, but those are not needed for govulncheck.
137+
type Frame struct {
138+
Module string `json:"module,omitempty"`
139+
Location Location `json:"location,omitempty"`
140+
}
141+
142+
// Location is currently a physical location annotated with a message.
143+
type Location struct {
144+
PhysicalLocation PhysicalLocation `json:"physicalLocation,omitempty"`
145+
Message Description `json:"message,omitempty"`
146+
}
147+
148+
type PhysicalLocation struct {
149+
ArtifactLocation ArtifactLocation `json:"artifactLocation,omitempty"`
150+
Region Region `json:"region,omitempty"`
151+
}
152+
153+
// ArtifactLocation is a path to an offending file.
154+
type ArtifactLocation struct {
155+
// URI is a path to the artifact. If URIBaseID is empty, then
156+
// URI is absolute and it needs to start with, say, "file://."
157+
URI string `json:"uri,omitempty"`
158+
// URIBaseID is offset for URI. An example is %SRCROOT%, used by
159+
// Github Code Scanning to point to the root of the target repo.
160+
// Its value must be defined in URIBaseIDs of a Run.
161+
URIBaseID string `json:"uriBaseId,omitempty"`
162+
}
163+
164+
// Region is a target region within a file.
165+
type Region struct {
166+
StartLine int `json:"startLine,omitempty"`
167+
StartColumn int `json:"startColumn,omitempty"`
168+
EndLine int `json:"endLine,omitempty"`
169+
EndColumn int `json:"endColumn,omitempty"`
170+
}

0 commit comments

Comments
 (0)