зеркало из https://github.com/golang/vulndb.git
all: update for OSV schema changes
The OSV affected.package.name field is now the module path, not the package import path. The affected.package.ecosystem_speficic.imports field now contains a list of Go packages and symbols within those packages. Restructure the report YAML to match the OSV structure: A report contains a list of modules, a module contains a list of packages, a package contains a list of symbols. Move GOOS/GOARCH to the package, rather than being report-global. This change updates the canonical YAML format and changes the OSV generation to the new form, but does not reformat data/reports. The report loader rewrites the old report YAML into the new style. Followup CLs will convert the reports and remove the rewriter. Change-Id: I71af994846721fdd43a8ee5c41574387ff781332 Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/424895 Reviewed-by: Julie Qiu <julieqiu@google.com> Run-TryBot: Damien Neil <dneil@google.com>
This commit is contained in:
Родитель
425ceb2f2b
Коммит
703236d8e9
|
@ -35,10 +35,12 @@ func TestExportedFunctions(t *testing.T) {
|
|||
defer e.Cleanup()
|
||||
|
||||
rc := newReportClient(&report.Report{
|
||||
Packages: []report.Package{{
|
||||
Module: "example.com/m",
|
||||
Package: "example.com/m/p",
|
||||
Symbols: []string{"vuln"},
|
||||
Modules: []*report.Module{{
|
||||
Module: "example.com/m",
|
||||
Packages: []*report.Package{{
|
||||
Package: "example.com/m/p",
|
||||
Symbols: []string{"vuln"},
|
||||
}},
|
||||
}},
|
||||
})
|
||||
pkgs, err := loadPackage(e.Config, path.Join(e.Temp(), "m/p"))
|
||||
|
|
|
@ -239,28 +239,31 @@ func addTODOs(r *report.Report) {
|
|||
if r.Excluded != "" {
|
||||
return
|
||||
}
|
||||
if len(r.Packages) == 0 {
|
||||
r.Packages = append(r.Packages, report.Package{})
|
||||
if len(r.Modules) == 0 {
|
||||
r.Modules = append(r.Modules, &report.Module{
|
||||
Packages: []*report.Package{{}},
|
||||
})
|
||||
}
|
||||
for i := range r.Packages {
|
||||
p := &r.Packages[i]
|
||||
if p.Module == "" && !stdlib.Contains(p.Module) {
|
||||
p.Module = todo
|
||||
for _, m := range r.Modules {
|
||||
if m.Module == "" {
|
||||
m.Module = todo
|
||||
}
|
||||
if p.Package == "" {
|
||||
p.Package = todo
|
||||
}
|
||||
if len(p.Versions) == 0 {
|
||||
p.Versions = []report.VersionRange{{
|
||||
if len(m.Versions) == 0 {
|
||||
m.Versions = []report.VersionRange{{
|
||||
Introduced: todo,
|
||||
Fixed: todo,
|
||||
}}
|
||||
}
|
||||
if p.VulnerableAt == "" {
|
||||
p.VulnerableAt = todo
|
||||
if m.VulnerableAt == "" {
|
||||
m.VulnerableAt = todo
|
||||
}
|
||||
if len(p.Symbols) == 0 {
|
||||
p.Symbols = []string{todo}
|
||||
for _, p := range m.Packages {
|
||||
if p.Package == "" {
|
||||
p.Package = todo
|
||||
}
|
||||
if len(p.Symbols) == 0 {
|
||||
p.Symbols = []string{todo}
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.Description == "" {
|
||||
|
@ -319,41 +322,37 @@ func fix(ctx context.Context, filename string, accessToken string) (err error) {
|
|||
}
|
||||
|
||||
func checkReportSymbols(r *report.Report) (bool, error) {
|
||||
if len(r.OS) > 0 || len(r.Arch) > 0 {
|
||||
return false, errors.New("specific GOOS/GOARCH not yet implemented")
|
||||
}
|
||||
rc := newReportClient(r)
|
||||
added := false
|
||||
for i, p := range r.Packages {
|
||||
if len(p.Symbols) == 0 {
|
||||
continue
|
||||
}
|
||||
syms, err := findExportedSymbols(p, rc)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !slices.Equal(syms, r.Packages[i].DerivedSymbols) {
|
||||
added = true
|
||||
r.Packages[i].DerivedSymbols = syms
|
||||
for _, m := range r.Modules {
|
||||
for _, p := range m.Packages {
|
||||
if len(p.Symbols) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(p.GOOS) > 0 || len(p.GOARCH) > 0 {
|
||||
return false, errors.New("specific GOOS/GOARCH not yet implemented")
|
||||
}
|
||||
syms, err := findExportedSymbols(m, p, rc)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !slices.Equal(syms, p.DerivedSymbols) {
|
||||
added = true
|
||||
p.DerivedSymbols = syms
|
||||
}
|
||||
}
|
||||
}
|
||||
return added, nil
|
||||
}
|
||||
|
||||
func findExportedSymbols(p report.Package, c *reportClient) (_ []string, err error) {
|
||||
defer derrors.Wrap(&err, "addExportedSymbols(%q, %q)", p.Module, p.Package)
|
||||
func findExportedSymbols(m *report.Module, p *report.Package, c *reportClient) (_ []string, err error) {
|
||||
defer derrors.Wrap(&err, "addExportedSymbols(%q, %q)", m.Module, p.Package)
|
||||
|
||||
if p.VulnerableAt == "" {
|
||||
if m.VulnerableAt == "" {
|
||||
fmt.Fprintf(os.Stderr, "%v: no vulnerable_at version, skipping symbol checks.\n", p.Package)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
module := p.Module
|
||||
pkgPath := p.Package
|
||||
if pkgPath == "" {
|
||||
pkgPath = module
|
||||
}
|
||||
|
||||
cleanup, err := changeToTempDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -363,8 +362,8 @@ func findExportedSymbols(p report.Package, c *reportClient) (_ []string, err err
|
|||
return nil, err
|
||||
}
|
||||
std := false
|
||||
if !stdlib.Contains(p.Module) {
|
||||
pkgPathAndVersion := pkgPath + "@" + p.VulnerableAt.V()
|
||||
if m.Module != stdlib.ModulePath {
|
||||
pkgPathAndVersion := p.Package + "@" + m.VulnerableAt.V()
|
||||
if err := run("go", "get", pkgPathAndVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -373,15 +372,15 @@ func findExportedSymbols(p report.Package, c *reportClient) (_ []string, err err
|
|||
gover := runtime.Version()
|
||||
ver := semverForGoVersion(gover)
|
||||
if ver == "" || !affected(c.entry, ver.V()) {
|
||||
fmt.Fprintf(os.Stderr, "%v: Go version %q is not in a vulnerable range, skipping symbol checks.\n", pkgPath, gover)
|
||||
fmt.Fprintf(os.Stderr, "%v: Go version %q is not in a vulnerable range, skipping symbol checks.\n", p.Package, gover)
|
||||
return nil, nil
|
||||
}
|
||||
if ver != p.VulnerableAt {
|
||||
fmt.Fprintf(os.Stderr, "%v: WARNING: Go version %q does not match vulnerable_at version %q.\n", pkgPath, ver, p.VulnerableAt)
|
||||
if ver != m.VulnerableAt {
|
||||
fmt.Fprintf(os.Stderr, "%v: WARNING: Go version %q does not match vulnerable_at version %q.\n", p.Package, ver, m.VulnerableAt)
|
||||
}
|
||||
}
|
||||
|
||||
pkgs, err := loadPackage(&packages.Config{}, pkgPath)
|
||||
pkgs, err := loadPackage(&packages.Config{}, p.Package)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -389,16 +388,16 @@ func findExportedSymbols(p report.Package, c *reportClient) (_ []string, err err
|
|||
return nil, errors.New("no packages found")
|
||||
}
|
||||
// First package should match package path and module.
|
||||
if pkgs[0].PkgPath != pkgPath {
|
||||
return nil, fmt.Errorf("first package had import path %s, wanted %s", pkgs[0].PkgPath, pkgPath)
|
||||
if pkgs[0].PkgPath != p.Package {
|
||||
return nil, fmt.Errorf("first package had import path %s, wanted %s", pkgs[0].PkgPath, p.Package)
|
||||
}
|
||||
if std {
|
||||
if pm := pkgs[0].Module; std && pm != nil {
|
||||
return nil, fmt.Errorf("got module %v, expected nil", pm)
|
||||
}
|
||||
} else {
|
||||
if pm := pkgs[0].Module; pm == nil || pm.Path != module {
|
||||
return nil, fmt.Errorf("got module %v, expected %s", pm, module)
|
||||
if pm := pkgs[0].Module; pm == nil || pm.Path != m.Module {
|
||||
return nil, fmt.Errorf("got module %v, expected %s", pm, m.Module)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ packages:
|
|||
versions:
|
||||
- fixed: 0.0.0-20160903044734-789a4c4bd4c1
|
||||
- module: github.com/square/go-jose
|
||||
versions:
|
||||
- fixed: 0.0.0-20160903044734-789a4c4bd4c1
|
||||
symbols:
|
||||
- JsonWebEncryption.Decrypt
|
||||
- JsonWebEncryption.DecryptMulti
|
||||
|
|
|
@ -8,6 +8,8 @@ packages:
|
|||
versions:
|
||||
- fixed: 0.0.0-20160831185616-c7581939a365
|
||||
- module: github.com/square/go-jose
|
||||
versions:
|
||||
- fixed: 0.0.0-20160831185616-c7581939a365
|
||||
symbols:
|
||||
- JsonWebEncryption.Decrypt
|
||||
description: |
|
||||
|
|
|
@ -11,6 +11,8 @@ packages:
|
|||
package: github.com/google/fscrypt/security
|
||||
symbols:
|
||||
- UserKeyringID
|
||||
versions:
|
||||
- fixed: 0.2.4
|
||||
description: |
|
||||
After dropping and then elevating process privileges euid, guid, and groups
|
||||
are not properly restored to their original values, allowing an unprivileged
|
||||
|
|
12
go.mod
12
go.mod
|
@ -3,7 +3,7 @@ module golang.org/x/vulndb
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
golang.org/x/vuln v0.0.0-20220504230052-b2400d8d07c8
|
||||
golang.org/x/vuln v0.0.0-20220819162940-6faf8534b80b
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
)
|
||||
|
||||
|
@ -25,14 +25,14 @@ require (
|
|||
go.opentelemetry.io/otel v1.4.0
|
||||
go.opentelemetry.io/otel/metric v0.27.0
|
||||
go.opentelemetry.io/otel/sdk v1.4.0
|
||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
|
||||
golang.org/x/exp/event v0.0.0-20220218215828-6cf2b201936e
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/tools v0.1.11-0.20220504204054-4911e4af7dc7
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3
|
||||
google.golang.org/api v0.70.0
|
||||
google.golang.org/grpc v1.44.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
|
@ -71,7 +71,7 @@ require (
|
|||
go.opentelemetry.io/otel/sdk/metric v0.26.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.4.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf // indirect
|
||||
|
|
21
go.sum
21
go.sum
|
@ -356,8 +356,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0=
|
||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
golang.org/x/exp/event v0.0.0-20220218215828-6cf2b201936e h1:K2AuHMC+jaRTzAcivRwKOzjTZ1925Yx4xHMg07YoBQc=
|
||||
golang.org/x/exp/event v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AVlZHjhWbW/3yOcmKMtJiObwBPJajBlUpQXRijFNrNc=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
|
@ -427,8 +427,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
|||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -457,8 +458,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -520,8 +522,9 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -592,10 +595,10 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.11-0.20220504204054-4911e4af7dc7 h1:QA4ZyquqBP74mma6x4nQD4mSgYyTlie6xsnHTNOrOTI=
|
||||
golang.org/x/tools v0.1.11-0.20220504204054-4911e4af7dc7/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
||||
golang.org/x/vuln v0.0.0-20220504230052-b2400d8d07c8 h1:ktGzfLSmromqTs5OnNke8ZkhPYxp+FBZl1OwYHAI0Ks=
|
||||
golang.org/x/vuln v0.0.0-20220504230052-b2400d8d07c8/go.mod h1:d4bTbXdZXwwxS/kocyDYvMPrnheQY7jl7nGUkXyWsH8=
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3 h1:aE4T3aJwdCNz+s35ScSQYUzeGu7BOLDHZ1bBHVurqqY=
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/vuln v0.0.0-20220819162940-6faf8534b80b h1:ik7eOhUcX1tUkjk2QMWi2uLpqwTzkH9aamJc3GbrSk8=
|
||||
golang.org/x/vuln v0.0.0-20220819162940-6faf8534b80b/go.mod h1:7tDfEDtOLlzHQRi4Yzfg5seVBSvouUIjyPzBx4q5CxQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/vuln/client"
|
||||
|
@ -184,17 +185,13 @@ func GenerateOSVEntry(id, url string, r report.Report) (osv.Entry, []string) {
|
|||
}
|
||||
|
||||
moduleMap := make(map[string]bool)
|
||||
for _, p := range r.Packages {
|
||||
importPath := p.Module
|
||||
if p.Package != "" {
|
||||
importPath = p.Package
|
||||
}
|
||||
if stdlib.Contains(p.Module) {
|
||||
for _, m := range r.Modules {
|
||||
if m.Module == stdlib.ModulePath {
|
||||
moduleMap[stdFileName] = true
|
||||
} else {
|
||||
moduleMap[p.Module] = true
|
||||
moduleMap[m.Module] = true
|
||||
}
|
||||
entry.Affected = append(entry.Affected, generateAffected(importPath, p.Versions, r.OS, r.Arch, p.AllSymbols(), url))
|
||||
entry.Affected = append(entry.Affected, generateAffected(m, url))
|
||||
}
|
||||
|
||||
if r.Links.Advisory != "" {
|
||||
|
@ -237,18 +234,35 @@ func generateAffectedRanges(versions []report.VersionRange) osv.Affects {
|
|||
return osv.Affects{a}
|
||||
}
|
||||
|
||||
func generateAffected(importPath string, versions []report.VersionRange, goos, goarch, symbols []string, url string) osv.Affected {
|
||||
func generateImports(m *report.Module) (imps []osv.EcosystemSpecificImport) {
|
||||
for _, p := range m.Packages {
|
||||
syms := append([]string{}, p.Symbols...)
|
||||
syms = append(syms, p.DerivedSymbols...)
|
||||
sort.Strings(syms)
|
||||
imps = append(imps, osv.EcosystemSpecificImport{
|
||||
Path: p.Package,
|
||||
GOOS: p.GOOS,
|
||||
GOARCH: p.GOARCH,
|
||||
Symbols: syms,
|
||||
})
|
||||
}
|
||||
return imps
|
||||
}
|
||||
|
||||
func generateAffected(m *report.Module, url string) osv.Affected {
|
||||
name := m.Module
|
||||
if name == stdlib.ModulePath {
|
||||
name = "stdlib"
|
||||
}
|
||||
return osv.Affected{
|
||||
Package: osv.Package{
|
||||
Name: importPath,
|
||||
Name: name,
|
||||
Ecosystem: osv.GoEcosystem,
|
||||
},
|
||||
Ranges: generateAffectedRanges(versions),
|
||||
Ranges: generateAffectedRanges(m.Versions),
|
||||
DatabaseSpecific: osv.DatabaseSpecific{URL: url},
|
||||
EcosystemSpecific: osv.EcosystemSpecific{
|
||||
GOOS: goos,
|
||||
GOARCH: goarch,
|
||||
Symbols: symbols,
|
||||
Imports: generateImports(m),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
func TestGenerate(t *testing.T) {
|
||||
r := report.Report{
|
||||
Packages: []report.Package{
|
||||
Modules: []*report.Module{
|
||||
{
|
||||
Module: "example.com/vulnerable/v2",
|
||||
Versions: []report.VersionRange{
|
||||
|
@ -25,34 +25,49 @@ func TestGenerate(t *testing.T) {
|
|||
{Introduced: "2.3.4", Fixed: "2.3.5"},
|
||||
{Introduced: "2.5.0"},
|
||||
},
|
||||
Symbols: []string{"A", "B.b"},
|
||||
DerivedSymbols: []string{"D"},
|
||||
},
|
||||
{
|
||||
Module: "vanity.host/vulnerable",
|
||||
Package: "vanity.host/vulnerable/package",
|
||||
Symbols: []string{"b", "A.b"},
|
||||
Packages: []*report.Package{
|
||||
{
|
||||
Package: "example.com/vulnerable/v2",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"A", "B.b"},
|
||||
DerivedSymbols: []string{"D"},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Module: "vanity.host/vulnerable",
|
||||
Versions: []report.VersionRange{
|
||||
{Fixed: "2.1.1"},
|
||||
{Introduced: "2.3.4", Fixed: "2.3.5"},
|
||||
{Introduced: "2.5.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Module: "example.com/also-vulnerable",
|
||||
Package: "example.com/also-vulnerable/package",
|
||||
Symbols: []string{"z"},
|
||||
Packages: []*report.Package{
|
||||
{
|
||||
Package: "vanity.host/vulnerable/package",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"A.b", "b"},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Module: "example.com/also-vulnerable",
|
||||
Versions: []report.VersionRange{
|
||||
{Fixed: "2.1.1"},
|
||||
},
|
||||
Packages: []*report.Package{
|
||||
{
|
||||
Package: "example.com/also-vulnerable/package",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"z"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Description: "It's a real bad one, I'll tell you that",
|
||||
CVEs: []string{"CVE-0000-0000"},
|
||||
GHSAs: []string{"GHSA-abcd-efgh"},
|
||||
Credit: "ignored",
|
||||
OS: []string{"windows"},
|
||||
Arch: []string{"arm64"},
|
||||
Links: report.Links{
|
||||
PR: "pr",
|
||||
Commit: "commit",
|
||||
|
@ -105,14 +120,19 @@ func TestGenerate(t *testing.T) {
|
|||
},
|
||||
DatabaseSpecific: osv.DatabaseSpecific{URL: url},
|
||||
EcosystemSpecific: osv.EcosystemSpecific{
|
||||
Symbols: []string{"A", "B.b", "D"},
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Imports: []osv.EcosystemSpecificImport{
|
||||
{
|
||||
Path: "example.com/vulnerable/v2",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"A", "B.b", "D"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Package: osv.Package{
|
||||
Name: "vanity.host/vulnerable/package",
|
||||
Name: "vanity.host/vulnerable",
|
||||
Ecosystem: "Go",
|
||||
},
|
||||
Ranges: []osv.AffectsRange{
|
||||
|
@ -139,14 +159,19 @@ func TestGenerate(t *testing.T) {
|
|||
},
|
||||
DatabaseSpecific: osv.DatabaseSpecific{URL: url},
|
||||
EcosystemSpecific: osv.EcosystemSpecific{
|
||||
Symbols: []string{"b", "A.b"},
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Imports: []osv.EcosystemSpecificImport{
|
||||
{
|
||||
Path: "vanity.host/vulnerable/package",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"A.b", "b"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Package: osv.Package{
|
||||
Name: "example.com/also-vulnerable/package",
|
||||
Name: "example.com/also-vulnerable",
|
||||
Ecosystem: "Go",
|
||||
},
|
||||
Ranges: []osv.AffectsRange{
|
||||
|
@ -164,9 +189,14 @@ func TestGenerate(t *testing.T) {
|
|||
},
|
||||
DatabaseSpecific: osv.DatabaseSpecific{URL: url},
|
||||
EcosystemSpecific: osv.EcosystemSpecific{
|
||||
Symbols: []string{"z"},
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Imports: []osv.EcosystemSpecificImport{
|
||||
{
|
||||
Path: "example.com/also-vulnerable/package",
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
Symbols: []string{"z"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -65,14 +65,14 @@ func ToCVE(reportPath string) (_ *cveschema.CVE, err error) {
|
|||
},
|
||||
}
|
||||
|
||||
for _, p := range r.Packages {
|
||||
for _, m := range r.Modules {
|
||||
c.Affects.Vendor.Data = append(c.Affects.Vendor.Data, cveschema.VendorDataItem{
|
||||
VendorName: "n/a", // ???
|
||||
Product: cveschema.Product{
|
||||
Data: []cveschema.ProductDataItem{
|
||||
{
|
||||
ProductName: p.Package,
|
||||
Version: versionToVersion(p.Versions),
|
||||
ProductName: m.Module,
|
||||
Version: versionToVersion(m.Versions),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -145,10 +145,18 @@ func CVEToReport(c *cveschema.CVE, modulePath string) *Report {
|
|||
pkgPath = data2[0].ProductName
|
||||
}
|
||||
}
|
||||
if modulePath == "" {
|
||||
modulePath = "TODO"
|
||||
}
|
||||
if pkgPath == "" {
|
||||
pkgPath = modulePath
|
||||
}
|
||||
r := &Report{
|
||||
Packages: []Package{{
|
||||
Module: modulePath,
|
||||
Package: pkgPath,
|
||||
Modules: []*Module{{
|
||||
Module: modulePath,
|
||||
Packages: []*Package{{
|
||||
Package: pkgPath,
|
||||
}},
|
||||
}},
|
||||
Description: description,
|
||||
CVEs: []string{c.Metadata.ID},
|
||||
|
@ -160,11 +168,11 @@ func CVEToReport(c *cveschema.CVE, modulePath string) *Report {
|
|||
},
|
||||
}
|
||||
if !strings.Contains(modulePath, ".") {
|
||||
r.Packages[0].Module = stdlib.ModulePath
|
||||
r.Packages[0].Package = modulePath
|
||||
r.Modules[0].Module = stdlib.ModulePath
|
||||
r.Modules[0].Packages[0].Package = modulePath
|
||||
}
|
||||
if stdlib.Contains(r.Packages[0].Module) && r.Packages[0].Package == "" {
|
||||
r.Packages[0].Package = modulePath
|
||||
if stdlib.Contains(r.Modules[0].Module) && r.Modules[0].Packages[0].Package == "" {
|
||||
r.Modules[0].Packages[0].Package = modulePath
|
||||
}
|
||||
r.Fix()
|
||||
return r
|
||||
|
|
|
@ -72,22 +72,20 @@ func ToCVE5(reportPath string) (_ *cveschema5.CVERecord, err error) {
|
|||
},
|
||||
}
|
||||
|
||||
for _, p := range r.Packages {
|
||||
pkg := p.Package
|
||||
if pkg == "" {
|
||||
pkg = p.Module
|
||||
for _, m := range r.Modules {
|
||||
for _, p := range m.Packages {
|
||||
affected := cveschema5.Affected{
|
||||
CollectionURL: "https://pkg.go.dev",
|
||||
PackageName: p.Package,
|
||||
Versions: versionRangeToVersionRange(m.Versions),
|
||||
DefaultStatus: cveschema5.StatusUnaffected,
|
||||
Platforms: p.GOOS,
|
||||
}
|
||||
for _, symbol := range p.AllSymbols() {
|
||||
affected.ProgramRoutines = append(affected.ProgramRoutines, cveschema5.ProgramRoutine{Name: symbol})
|
||||
}
|
||||
c.Affected = append(c.Affected, affected)
|
||||
}
|
||||
affected := cveschema5.Affected{
|
||||
CollectionURL: "https://pkg.go.dev",
|
||||
PackageName: pkg,
|
||||
Versions: versionRangeToVersionRange(p.Versions),
|
||||
DefaultStatus: cveschema5.StatusUnaffected,
|
||||
Platforms: r.OS,
|
||||
}
|
||||
for _, symbol := range p.AllSymbols() {
|
||||
affected.ProgramRoutines = append(affected.ProgramRoutines, cveschema5.ProgramRoutine{Name: symbol})
|
||||
}
|
||||
c.Affected = append(c.Affected, affected)
|
||||
}
|
||||
|
||||
for _, link := range r.AllLinks() {
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
package report
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"golang.org/x/vulndb/internal/cveschema5"
|
||||
)
|
||||
|
||||
|
@ -180,8 +180,8 @@ func TestToCVE5(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("ToCVE5(%s) failed unexpectedly; err=%v", test.filename, err)
|
||||
}
|
||||
if want := test.want; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("ToCVE5(%s)=\n%v\nwant=\n%v", test.filename, got, want)
|
||||
if diff := cmp.Diff(test.want, got); diff != "" {
|
||||
t.Fatalf("ToCVE5(%s): unexpected diffs (-want,+got):\n%v", test.filename, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -31,15 +31,18 @@ func GHSAToReport(sa *ghsa.SecurityAdvisory, modulePath string) *Report {
|
|||
}
|
||||
r.CVEs = cves
|
||||
r.GHSAs = ghsas
|
||||
for i, v := range sa.Vulns {
|
||||
p := Package{
|
||||
Package: v.Package,
|
||||
if modulePath == "" {
|
||||
modulePath = "TODO"
|
||||
}
|
||||
for _, v := range sa.Vulns {
|
||||
m := &Module{
|
||||
Module: modulePath,
|
||||
Versions: versions(v.EarliestFixedVersion, v.VulnerableVersionRange),
|
||||
Packages: []*Package{{
|
||||
Package: v.Package,
|
||||
}},
|
||||
}
|
||||
if i == 0 {
|
||||
p.Module = modulePath
|
||||
}
|
||||
r.Packages = append(r.Packages, p)
|
||||
r.Modules = append(r.Modules, m)
|
||||
}
|
||||
r.Fix()
|
||||
return r
|
||||
|
|
|
@ -28,12 +28,14 @@ func TestGHSAToReport(t *testing.T) {
|
|||
}
|
||||
got := GHSAToReport(sa, "aModule")
|
||||
want := &Report{
|
||||
Packages: []Package{{
|
||||
Module: "aModule",
|
||||
Package: "aPackage",
|
||||
Modules: []*Module{{
|
||||
Module: "aModule",
|
||||
Versions: []VersionRange{
|
||||
{Fixed: "1.2.3"},
|
||||
},
|
||||
Packages: []*Package{{
|
||||
Package: "aPackage",
|
||||
}},
|
||||
}},
|
||||
LastModified: &updatedTime,
|
||||
Description: "a description",
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
"golang.org/x/vulndb/internal/stdlib"
|
||||
)
|
||||
|
||||
// TODO: getting things from the proxy should all be cached so we
|
||||
|
@ -147,41 +148,44 @@ func checkModVersions(modPath string, vrs []VersionRange) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Package) lintStdLibPkg(addPkgIssue func(string)) {
|
||||
if p.Package == "" {
|
||||
func (m *Module) lintStdLib(addPkgIssue func(string)) {
|
||||
if len(m.Packages) == 0 {
|
||||
addPkgIssue("missing package")
|
||||
}
|
||||
for _, p := range m.Packages {
|
||||
if p.Package == "" {
|
||||
addPkgIssue("missing package")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Package) lintThirdPartyPkg(addPkgIssue func(string)) {
|
||||
if p.Module == "" {
|
||||
func (m *Module) lintThirdParty(addPkgIssue func(string)) {
|
||||
if m.Module == "" {
|
||||
addPkgIssue("missing module")
|
||||
return
|
||||
}
|
||||
if p.Package == p.Module {
|
||||
addPkgIssue("package is redundant and can be removed")
|
||||
}
|
||||
if p.Package != "" && !strings.HasPrefix(p.Package, p.Module) {
|
||||
addPkgIssue("module must be a prefix of package")
|
||||
}
|
||||
if err := checkModVersions(p.Module, p.Versions); err != nil {
|
||||
if err := checkModVersions(m.Module, m.Versions); err != nil {
|
||||
addPkgIssue(err.Error())
|
||||
}
|
||||
|
||||
importPath := p.Package
|
||||
if p.Package == "" {
|
||||
importPath = p.Module
|
||||
}
|
||||
if err := module.CheckImportPath(importPath); err != nil {
|
||||
addPkgIssue(err.Error())
|
||||
for _, p := range m.Packages {
|
||||
if p.Package == "" {
|
||||
addPkgIssue("missing package")
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(p.Package, m.Module) {
|
||||
addPkgIssue("module must be a prefix of package")
|
||||
}
|
||||
if err := module.CheckImportPath(p.Package); err != nil {
|
||||
addPkgIssue(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Package) lintVersions(addPkgIssue func(string)) {
|
||||
if p.VulnerableAt != "" && !p.VulnerableAt.IsValid() {
|
||||
addPkgIssue(fmt.Sprintf("invalid vulnerable_at semantic version: %q", p.VulnerableAt))
|
||||
func (m *Module) lintVersions(addPkgIssue func(string)) {
|
||||
if m.VulnerableAt != "" && !m.VulnerableAt.IsValid() {
|
||||
addPkgIssue(fmt.Sprintf("invalid vulnerable_at semantic version: %q", m.VulnerableAt))
|
||||
}
|
||||
for i, vr := range p.Versions {
|
||||
for i, vr := range m.Versions {
|
||||
for _, v := range []Version{vr.Introduced, vr.Fixed} {
|
||||
if v != "" && !v.IsValid() {
|
||||
addPkgIssue(fmt.Sprintf("invalid semantic version: %q", v))
|
||||
|
@ -194,7 +198,7 @@ func (p *Package) lintVersions(addPkgIssue func(string)) {
|
|||
}
|
||||
// Check all previous version ranges to ensure none overlap with
|
||||
// this one.
|
||||
for _, vrPrev := range p.Versions[:i] {
|
||||
for _, vrPrev := range m.Versions[:i] {
|
||||
if vrPrev.Introduced.Before(vr.Fixed) && vr.Introduced.Before(vrPrev.Fixed) {
|
||||
addPkgIssue(fmt.Sprintf("version ranges overlap: [%v,%v), [%v,%v)", vr.Introduced, vr.Fixed, vr.Introduced, vrPrev.Fixed))
|
||||
}
|
||||
|
@ -318,8 +322,8 @@ func (r *Report) Lint(filename string) []string {
|
|||
if r.Excluded != "" {
|
||||
addIssue("report in reports/ must not have excluded set")
|
||||
}
|
||||
if len(r.Packages) == 0 {
|
||||
addIssue("no packages")
|
||||
if len(r.Modules) == 0 {
|
||||
addIssue("no modules")
|
||||
}
|
||||
if r.Description == "" {
|
||||
addIssue("missing description")
|
||||
|
@ -330,8 +334,8 @@ func (r *Report) Lint(filename string) []string {
|
|||
} else if !slices.Contains(ExcludedReasons, r.Excluded) {
|
||||
addIssue(fmt.Sprintf("excluded (%q) is not in set %v", r.Excluded, ExcludedReasons))
|
||||
}
|
||||
if len(r.Packages) != 0 {
|
||||
addIssue("excluded report should not have packages")
|
||||
if len(r.Modules) != 0 {
|
||||
addIssue("excluded report should not have modules")
|
||||
}
|
||||
if len(r.CVEs) == 0 && len(r.GHSAs) == 0 {
|
||||
addIssue("excluded report must have at least one associated CVE or GHSA")
|
||||
|
@ -339,19 +343,19 @@ func (r *Report) Lint(filename string) []string {
|
|||
}
|
||||
|
||||
isStdLibReport := false
|
||||
for i, p := range r.Packages {
|
||||
for i, m := range r.Modules {
|
||||
addPkgIssue := func(iss string) {
|
||||
addIssue(fmt.Sprintf("packages[%v]: %v", i, iss))
|
||||
addIssue(fmt.Sprintf("modules[%v]: %v", i, iss))
|
||||
}
|
||||
|
||||
if p.Module == "std" {
|
||||
if m.Module == stdlib.ModulePath {
|
||||
isStdLibReport = true
|
||||
p.lintStdLibPkg(addPkgIssue)
|
||||
m.lintStdLib(addPkgIssue)
|
||||
} else {
|
||||
p.lintThirdPartyPkg(addPkgIssue)
|
||||
m.lintThirdParty(addPkgIssue)
|
||||
}
|
||||
|
||||
p.lintVersions(addPkgIssue)
|
||||
m.lintVersions(addPkgIssue)
|
||||
}
|
||||
|
||||
if r.LastModified != nil && r.LastModified.Before(r.Published) {
|
||||
|
@ -396,15 +400,12 @@ func (r *Report) Fix() {
|
|||
}
|
||||
*vp = v
|
||||
}
|
||||
for i, p := range r.Packages {
|
||||
if p.Package == p.Module {
|
||||
p.Package = ""
|
||||
for _, m := range r.Modules {
|
||||
for i := range m.Versions {
|
||||
fixVersion(&m.Versions[i].Introduced)
|
||||
fixVersion(&m.Versions[i].Fixed)
|
||||
}
|
||||
for j := range p.Versions {
|
||||
fixVersion(&r.Packages[i].Versions[j].Introduced)
|
||||
fixVersion(&r.Packages[i].Versions[j].Fixed)
|
||||
}
|
||||
fixVersion(&r.Packages[i].VulnerableAt)
|
||||
fixVersion(&m.VulnerableAt)
|
||||
}
|
||||
r.Links.Context = fixed
|
||||
}
|
||||
|
|
|
@ -34,18 +34,20 @@ func TestLint(t *testing.T) {
|
|||
want []string
|
||||
}{
|
||||
{
|
||||
desc: "no packages",
|
||||
desc: "no modules",
|
||||
report: Report{
|
||||
Description: "description",
|
||||
},
|
||||
want: []string{"no packages"},
|
||||
want: []string{"no modules"},
|
||||
},
|
||||
{
|
||||
desc: "missing module",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
// no module
|
||||
Package: "golang.org/x/vulndb",
|
||||
Modules: []*Module{{
|
||||
// mo module
|
||||
Packages: []*Package{{
|
||||
Package: "golang.org/x/vulndb",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
},
|
||||
|
@ -54,9 +56,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "missing description",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
// no description
|
||||
Links: validStdLibLinks,
|
||||
|
@ -64,22 +68,26 @@ func TestLint(t *testing.T) {
|
|||
want: []string{"missing description"},
|
||||
},
|
||||
{
|
||||
desc: "third party: redundant module and package",
|
||||
desc: "missing package path",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Package: "golang.org/x/vulndb",
|
||||
Modules: []*Module{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Packages: []*Package{{
|
||||
Symbols: []string{"Foo"},
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
},
|
||||
want: []string{"package is redundant and can be removed"},
|
||||
want: []string{"missing package"},
|
||||
},
|
||||
{
|
||||
desc: "third party: module is not a prefix of package",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Package: "golang.org/x/crypto",
|
||||
Modules: []*Module{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Packages: []*Package{{
|
||||
Package: "golang.org/x/crypto",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
},
|
||||
|
@ -88,8 +96,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "third party: invalid import path",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Modules: []*Module{{
|
||||
Module: "invalid.",
|
||||
Packages: []*Package{{
|
||||
Package: "invalid.",
|
||||
}},
|
||||
Versions: []VersionRange{{
|
||||
Fixed: "1.2.1",
|
||||
}},
|
||||
|
@ -102,9 +113,12 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "standard library: missing package",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
// no package
|
||||
Packages: []*Package{{
|
||||
// no package
|
||||
Symbols: []string{"Atoi"},
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: validStdLibLinks,
|
||||
|
@ -114,14 +128,16 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "overlapping version ranges",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Versions: []VersionRange{{
|
||||
Fixed: "1.2.1",
|
||||
}, {
|
||||
Fixed: "1.3.2",
|
||||
}},
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: validStdLibLinks,
|
||||
|
@ -131,13 +147,15 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "fixed before introduced",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Versions: []VersionRange{{
|
||||
Introduced: "1.3",
|
||||
Fixed: "1.2.1",
|
||||
}},
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: validStdLibLinks,
|
||||
|
@ -147,12 +165,14 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "invalid semantic version",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Versions: []VersionRange{{
|
||||
Introduced: "1.3.X",
|
||||
}},
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: validStdLibLinks,
|
||||
|
@ -162,9 +182,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "last modified before published",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
LastModified: &jan2000,
|
||||
|
@ -176,9 +198,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "bad cve identifier",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
CVEs: []string{"CVE.12345.456"},
|
||||
|
@ -189,9 +213,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "cve and cve metadata both present",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
CVEs: []string{"CVE-2022-1234545"},
|
||||
|
@ -205,9 +231,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "missing cve metadata id",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
CVEMetadata: &CVEMeta{
|
||||
|
@ -220,9 +248,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "bad cve metadata id",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
CVEMetadata: &CVEMeta{
|
||||
|
@ -235,8 +265,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "unfixed links",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Modules: []*Module{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Packages: []*Package{{
|
||||
Package: "golang.org/x/vulndb",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: Links{
|
||||
|
@ -256,9 +289,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "standard library: unfixed/missing links",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Module: "std",
|
||||
Package: "time",
|
||||
Modules: []*Module{{
|
||||
Module: "std",
|
||||
Packages: []*Package{{
|
||||
Package: "time",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: Links{
|
||||
|
@ -285,8 +320,11 @@ func TestLint(t *testing.T) {
|
|||
{
|
||||
desc: "invalid URL",
|
||||
report: Report{
|
||||
Packages: []Package{{
|
||||
Modules: []*Module{{
|
||||
Module: "golang.org/x/vulndb",
|
||||
Packages: []*Package{{
|
||||
Package: "golang.org/x/vulndb",
|
||||
}},
|
||||
}},
|
||||
Description: "description",
|
||||
Links: Links{
|
||||
|
@ -305,7 +343,7 @@ func TestLint(t *testing.T) {
|
|||
},
|
||||
want: []string{
|
||||
`report in reports/ must not have excluded set`,
|
||||
`no packages`,
|
||||
`no modules`,
|
||||
`missing description`,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
package report
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -47,7 +49,31 @@ type VersionRange struct {
|
|||
Fixed Version `yaml:"fixed,omitempty"`
|
||||
}
|
||||
|
||||
type Module struct {
|
||||
Module string `yaml:",omitempty"`
|
||||
Versions []VersionRange `yaml:",omitempty"`
|
||||
// Known-vulnerable version, to use when performing static analysis or
|
||||
// other techniques on a vulnerable version of the package.
|
||||
//
|
||||
// In general, we want to use the most recent vulnerable version of
|
||||
// the package. Determining this programmatically is difficult, especially
|
||||
// for packages without tagged versions, so we specify it manually here.
|
||||
VulnerableAt Version `yaml:"vulnerable_at,omitempty"`
|
||||
Packages []*Package `yaml:",omitempty"`
|
||||
}
|
||||
|
||||
type Package struct {
|
||||
Package string `yaml:",omitempty"`
|
||||
GOOS []string `yaml:"goos,omitempty"`
|
||||
GOARCH []string `yaml:"goarch,omitempty"`
|
||||
// Symbols originally identified as vulnerable.
|
||||
Symbols []string `yaml:",omitempty"`
|
||||
// Additional vulnerable symbols, computed from Symbols via static analysis
|
||||
// or other technique.
|
||||
DerivedSymbols []string `yaml:"derived_symbols,omitempty"`
|
||||
}
|
||||
|
||||
type LegacyPackage struct {
|
||||
Module string `yaml:",omitempty"`
|
||||
Package string `yaml:",omitempty"`
|
||||
// Symbols originally identified as vulnerable.
|
||||
|
@ -107,7 +133,7 @@ type Report struct {
|
|||
// Excluded indicates an excluded report.
|
||||
Excluded ExcludedReason `yaml:",omitempty"`
|
||||
|
||||
Packages []Package `yaml:"packages,omitempty"`
|
||||
Modules []*Module `yaml:",omitempty"`
|
||||
|
||||
// Description is the CVE description from an existing CVE. If we are
|
||||
// assigning a CVE ID ourselves, use CVEMetadata.Description instead.
|
||||
|
@ -123,15 +149,19 @@ type Report struct {
|
|||
// the above CVEs.
|
||||
GHSAs []string `yaml:",omitempty"`
|
||||
|
||||
Credit string `yaml:",omitempty"`
|
||||
OS []string `yaml:",omitempty"`
|
||||
Arch []string `yaml:",omitempty"`
|
||||
Links Links `yaml:",omitempty"`
|
||||
Credit string `yaml:",omitempty"`
|
||||
Links Links `yaml:",omitempty"`
|
||||
|
||||
// CVEMetdata is used to capture CVE information when we want to assign a
|
||||
// CVE ourselves. If a CVE already exists for an issue, use the CVE field
|
||||
// to fill in the ID string.
|
||||
CVEMetadata *CVEMeta `yaml:"cve_metadata,omitempty"`
|
||||
|
||||
// Pre-refactoring fields.
|
||||
// TODO(dneil): Remove.
|
||||
LegacyPackages []LegacyPackage `yaml:"packages,omitempty"`
|
||||
LegacyOS []string `yaml:"os,omitempty"`
|
||||
LegacyArch []string `yaml:"arch,omitempty"`
|
||||
}
|
||||
|
||||
// GetCVEs returns all CVE IDs for a report.
|
||||
|
@ -208,9 +238,53 @@ func Read(filename string) (_ *Report, err error) {
|
|||
if err := d.Decode(&r); err != nil {
|
||||
return nil, fmt.Errorf("yaml.Decode: %v", err)
|
||||
}
|
||||
|
||||
if err := r.upgrade(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// upgrade updates the format of a report from a prior syntax version
|
||||
// to the current one.
|
||||
//
|
||||
// TODO(dneil): delete after all reports have been updated to the new syntax.
|
||||
func (r *Report) upgrade() error {
|
||||
if len(r.Modules) > 0 && len(r.LegacyPackages) > 0 {
|
||||
return errors.New("modules and packages both set")
|
||||
}
|
||||
mods := make(map[string]*Module)
|
||||
for _, p := range r.LegacyPackages {
|
||||
mod := mods[p.Module]
|
||||
if mod == nil {
|
||||
mod = &Module{
|
||||
Module: p.Module,
|
||||
Versions: p.Versions,
|
||||
VulnerableAt: p.VulnerableAt,
|
||||
}
|
||||
mods[p.Module] = mod
|
||||
r.Modules = append(r.Modules, mod)
|
||||
}
|
||||
if !reflect.DeepEqual(mod.Versions, p.Versions) || mod.VulnerableAt != p.VulnerableAt {
|
||||
return errors.New("inconsistent module versions")
|
||||
}
|
||||
name := p.Package
|
||||
if name == "" {
|
||||
name = p.Module
|
||||
}
|
||||
mod.Packages = append(mod.Packages, &Package{
|
||||
Package: name,
|
||||
GOOS: r.LegacyOS,
|
||||
GOARCH: r.LegacyArch,
|
||||
Symbols: p.Symbols,
|
||||
DerivedSymbols: p.DerivedSymbols,
|
||||
})
|
||||
}
|
||||
r.LegacyPackages = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes r to filename in YAML format.
|
||||
func (r *Report) Write(filename string) (err error) {
|
||||
f, err := os.Create(filename)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
packages:
|
||||
modules:
|
||||
- module: github.com/gin-gonic/gin
|
||||
symbols:
|
||||
- defaultLogFormatter
|
||||
versions:
|
||||
- fixed: 1.6.0
|
||||
packages:
|
||||
- package: github.com/gin-gonic/gin
|
||||
symbols:
|
||||
- defaultLogFormatter
|
||||
description: |
|
||||
The default Formatter for the Logger middleware (LoggerConfig.Formatter),
|
||||
which is included in the Default engine, allows attackers to inject arbitrary
|
||||
|
|
|
@ -2,15 +2,18 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
packages:
|
||||
modules:
|
||||
- module: std
|
||||
package: crypto/rand
|
||||
symbols:
|
||||
- TestSymbol
|
||||
versions:
|
||||
- fixed: 1.17.11
|
||||
- introduced: 1.18.0
|
||||
fixed: 1.18.3
|
||||
packages:
|
||||
- package: crypto/rand
|
||||
goos:
|
||||
- windows
|
||||
symbols:
|
||||
- TestSymbol
|
||||
description: |
|
||||
On Windows, TestSymbol will hang indefinitely if passed a large buffer.
|
||||
cve_metadata:
|
||||
|
@ -19,8 +22,6 @@ cve_metadata:
|
|||
description: |
|
||||
A description
|
||||
credit: A Credit
|
||||
os:
|
||||
- windows
|
||||
links:
|
||||
pr: https://go.dev/cl/12345
|
||||
commit: https://go.googlesource.com/go/+/abcde
|
||||
|
|
|
@ -232,8 +232,10 @@ Links:
|
|||
See [doc/triage.md](https://github.com/golang/vulndb/blob/master/doc/triage.md) for instructions on how to triage this report.
|
||||
|
||||
` + "```" + `
|
||||
packages:
|
||||
modules:
|
||||
- module: a.Module
|
||||
packages:
|
||||
- package: a.Module
|
||||
description: |
|
||||
a description
|
||||
cves:
|
||||
|
@ -272,10 +274,12 @@ func TestNewGHSABody(t *testing.T) {
|
|||
See [doc/triage.md](https://github.com/golang/vulndb/blob/master/doc/triage.md) for instructions on how to triage this report.
|
||||
|
||||
` + "```" + `
|
||||
packages:
|
||||
- package: aPackage
|
||||
modules:
|
||||
- module: TODO
|
||||
versions:
|
||||
- fixed: 1.2.3
|
||||
packages:
|
||||
- package: aPackage
|
||||
description: a description
|
||||
ghsas:
|
||||
- G1
|
||||
|
|
Загрузка…
Ссылка в новой задаче