Skip to content

Commit

Permalink
Align GoVulncheck Go version with go.mod (#818)
Browse files Browse the repository at this point in the history
GoVulncheck uses local installed GO version to determine vulnerabilities
if the env `GOVERSION` is not defined.
Set the `GOVERSION` value to the one defined in go.mod.

detail: #679

---------

Co-authored-by: Rex P <[email protected]>
  • Loading branch information
hogo6002 and another-rex authored Feb 26, 2024
1 parent 2e1704d commit 63d8b2a
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 45 deletions.
184 changes: 182 additions & 2 deletions internal/sourceanalysis/__snapshots__/integration_test.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

[Test_RunGoVulnCheck - 1]
{
"GO-2021-0053": [
Expand Down Expand Up @@ -69,12 +68,193 @@
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 13,
"line": 16,
"column": 22
}
}
]
}
],
"GO-2023-2382": [
{
"osv": "GO-2023-2382",
"fixed_version": "v1.20.12",
"trace": [
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http/internal"
}
]
},
{
"osv": "GO-2023-2382",
"fixed_version": "v1.20.12",
"trace": [
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http/internal"
}
]
},
{
"osv": "GO-2023-2382",
"fixed_version": "v1.20.12",
"trace": [
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http/internal",
"function": "Read",
"receiver": "*chunkedReader",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 97,
"column": 26
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "readLocked",
"receiver": "*body",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 840,
"column": 21
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "Read",
"receiver": "bodyLocked",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 1039,
"column": 24
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "io",
"function": "copyBuffer",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 429,
"column": 21
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "io",
"function": "Copy",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 388,
"column": 19
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "Close",
"receiver": "*body",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 1003,
"column": 19
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "finishRequest",
"receiver": "*response",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 1675,
"column": 17
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "serve",
"receiver": "*conn",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 2045,
"column": 18
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "Serve",
"receiver": "*Server",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 3285,
"column": 3
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "ListenAndServe",
"receiver": "*Server",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 3184,
"column": 18
}
},
{
"module": "stdlib",
"version": "v1.19.0",
"package": "net/http",
"function": "ListenAndServe",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 3438,
"column": 30
}
},
{
"module": "github.com/ossf-tests/osv-e2e",
"package": "github.com/ossf-tests/osv-e2e",
"function": "main",
"position": {
"filename": "\u003cAny value\u003e",
"offset": -1,
"line": 19,
"column": 28
}
}
]
}
]
}
---
14 changes: 12 additions & 2 deletions internal/sourceanalysis/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,17 @@ func goAnalysis(r reporter.Reporter, pkgs []models.PackageVulns, source models.S
return
}

// Set GOVERSION to the Go version in go.mod.
var goVersion string
for _, pkg := range pkgs {
if pkg.Package.Name == "stdlib" {
goVersion = pkg.Package.Version
break
}
}

vulns, vulnsByID := vulnsFromAllPkgs(pkgs)
res, err := runGovulncheck(filepath.Dir(source.Path), vulns)
res, err := runGovulncheck(filepath.Dir(source.Path), vulns, goVersion)
if err != nil {
// TODO: Better method to identify the type of error and give advice specific to the error
r.Errorf(
Expand Down Expand Up @@ -92,7 +101,7 @@ func fillNotImportedAnalysisInfo(vulnsByID map[string]models.Vulnerability, vuln
}
}

func runGovulncheck(moddir string, vulns []models.Vulnerability) (map[string][]*govulncheck.Finding, error) {
func runGovulncheck(moddir string, vulns []models.Vulnerability, goVersion string) (map[string][]*govulncheck.Finding, error) {
// Create a temporary directory containing all of the vulnerabilities that
// are passed in to check against govulncheck.
//
Expand Down Expand Up @@ -128,6 +137,7 @@ func runGovulncheck(moddir string, vulns []models.Vulnerability) (map[string][]*
cmd := scan.Command(context.Background(), "-db", dbdirURL.String(), "-C", moddir, "-json", "./...")
var b bytes.Buffer
cmd.Stdout = &b
cmd.Env = append(os.Environ(), fmt.Sprintf("GOVERSION=go%s", goVersion))
if err := cmd.Start(); err != nil {
return nil, err
}
Expand Down
72 changes: 72 additions & 0 deletions internal/sourceanalysis/integration/fixtures-go/GO-2023-2382.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"schema_version": "1.3.1",
"id": "GO-2023-2382",
"modified": "2023-12-06T16:22:36Z",
"published": "2023-12-06T16:22:36Z",
"aliases": [
"CVE-2023-39326"
],
"summary": "Denial of service via chunk extensions in net/http",
"details": "A malicious HTTP sender can use chunk extensions to cause a receiver reading from a request or response body to read many more bytes from the network than are in the body.\n\nA malicious HTTP client can further exploit this to cause a server to automatically read a large amount of data (up to about 1GiB) when a handler fails to read the entire body of a request.\n\nChunk extensions are a little-used HTTP feature which permit including additional metadata in a request or response body sent using the chunked encoding. The net/http chunked encoding reader discards this metadata. A sender can exploit this by inserting a large metadata segment with each byte transferred. The chunk reader now produces an error if the ratio of real body to encoded bytes grows too small.",
"affected": [
{
"package": {
"name": "stdlib",
"ecosystem": "Go"
},
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "1.20.12"
},
{
"introduced": "1.21.0-0"
},
{
"fixed": "1.21.5"
}
]
}
],
"ecosystem_specific": {
"imports": [
{
"path": "net/http/internal",
"symbols": [
"chunkedReader.Read",
"chunkedReader.beginChunk",
"readChunkLine"
]
}
]
}
}
],
"references": [
{
"type": "REPORT",
"url": "https://go.dev/issue/64433"
},
{
"type": "FIX",
"url": "https://go.dev/cl/547335"
},
{
"type": "WEB",
"url": "https://groups.google.com/g/golang-dev/c/6ypN5EjibjM/m/KmLVYH_uAgAJ"
}
],
"credits": [
{
"name": "Bartek Nowotarski"
}
],
"database_specific": {
"url": "https://pkg.go.dev/vuln/GO-2023-2382"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package main

import (
"log"
"net/http"

"github.com/gogo/protobuf/plugin/unmarshal"
"github.com/gogo/protobuf/version"
"github.com/ipfs/go-bitfield"
Expand All @@ -11,4 +14,11 @@ func main() {
unmarshal.NewUnmarshal()

bitfield.NewBitfield(14)

// Test stdlib
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal(err)
}

}
7 changes: 6 additions & 1 deletion internal/sourceanalysis/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func Test_RunGoVulnCheck(t *testing.T) {
vulns = append(vulns, newVuln)
}

res, err := runGovulncheck(filepath.Join(fixturesDir, "test-project"), vulns)
res, err := runGovulncheck(filepath.Join(fixturesDir, "test-project"), vulns, "1.19")
if err != nil {
t.Errorf("failed to run RunGoVulnCheck: %v", err)
}
Expand All @@ -54,5 +54,10 @@ func Test_RunGoVulnCheck(t *testing.T) {
res["GO-2023-1558"][2].Trace[0].Position.Offset = -1
res["GO-2023-1558"][2].Trace[1].Position.Offset = -1

for _, traceItem := range res["GO-2023-2382"][2].Trace {
traceItem.Position.Filename = "<Any value>"
traceItem.Position.Offset = -1
}

testutility.NewSnapshot().MatchJSON(t, res)
}

0 comments on commit 63d8b2a

Please sign in to comment.