Skip to content

Commit 745db65

Browse files
author
Maceo Thompson
committed
internal/openvex: add statements to handler
Change-Id: I1b1b7c9dff24fab589d83c38f1dd0dab4f5322d6 Reviewed-on: https://go-review.googlesource.com/c/vuln/+/575859 Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent ad5a6f8 commit 745db65

File tree

3 files changed

+261
-11
lines changed

3 files changed

+261
-11
lines changed

cmd/govulncheck/testdata/common/testfiles/binary-call/binary_vex.ct

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,98 @@ $ govulncheck -format openvex -mode binary ${common_vuln_binary}
77
"author": "Unknown Author",
88
"timestamp": "2024-01-01T00:00:00",
99
"version": 1,
10-
"tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck"
10+
"tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck",
11+
"statements": [
12+
{
13+
"vulnerability": {
14+
"@id": "https://pkg.go.dev/vuln/GO-2020-0015",
15+
"name": "GO-2020-0015",
16+
"description": "Infinite loop when decoding some inputs in golang.org/x/text",
17+
"aliases": [
18+
"CVE-2020-14040",
19+
"GHSA-5rcv-m4m3-hfh7"
20+
]
21+
},
22+
"products": [
23+
{
24+
"@id": "Unknown Product"
25+
}
26+
],
27+
"status": "not_affected",
28+
"justification": "vulnerable_code_not_present",
29+
"impact_statement": "Govulncheck determined that the vulnerable code isn't called"
30+
},
31+
{
32+
"vulnerability": {
33+
"@id": "https://pkg.go.dev/vuln/GO-2021-0054",
34+
"name": "GO-2021-0054",
35+
"description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
36+
"aliases": [
37+
"CVE-2020-36067",
38+
"GHSA-p64j-r5f4-pwwx"
39+
]
40+
},
41+
"products": [
42+
{
43+
"@id": "Unknown Product"
44+
}
45+
],
46+
"status": "affected"
47+
},
48+
{
49+
"vulnerability": {
50+
"@id": "https://pkg.go.dev/vuln/GO-2021-0059",
51+
"name": "GO-2021-0059",
52+
"description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
53+
"aliases": [
54+
"CVE-2020-35380",
55+
"GHSA-w942-gw6m-p62c"
56+
]
57+
},
58+
"products": [
59+
{
60+
"@id": "Unknown Product"
61+
}
62+
],
63+
"status": "not_affected",
64+
"justification": "vulnerable_code_not_present",
65+
"impact_statement": "Govulncheck determined that the vulnerable code isn't called"
66+
},
67+
{
68+
"vulnerability": {
69+
"@id": "https://pkg.go.dev/vuln/GO-2021-0113",
70+
"name": "GO-2021-0113",
71+
"description": "Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.",
72+
"aliases": [
73+
"CVE-2021-38561",
74+
"GHSA-ppp9-7jff-5vj2"
75+
]
76+
},
77+
"products": [
78+
{
79+
"@id": "Unknown Product"
80+
}
81+
],
82+
"status": "affected"
83+
},
84+
{
85+
"vulnerability": {
86+
"@id": "https://pkg.go.dev/vuln/GO-2021-0265",
87+
"name": "GO-2021-0265",
88+
"description": "A maliciously crafted path can cause Get and other query functions to consume excessive amounts of CPU and time.",
89+
"aliases": [
90+
"CVE-2021-42248",
91+
"CVE-2021-42836",
92+
"GHSA-c9gm-7rfj-8w5h",
93+
"GHSA-ppj4-34rq-v8j9"
94+
]
95+
},
96+
"products": [
97+
{
98+
"@id": "Unknown Product"
99+
}
100+
],
101+
"status": "affected"
102+
}
103+
]
11104
}

