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