cmd/govulncheck/testdata/common/testfiles/source-call/source_call_vex.ct

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,98 @@ $ govulncheck -C ${moddir}/vuln -format openvex ./...
77
"author": "Unknown Author",
88
"timestamp": "2024-01-01T00:00:00",
99
"version": 1,
10-
"tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck"
10+
"tooling": "https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck",
11+
"statements": [
12+
{
13+
"vulnerability": {
14+
"@id": "https://pkg.go.dev/vuln/GO-2020-0015",
15+
"name": "GO-2020-0015",
16+
"description": "Infinite loop when decoding some inputs in golang.org/x/text",
17+
"aliases": [
18+
"CVE-2020-14040",
19+
"GHSA-5rcv-m4m3-hfh7"
20+
]
21+
},
22+
"products": [
23+
{
24+
"@id": "Unknown Product"
25+
}
26+
],
27+
"status": "not_affected",
28+
"justification": "vulnerable_code_not_present",
29+
"impact_statement": "Govulncheck determined that the vulnerable code isn't called"
30+
},
31+
{
32+
"vulnerability": {
33+
"@id": "https://pkg.go.dev/vuln/GO-2021-0054",
34+
"name": "GO-2021-0054",
35+
"description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
36+
"aliases": [
37+
"CVE-2020-36067",
38+
"GHSA-p64j-r5f4-pwwx"
39+
]
40+
},
41+
"products": [
42+
{
43+
"@id": "Unknown Product"
44+
}
45+
],
46+
"status": "affected"
47+
},
48+
{
49+
"vulnerability": {
50+
"@id": "https://pkg.go.dev/vuln/GO-2021-0059",
51+
"name": "GO-2021-0059",
52+
"description": "Due to improper bounds checking, maliciously crafted JSON objects can cause an out-of-bounds panic. If parsing user input, this may be used as a denial of service vector.",
53+
"aliases": [
54+
"CVE-2020-35380",
55+
"GHSA-w942-gw6m-p62c"
56+
]
57+
},
58+
"products": [
59+
{
60+
"@id": "Unknown Product"
61+
}
62+
],
63+
"status": "not_affected",
64+
"justification": "vulnerable_code_not_present",
65+
"impact_statement": "Govulncheck determined that the vulnerable code isn't called"
66+
},
67+
{
68+
"vulnerability": {
69+
"@id": "https://pkg.go.dev/vuln/GO-2021-0113",
70+
"name": "GO-2021-0113",
71+
"description": "Due to improper index calculation, an incorrectly formatted language tag can cause Parse to panic via an out of bounds read. If Parse is used to process untrusted user inputs, this may be used as a vector for a denial of service attack.",
72+
"aliases": [
73+
"CVE-2021-38561",
74+
"GHSA-ppp9-7jff-5vj2"
75+
]
76+
},
77+
"products": [
78+
{
79+
"@id": "Unknown Product"
80+
}
81+
],
82+
"status": "affected"
83+
},
84+
{
85+
"vulnerability": {
86+
"@id": "https://pkg.go.dev/vuln/GO-2021-0265",
87+
"name": "GO-2021-0265",
88+
"description": "A maliciously crafted path can cause Get and other query functions to consume excessive amounts of CPU and time.",
89+
"aliases": [
90+
"CVE-2021-42248",
91+
"CVE-2021-42836",
92+
"GHSA-c9gm-7rfj-8w5h",
93+
"GHSA-ppj4-34rq-v8j9"
94+
]
95+
},
96+
"products": [
97+
{
98+
"@id": "Unknown Product"
99+
}
100+
],
101+
"status": "affected"
102+
}
103+
]
11104
}

internal/openvex/handler.go

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package openvex
66

77
import (
88
"encoding/json"
9+
"fmt"
910
"io"
11+
"slices"
1012
"time"
1113

1214
"golang.org/x/vuln/internal/govulncheck"
@@ -75,7 +77,7 @@ func (h *handler) Finding(f *govulncheck.Finding) error {
7577
// Flush is used to print the vex json to w.
7678
// This is needed as vex is not streamed.
7779
func (h *handler) Flush() error {
78-
doc := toVex()
80+
doc := toVex(h)
7981
out, err := json.MarshalIndent(doc, "", " ")
8082
if err != nil {
8183
return err
@@ -84,15 +86,77 @@ func (h *handler) Flush() error {
8486
return err
8587
}
8688

87-
func toVex() Document {
89+
func toVex(h *handler) Document {
8890
doc := Document{
89-
ID: "govulncheckVEX", // TODO: create hash from document for ID
90-
Context: ContextURI,
91-
Author: DefaultAuthor,
92-
Timestamp: time.Now().UTC(),
93-
Version: 1,
94-
Tooling: Tooling,
95-
//TODO: Add statements
91+
ID: "govulncheckVEX", // TODO: create hash from document for ID
92+
Context: ContextURI,
93+
Author: DefaultAuthor,
94+
Timestamp: time.Now().UTC(),
95+
Version: 1,
96+
Tooling: Tooling,
97+
Statements: statements(h),
9698
}
9799
return doc
98100
}
101+
102+
// statements combines all OSVs found by govulncheck and generates the list of
103+
// vex statements with the proper affected level and justification to match the
104+
// openVex specification.
105+
func statements(h *handler) []Statement {
106+
var scanLevel findingLevel
107+
switch h.cfg.ScanLevel {
108+
case govulncheck.ScanLevelModule:
109+
scanLevel = required
110+
case govulncheck.ScanLevelPackage:
111+
scanLevel = imported
112+
case govulncheck.ScanLevelSymbol:
113+
scanLevel = called
114+
}
115+
116+
var statements []Statement
117+
for id, osv := range h.osvs {
118+
description := osv.Summary
119+
if description == "" {
120+
description = osv.Details
121+
}
122+
s := Statement{
123+
Vulnerability: Vulnerability{
124+
ID: fmt.Sprintf("https://pkg.go.dev/vuln/%s", id),
125+
Name: id,
126+
Description: description,
127+
Aliases: osv.Aliases,
128+
},
129+
Products: []Product{
130+
{
131+
ID: DefaultPID,
132+
},
133+
},
134+
}
135+
136+
if h.levels[id] >= scanLevel {
137+
s.Status = StatusAffected
138+
} else {
139+
s.Status = StatusNotAffected
140+
s.ImpactStatement = Impact
141+
s.Justification = JustificationNotPresent
142+
// We only reach this case if running in symbol mode
143+
if h.levels[id] == imported {
144+
s.Justification = JustificationNotExecuted
145+
}
146+
}
147+
statements = append(statements, s)
148+
}
149+
150+
slices.SortFunc(statements, func(a, b Statement) int {
151+
if a.Vulnerability.ID > b.Vulnerability.ID {
152+
return 1
153+
}
154+
if a.Vulnerability.ID < b.Vulnerability.ID {
155+
return -1
156+
}
157+
// this should never happen in practice, since statements are being
158+
// populated from a map with the vulnerability IDs as keys
159+
return 0
160+
})
161+
return statements
162+
}

0 commit comments

Comments
 (0)