зеркало из https://github.com/golang/vuln.git
all: initial commit
This commit is contained in:
Коммит
abe7a418ae
|
@ -0,0 +1,12 @@
|
|||
This repository contains a handful of prototypes for the Go vulnerability database,
|
||||
as well as a initial set of vulnerability reports. Some of these packages can probably
|
||||
be coalesced, but for now are easier to work on in a more segmented fashion.
|
||||
|
||||
* `reports` contains TOML security reports, the format is described in `format.md`
|
||||
* `report` provides a package for parsing and linting TOML reports
|
||||
* `osv` provides a package for generating OSV-style JSON vulnerability entries from a `report.Report`
|
||||
* `client` contains a client for accesing HTTP/fs based vulnerability databases, as well as a minimal caching implementation
|
||||
* `cmd/gendb` provides a tool for converting TOML reports into JSON database
|
||||
* `cmd/genhtml` provides a tool for converting TOML reports into a HTML website
|
||||
* `cmd/linter` provides a tool for linting individual reports
|
||||
* `cmd/report2cve` provides a tool for converting TOML reports into JSON CVEs
|
|
@ -0,0 +1,115 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"golang.org/x/vulndb/osv"
|
||||
)
|
||||
|
||||
// NOTE: this cache implementation should be internal to the go tooling
|
||||
// (i.e. cmd/go/internal/something) so that the vulndb cache is owned
|
||||
// by the go command. Also it is currently NOT CONCURRENCY SAFE since
|
||||
// it does not implement file locking. When ported to the stdlib it
|
||||
// should use cmd/go/internal/lockedfile.
|
||||
|
||||
// The cahce uses a single JSON index file for each vulnerability database
|
||||
// which contains the map from packages to the time the last
|
||||
// vulnerability for that package was added/modified and the time that
|
||||
// the index was retrieved from the vulnerability database. The JSON
|
||||
// format is as follows:
|
||||
//
|
||||
// $GOPATH/pkg/mod/cache/download/vulndb/{db hostname}/indexes/index.json
|
||||
// {
|
||||
// Retrieved time.Time
|
||||
// Index map[string]time.Time
|
||||
// }
|
||||
//
|
||||
// Each package also has a JSON file which contains the array of vulnerability
|
||||
// entries for the package. The JSON format is as follows:
|
||||
//
|
||||
// $GOPATH/pkg/mod/cache/download/vulndb/{db hostname}/{import path}/vulns.json
|
||||
// []*osv.Entry
|
||||
|
||||
type Cache interface {
|
||||
ReadIndex(string) (map[string]time.Time, time.Time, error)
|
||||
WriteIndex(string, map[string]time.Time, time.Time) error
|
||||
ReadEntries(string, string) ([]*osv.Entry, error)
|
||||
WriteEntries(string, string, []*osv.Entry) error
|
||||
}
|
||||
|
||||
type fsCache struct{}
|
||||
|
||||
// should be cfg.GOMODCACHE when doing this inside the cmd/go/internal
|
||||
var cacheRoot = filepath.Join(build.Default.GOPATH, "/pkg/mod/cache/downlaod/vulndb")
|
||||
|
||||
type cachedIndex struct {
|
||||
Retrieved time.Time
|
||||
Index map[string]time.Time
|
||||
}
|
||||
|
||||
func (c *fsCache) ReadIndex(dbName string) (map[string]time.Time, time.Time, error) {
|
||||
b, err := os.ReadFile(filepath.Join(cacheRoot, dbName, "index.json"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, time.Time{}, nil
|
||||
}
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
var index cachedIndex
|
||||
if err := json.Unmarshal(b, &index); err != nil {
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
return index.Index, index.Retrieved, nil
|
||||
}
|
||||
|
||||
func (c *fsCache) WriteIndex(dbName string, index map[string]time.Time, retrieved time.Time) error {
|
||||
path := filepath.Join(cacheRoot, dbName)
|
||||
if err := os.MkdirAll(path, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
j, err := json.Marshal(cachedIndex{
|
||||
Index: index,
|
||||
Retrieved: retrieved,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(path, "index.json"), j, 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *fsCache) ReadEntries(dbName string, p string) ([]*osv.Entry, error) {
|
||||
b, err := os.ReadFile(filepath.Join(cacheRoot, dbName, p, "vulns.json"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var entries []*osv.Entry
|
||||
if err := json.Unmarshal(b, &entries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func (c *fsCache) WriteEntries(dbName string, p string, entries []*osv.Entry) error {
|
||||
path := filepath.Join(cacheRoot, dbName, p)
|
||||
if err := os.MkdirAll(path, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
j, err := json.Marshal(entries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(path, "vulns.json"), j, 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/vulndb/osv"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
originalRoot := cacheRoot
|
||||
defer func() { cacheRoot = originalRoot }()
|
||||
|
||||
tmp, err := os.MkdirTemp("", "vulndb-cache")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
cacheRoot = tmp
|
||||
|
||||
cache := &fsCache{}
|
||||
dbName := "vulndb.golang.org"
|
||||
|
||||
_, _, err = cache.ReadIndex(dbName)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadIndex failed for non-existent database: %v", err)
|
||||
}
|
||||
|
||||
if err = os.Mkdir(filepath.Join(tmp, dbName), 0777); err != nil {
|
||||
t.Fatalf("os.Mkdir failed: %v", err)
|
||||
}
|
||||
_, _, err = cache.ReadIndex(dbName)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadIndex failed for database without cached index: %v", err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
expectedIdx := map[string]time.Time{
|
||||
"a.vuln.example.com": time.Time{}.Add(time.Hour),
|
||||
"b.vuln.example.com": time.Time{}.Add(time.Hour * 2),
|
||||
"c.vuln.example.com": time.Time{}.Add(time.Hour * 3),
|
||||
}
|
||||
if err = cache.WriteIndex(dbName, expectedIdx, now); err != nil {
|
||||
t.Fatalf("WriteIndex failed to write index: %v", err)
|
||||
}
|
||||
|
||||
idx, retrieved, err := cache.ReadIndex(dbName)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadIndex failed for database with cached index: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(idx, expectedIdx) {
|
||||
t.Errorf("ReadIndex returned unexpected index, got:\n%s\nwant:\n%s", idx, expectedIdx)
|
||||
}
|
||||
if !retrieved.Equal(now) {
|
||||
t.Errorf("ReadIndex returned unexpected retrieved: got %s, want %s", retrieved, now)
|
||||
}
|
||||
|
||||
if _, err = cache.ReadEntries(dbName, "vuln.example.com"); err != nil {
|
||||
t.Fatalf("ReadEntires failed for non-existent package: %v", err)
|
||||
}
|
||||
|
||||
expectedEntries := []*osv.Entry{
|
||||
&osv.Entry{ID: "001"},
|
||||
&osv.Entry{ID: "002"},
|
||||
&osv.Entry{ID: "003"},
|
||||
}
|
||||
if err := cache.WriteEntries(dbName, "vuln.example.com", expectedEntries); err != nil {
|
||||
t.Fatalf("WriteEntries failed: %v", err)
|
||||
}
|
||||
|
||||
entries, err := cache.ReadEntries(dbName, "vuln.example.com")
|
||||
if err != nil {
|
||||
t.Fatalf("ReadEntries failed for cached package: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(entries, expectedEntries) {
|
||||
t.Errorf("ReadEntries returned unexpected entries, got:\n%v\nwant:\n%v", entries, expectedEntries)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/vulndb/osv"
|
||||
)
|
||||
|
||||
type dbIndex struct{}
|
||||
|
||||
type source interface {
|
||||
Get([]string) ([]*osv.Entry, error)
|
||||
Index() (map[string]time.Time, error)
|
||||
}
|
||||
|
||||
type localSource struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func (ls *localSource) Get(packages []string) ([]*osv.Entry, error) {
|
||||
var entries []*osv.Entry
|
||||
for _, p := range packages {
|
||||
content, err := os.ReadFile(filepath.Join(ls.dir, p+".json"))
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var e []*osv.Entry
|
||||
if err = json.Unmarshal(content, &e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, e...)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func (ls *localSource) Index() (map[string]time.Time, error) {
|
||||
var index map[string]time.Time
|
||||
b, err := os.ReadFile(filepath.Join(ls.dir, "index.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = json.Unmarshal(b, &index); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return index, nil
|
||||
}
|
||||
|
||||
type httpSource struct {
|
||||
url string
|
||||
c *http.Client
|
||||
cache Cache
|
||||
dbName string
|
||||
}
|
||||
|
||||
func (hs *httpSource) Index() (map[string]time.Time, error) {
|
||||
var cachedIndex map[string]time.Time
|
||||
var cachedIndexRetrieved *time.Time
|
||||
|
||||
if hs.cache != nil {
|
||||
cachedIndex, retrieved, err := hs.cache.ReadIndex(hs.dbName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cachedIndex != nil {
|
||||
if time.Since(retrieved) < time.Hour*2 {
|
||||
return cachedIndex, nil
|
||||
}
|
||||
|
||||
cachedIndexRetrieved = &retrieved
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", path.Join(hs.url, "index.json"), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cachedIndexRetrieved != nil {
|
||||
req.Header.Add("If-Modified-Since", cachedIndexRetrieved.Format(http.TimeFormat))
|
||||
}
|
||||
resp, err := hs.c.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if cachedIndexRetrieved != nil && resp.StatusCode == http.StatusNotModified {
|
||||
return cachedIndex, nil
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var index map[string]time.Time
|
||||
if err = json.Unmarshal(b, &index); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hs.cache != nil {
|
||||
if err = hs.cache.WriteIndex(hs.dbName, index, time.Now()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return index, nil
|
||||
}
|
||||
|
||||
func (hs *httpSource) Get(packages []string) ([]*osv.Entry, error) {
|
||||
var entries []*osv.Entry
|
||||
|
||||
index, err := hs.Index()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var stillNeed []string
|
||||
if hs.cache != nil {
|
||||
for _, p := range packages {
|
||||
lastModified, present := index[p]
|
||||
if !present {
|
||||
continue
|
||||
}
|
||||
if cached, err := hs.cache.ReadEntries(hs.dbName, p); err != nil {
|
||||
return nil, err
|
||||
} else if cached != nil {
|
||||
var stale bool
|
||||
for _, e := range entries {
|
||||
if e.LastModified.Before(lastModified) {
|
||||
stale = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !stale {
|
||||
entries = append(entries, cached...)
|
||||
continue
|
||||
}
|
||||
}
|
||||
stillNeed = append(stillNeed, p)
|
||||
}
|
||||
} else {
|
||||
stillNeed = packages
|
||||
}
|
||||
|
||||
for _, p := range stillNeed {
|
||||
resp, err := hs.c.Get(path.Join(hs.url, p+".json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
continue
|
||||
}
|
||||
// might want this to be a LimitedReader
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var e []*osv.Entry
|
||||
if err = json.Unmarshal(content, &e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: we may want to check that the returned entries actually match
|
||||
// the package we asked about, so that the cache cannot be poisoned
|
||||
entries = append(entries, e...)
|
||||
|
||||
if hs.cache != nil {
|
||||
if err := hs.cache.WriteEntries(hs.dbName, p, e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sources []source
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
HTTPClient *http.Client
|
||||
HTTPCache Cache
|
||||
}
|
||||
|
||||
func NewClient(sources []string, opts Options) (*Client, error) {
|
||||
c := &Client{}
|
||||
for _, uri := range sources {
|
||||
// should parse the URI out here instead of in there
|
||||
switch {
|
||||
case strings.HasPrefix("http://", uri) || strings.HasPrefix("https://", uri):
|
||||
hs := &httpSource{url: uri}
|
||||
url, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hs.dbName = url.Hostname()
|
||||
if opts.HTTPCache != nil {
|
||||
hs.cache = opts.HTTPCache
|
||||
}
|
||||
if opts.HTTPClient != nil {
|
||||
hs.c = opts.HTTPClient
|
||||
} else {
|
||||
hs.c = new(http.Client)
|
||||
}
|
||||
c.sources = append(c.sources, hs)
|
||||
case strings.HasPrefix("file://", uri):
|
||||
url, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.sources = append(c.sources, &localSource{dir: url.Path})
|
||||
default:
|
||||
return nil, fmt.Errorf("source %q has unsupported scheme", uri)
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Client) Get(packages []string) ([]*osv.Entry, error) {
|
||||
var entries []*osv.Entry
|
||||
// probably should be parallelized
|
||||
for _, s := range c.sources {
|
||||
e, err := s.Get(packages)
|
||||
if err != nil {
|
||||
return nil, err // be failure tolerant?
|
||||
}
|
||||
entries = append(entries, e...)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"golang.org/x/vulndb/osv"
|
||||
"golang.org/x/vulndb/report"
|
||||
)
|
||||
|
||||
type IndexEntry struct {
|
||||
LastModified time.Time
|
||||
LastNewFinding time.Time
|
||||
}
|
||||
|
||||
func fail(why string) {
|
||||
fmt.Fprintln(os.Stderr, why)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// TODO: obviously not for the real world
|
||||
const dbURL = "https://team.git.corp.google.com/golang/vulndb/+/refs/heads/main/reports/"
|
||||
|
||||
func matchesCurrent(path string, new []osv.Entry) bool {
|
||||
var current []osv.Entry
|
||||
content, err := ioutil.ReadFile(path + ".json")
|
||||
if err != nil {
|
||||
fmt.Println("bad", err)
|
||||
return false
|
||||
}
|
||||
if err = json.Unmarshal(content, ¤t); err != nil {
|
||||
return false
|
||||
}
|
||||
return reflect.DeepEqual(current, new)
|
||||
}
|
||||
|
||||
func main() {
|
||||
tomlDir := flag.String("reports", "Directory containing toml reports", "")
|
||||
jsonDir := flag.String("out", "Directory to write JSON database to", "")
|
||||
flag.Parse()
|
||||
|
||||
tomlFiles, err := ioutil.ReadDir(*tomlDir)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("can't read %q: %s", *tomlDir, err))
|
||||
}
|
||||
|
||||
jsonVulns := map[string][]osv.Entry{}
|
||||
for _, f := range tomlFiles {
|
||||
if !strings.HasSuffix(f.Name(), ".toml") {
|
||||
continue
|
||||
}
|
||||
content, err := ioutil.ReadFile(filepath.Join(*tomlDir, f.Name()))
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("can't read %q: %s", f.Name(), err))
|
||||
}
|
||||
var vuln report.Report
|
||||
err = toml.Unmarshal(content, &vuln)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("unable to unmarshal %q: %s", f.Name(), err))
|
||||
}
|
||||
if err = vuln.Lint(); err != nil {
|
||||
fail(fmt.Sprintf("invalid vulnerability %q: %s", f.Name(), err))
|
||||
}
|
||||
|
||||
name := strings.TrimSuffix(filepath.Base(f.Name()), filepath.Ext(f.Name()))
|
||||
|
||||
for _, e := range osv.Generate(name, fmt.Sprintf("%s%s.toml", dbURL, name), vuln) {
|
||||
jsonVulns[e.Package.Name] = append(jsonVulns[e.Package.Name], e)
|
||||
}
|
||||
}
|
||||
|
||||
index := map[string]*IndexEntry{}
|
||||
if content, err := ioutil.ReadFile(filepath.Join(*jsonDir, "index.json")); err == nil {
|
||||
err = json.Unmarshal(content, &index)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to parse index: %s", err))
|
||||
}
|
||||
} else if err != nil && !os.IsNotExist(err) {
|
||||
fail(fmt.Sprintf("failed to read index %q: %s", filepath.Join(*jsonDir, "index.json"), err))
|
||||
}
|
||||
|
||||
// TODO(bracewell): I'm pretty sure the freshness stuff is basically
|
||||
// completely broken at the moment.
|
||||
now := time.Now()
|
||||
for path, v := range jsonVulns {
|
||||
outPath := filepath.Join(*jsonDir, path)
|
||||
content, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to marshal json: %s", err))
|
||||
}
|
||||
// fmt.Println("making", filepath.Dir(outPath))
|
||||
err = os.MkdirAll(filepath.Dir(outPath), 0700)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to create directory %q: %s", filepath.Dir(outPath), err))
|
||||
}
|
||||
// if there is already an index entry, only update the file
|
||||
// if the set of vulns differ from what is already on disk
|
||||
if _, ok := index[path]; ok && matchesCurrent(outPath, v) {
|
||||
// fmt.Println("skipping", outPath)
|
||||
continue
|
||||
}
|
||||
// fmt.Println("writing", outPath, string(content))
|
||||
err = ioutil.WriteFile(outPath+".json", content, 0644)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to write %q: %s", outPath+".json", err))
|
||||
}
|
||||
if index[path] == nil {
|
||||
index[path] = &IndexEntry{}
|
||||
}
|
||||
index[path].LastModified = now
|
||||
// also need to set the LastNewFinding, somewhat more complicated...
|
||||
}
|
||||
|
||||
indexJSON, err := json.Marshal(index)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to marshal index json: %s", err))
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(*jsonDir, "index.json"), indexJSON, 0644)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to write index: %s", err))
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package main
|
|
@ -0,0 +1,207 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"golang.org/x/vulndb/report"
|
||||
)
|
||||
|
||||
var indexTemplate = template.Must(template.New("index").Parse(`<html>
|
||||
<body>
|
||||
<h1>Go Vulnerability Database</h1>
|
||||
<ul>
|
||||
{{range .Vulns}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
|
||||
</ul>
|
||||
<h2>Packages</h2>
|
||||
<ul>
|
||||
{{range .Packages}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
|
||||
</ul>
|
||||
</body>
|
||||
</html>`))
|
||||
var packageIndexTemplate = template.Must(template.New("package-index").Parse(`<html>
|
||||
<body>
|
||||
<h1>{{.Name}} Vulnerabilities</h1>
|
||||
<ul>
|
||||
{{range .Vulns}}<li><a href="{{.}}.html">{{.}}</a></li>{{end}}
|
||||
</ul>
|
||||
</body>
|
||||
</html>`))
|
||||
var vulnTemplate = template.Must(template.New("vuln").Parse(`<html>
|
||||
<body>
|
||||
<h1>{{.Name}}</h1>
|
||||
{{if .Vuln.Severity}}<p><b>Severity: </b>{{.Vuln.Severity}}</p>{{end}}
|
||||
{{if .Vuln.OS}}<p><b>Affected Operating Systems: </b>{{.Vuln.OS}}</p>{{end}}
|
||||
{{if .Vuln.Arch}}<p><b>Affected Architectures: </b>{{.Vuln.Arch}}</p>{{end}}
|
||||
<p>{{.Vuln.Description}}</p>
|
||||
{{if .Vuln.Credit}}<p><b>Credit: </b>{{.Vuln.Credit}}</p>{{end}}
|
||||
{{if .Vuln.CVE}}<p><b>CVE: </b>{{.Vuln.CVE}}</p>{{end}}
|
||||
|
||||
<h2>Affected Packages</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Package</th>
|
||||
<th>Introduced</th>
|
||||
<th>Fixed</th>
|
||||
<th>Symbols</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>{{.Vuln.Package}}</code></td>
|
||||
{{if not .Vuln.Versions}}<td colspan="2" style="text-align: center">All available versions are vulnerable</td>{{else}}
|
||||
{{range .Vuln.Versions}}
|
||||
<td style="text-align: center">{{.Introduced}}</td>
|
||||
<td style="text-align: center">{{.Fixed}}</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<td>
|
||||
<ul>
|
||||
{{range .Vuln.Symbols}}<li><code>{{.}}</code></li>{{end}}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{{range .Vuln.AdditionalPackages}}
|
||||
<tr>
|
||||
<td><code>{{.Package}}</code></td>
|
||||
{{if not .Versions}}<td colspan="2" style="text-align: center">All available versions are vulnerable</td>{{else}}
|
||||
{{range .Versions}}
|
||||
<td style="text-align: center">{{.Introduced}}</td>
|
||||
<td style="text-align: center">{{.Fixed}}</td>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<td>
|
||||
<ul>
|
||||
{{range .Symbols}}<li><code>{{.}}</code></li>{{end}}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
|
||||
<h2>Context</h2>
|
||||
{{if .Vuln.Links.Commit}}<p><b>Commit: </b><a href="{{.Vuln.Links.Commit}}">{{.Vuln.Links.Commit}}</a></p>{{end}}
|
||||
{{if .Vuln.Links.PR}}<p><b>PR: </b><a href="{{.Vuln.Links.PR}}">{{.Vuln.Links.PR}}</a></p>{{end}}
|
||||
{{if .Vuln.Links.Context}}<p><b>Additional links:</b><ul>{{range .Vuln.Links.Context}}<li><a href="{{.}}">{{.}}</a></li>{{end}}</ul></p>{{end}}
|
||||
</body>
|
||||
</html>`))
|
||||
|
||||
func generateWebsite(vulns map[string]report.Report, htmlDir string) error {
|
||||
index := map[string][]string{}
|
||||
var vulnNames []string
|
||||
for name, vuln := range vulns {
|
||||
index[vuln.Package] = append(index[vuln.Package], name)
|
||||
for _, additional := range vuln.AdditionalPackages {
|
||||
index[additional.Package] = append(index[additional.Package], name)
|
||||
}
|
||||
vulnNames = append(vulnNames, name)
|
||||
|
||||
filename := filepath.Join(htmlDir, name+".html")
|
||||
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
err = vulnTemplate.Execute(file, struct {
|
||||
Name string
|
||||
Vuln report.Report
|
||||
}{
|
||||
Name: name,
|
||||
Vuln: vuln,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for p, vulns := range index {
|
||||
filename := filepath.Join(htmlDir, p+".html")
|
||||
if err := os.MkdirAll(strings.TrimSuffix(filename, filepath.Base(filename)), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
err = packageIndexTemplate.Execute(file, struct {
|
||||
Name string
|
||||
Vulns []string
|
||||
}{
|
||||
Name: p,
|
||||
Vulns: vulns,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var packageNames []string
|
||||
for name := range index {
|
||||
packageNames = append(packageNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(packageNames)
|
||||
sort.Strings(vulnNames)
|
||||
file, err := os.OpenFile(filepath.Join(htmlDir, "index.html"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
err = indexTemplate.Execute(file, struct {
|
||||
Vulns []string
|
||||
Packages []string
|
||||
}{
|
||||
Vulns: vulnNames,
|
||||
Packages: packageNames,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fail(why string) {
|
||||
fmt.Fprintln(os.Stderr, why)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
tomlDir := flag.String("reports", "Directory containing toml reports", "")
|
||||
htmlDir := flag.String("out", "Directory to write website to", "")
|
||||
flag.Parse()
|
||||
|
||||
htmlVulns := map[string]report.Report{}
|
||||
tomlFiles, err := ioutil.ReadDir(*tomlDir)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("can't read %q: %s", *tomlDir, err))
|
||||
}
|
||||
for _, f := range tomlFiles {
|
||||
if !strings.HasSuffix(f.Name(), ".toml") {
|
||||
continue
|
||||
}
|
||||
content, err := ioutil.ReadFile(f.Name())
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("can't read %q: %s", f.Name(), err))
|
||||
}
|
||||
var vuln report.Report
|
||||
err = toml.Unmarshal(content, &vuln)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("unable to unmarshal %q: %s", f.Name(), err))
|
||||
}
|
||||
if err = vuln.Lint(); err != nil {
|
||||
fail(fmt.Sprintf("invalid vulnerability %q: %s", f.Name(), err))
|
||||
}
|
||||
name := strings.TrimSuffix(filepath.Base(f.Name()), filepath.Ext(f.Name()))
|
||||
htmlVulns[name] = vuln
|
||||
}
|
||||
err = generateWebsite(htmlVulns, *htmlDir)
|
||||
if err != nil {
|
||||
fail(fmt.Sprintf("failed to generate website: %s", err))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"golang.org/x/vulndb/report"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "only expect a single argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to read %q: %s\n", os.Args[1], err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var vuln report.Report
|
||||
err = toml.Unmarshal(content, &vuln)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to parse %q: %s\n", os.Args[1], err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = vuln.Lint(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "invalid vulnerability file %q: %s\n", os.Args[1], err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"golang.org/x/vulndb/report"
|
||||
)
|
||||
|
||||
// Affects
|
||||
type Affects struct {
|
||||
Vendor Vendor `json:"vendor"`
|
||||
}
|
||||
|
||||
// CVEDataMeta
|
||||
type CVEDataMeta struct {
|
||||
ASSIGNER string `json:"ASSIGNER"`
|
||||
ID string `json:"ID"`
|
||||
STATE string `json:"STATE"`
|
||||
}
|
||||
|
||||
// Description
|
||||
type Description struct {
|
||||
DescriptionData []LangString `json:"description_data"`
|
||||
}
|
||||
|
||||
// LangString
|
||||
type LangString struct {
|
||||
Lang string `json:"lang"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Problemtype
|
||||
type Problemtype struct {
|
||||
ProblemtypeData []ProblemtypeDataItems `json:"problemtype_data"`
|
||||
}
|
||||
|
||||
// ProblemtypeDataItems
|
||||
type ProblemtypeDataItems struct {
|
||||
Description []LangString `json:"description"`
|
||||
}
|
||||
|
||||
type VersionData struct {
|
||||
VersionData []VersionDataItems `json:"version_data"`
|
||||
}
|
||||
|
||||
type ProductDataItem struct {
|
||||
ProductName string `json:"product_name"`
|
||||
Version VersionData `json:"version"`
|
||||
}
|
||||
|
||||
// Product
|
||||
type Product struct {
|
||||
ProductData []ProductDataItem `json:"product_data"`
|
||||
}
|
||||
|
||||
// Reference
|
||||
type Reference struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// References
|
||||
type References struct {
|
||||
ReferenceData []Reference `json:"reference_data"`
|
||||
}
|
||||
|
||||
// Vendor
|
||||
type Vendor struct {
|
||||
VendorData []VendorDataItems `json:"vendor_data"`
|
||||
}
|
||||
|
||||
// VendorDataItems
|
||||
type VendorDataItems struct {
|
||||
Product Product `json:"product"`
|
||||
VendorName string `json:"vendor_name"`
|
||||
}
|
||||
|
||||
// VersionDataItems
|
||||
type VersionDataItems struct {
|
||||
VersionValue string `json:"version_value"`
|
||||
VersionAffected string `json:"version_affected"`
|
||||
}
|
||||
|
||||
// CVE
|
||||
type CVE struct {
|
||||
DataType string `json:"data_type"`
|
||||
DataFormat string `json:"data_format"`
|
||||
DataVersion string `json:"data_version"`
|
||||
CVEDataMeta CVEDataMeta `json:"CVE_data_meta"`
|
||||
|
||||
Affects Affects `json:"affects"`
|
||||
Description Description `json:"description"`
|
||||
Problemtype Problemtype `json:"problemtype"`
|
||||
References References `json:"references"`
|
||||
}
|
||||
|
||||
func FromReport(report *report.Report) (*CVE, error) {
|
||||
if report.CVE != "" {
|
||||
return nil, errors.New("report has CVE ID is wrong section (should be in cve_metadata for self-issued CVEs)")
|
||||
}
|
||||
if report.CVEMetadata == nil {
|
||||
return nil, errors.New("report missing cve_metadata section")
|
||||
}
|
||||
if report.CVEMetadata.ID == "" {
|
||||
return nil, errors.New("report missing CVE ID")
|
||||
}
|
||||
|
||||
cve := &CVE{
|
||||
DataType: "CVE",
|
||||
DataFormat: "MITRE",
|
||||
DataVersion: "4.0",
|
||||
CVEDataMeta: CVEDataMeta{
|
||||
ID: report.CVEMetadata.ID,
|
||||
ASSIGNER: "security@golang.org",
|
||||
STATE: "PUBLIC",
|
||||
},
|
||||
|
||||
Description: Description{
|
||||
DescriptionData: []LangString{
|
||||
{
|
||||
Lang: "eng",
|
||||
Value: strings.TrimSuffix(report.CVEMetadata.Description, "\n"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Problemtype: Problemtype{
|
||||
ProblemtypeData: []ProblemtypeDataItems{
|
||||
{
|
||||
Description: []LangString{
|
||||
{
|
||||
Lang: "eng",
|
||||
Value: report.CVEMetadata.CWE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Affects: Affects{
|
||||
Vendor: Vendor{
|
||||
VendorData: []VendorDataItems{
|
||||
{
|
||||
VendorName: "n/a", // ???
|
||||
Product: Product{
|
||||
ProductData: []ProductDataItem{
|
||||
{
|
||||
ProductName: report.Package,
|
||||
Version: versionToVersion(report.Versions),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, additional := range report.AdditionalPackages {
|
||||
cve.Affects.Vendor.VendorData = append(cve.Affects.Vendor.VendorData, VendorDataItems{
|
||||
VendorName: "n/a",
|
||||
Product: Product{
|
||||
ProductData: []ProductDataItem{
|
||||
{
|
||||
ProductName: additional.Package,
|
||||
Version: versionToVersion(additional.Versions),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if report.Links.PR != "" {
|
||||
cve.References.ReferenceData = append(cve.References.ReferenceData, Reference{URL: report.Links.PR})
|
||||
}
|
||||
if report.Links.Commit != "" {
|
||||
cve.References.ReferenceData = append(cve.References.ReferenceData, Reference{URL: report.Links.Commit})
|
||||
}
|
||||
for _, url := range report.Links.Context {
|
||||
cve.References.ReferenceData = append(cve.References.ReferenceData, Reference{URL: url})
|
||||
}
|
||||
|
||||
return cve, nil
|
||||
}
|
||||
|
||||
func versionToVersion(versions []report.VersionRange) VersionData {
|
||||
vd := VersionData{}
|
||||
for _, vr := range versions {
|
||||
if vr.Introduced != "" {
|
||||
vd.VersionData = append(vd.VersionData, VersionDataItems{
|
||||
VersionValue: vr.Introduced,
|
||||
VersionAffected: ">=",
|
||||
})
|
||||
}
|
||||
if vr.Fixed != "" {
|
||||
vd.VersionData = append(vd.VersionData, VersionDataItems{
|
||||
VersionValue: vr.Fixed,
|
||||
VersionAffected: "<",
|
||||
})
|
||||
}
|
||||
}
|
||||
return vd
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprint(os.Stderr, "usage: report2cve report.toml")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
reportPath := os.Args[1]
|
||||
b, err := os.ReadFile(reportPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read %q: %s\n", reportPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var r report.Report
|
||||
if err = toml.Unmarshal(b, &r); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to parse %q: %s\n", reportPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cve, err := FromReport(&r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to generate CVE: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// We need to use an encoder so that it doesn't escape angle
|
||||
// brackets.
|
||||
e := json.NewEncoder(os.Stdout)
|
||||
e.SetEscapeHTML(false)
|
||||
e.SetIndent("", "\t")
|
||||
if err = e.Encode(cve); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to marshal CVE: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
The main section of the TOML contains high level information about the vulnerability
|
||||
|
||||
```
|
||||
package = "github.com/example/module"
|
||||
```
|
||||
**required** `package` contains the import path of the vulnerable module.
|
||||
|
||||
```
|
||||
description = """
|
||||
A remote attacker can craft a message which causes a panic via nil pointer dereference if the field
|
||||
[`Config.Parser`] is not initialized.
|
||||
"""
|
||||
```
|
||||
**required** `description` contains a textual description of the vulnerability and its impact. This field can contain a subset of markdown markup, used to link to godoc documentation for methods/types in the vulnerable module (and/or other modules).
|
||||
|
||||
```
|
||||
cve = "CVE-000-000"
|
||||
```
|
||||
**optional** `cve` contains a CVE number for the vulnerability, if one has been assigned.
|
||||
|
||||
```
|
||||
credit = "A. Reporter"
|
||||
```
|
||||
**optional** `credit` contains credit for the person/organization that discovered/reported the vulnerability.
|
||||
|
||||
```
|
||||
symbols = ["Parser.Parse"]
|
||||
```
|
||||
**optional** `symbols` contains an array of vulnerable symbols. If included only programs which use these symbols will be marked as vulnerable. If omitted any program which imports this module will be marked vulnerable.
|
||||
|
||||
```
|
||||
[[versions]]
|
||||
```
|
||||
The `versions` sections of the TOML contain information about when the vulnerability was introduced, and when it was fixed. If the vulnerability is fixed in multiple major versions, then the TOML should contain multiple `versions` sections. If omitted it is assumed that _every_ version of the module is vulnerable.
|
||||
|
||||
```
|
||||
introduced = "v0.0.1"
|
||||
```
|
||||
**optional** `introduced` contains the pseudo-version at which the vulnerability was introduced. If this field is omitted it is assumed that every version, from the initial commit, up to the `fixed` version is vulnerable.
|
||||
|
||||
```
|
||||
fixed = "v4.0.0-20190408214815-ec0a89a131e3"
|
||||
```
|
||||
**optional** `fixed` contains the pseudo-version at which the vulnerability was fixed. If this field is omitted it is assumed that every version since the `introduced` version is vulnerable.
|
||||
|
||||
```
|
||||
[[additional_packages]]
|
||||
```
|
||||
The `additional_packages` sections of the TOML contain information about additional packages impacted by the vulnerability. These may be other submodules which independently implement the same vulnerability, or alternate module names for the same module.
|
||||
|
||||
```
|
||||
package = "gopkg.in/vuln-mod"
|
||||
```
|
||||
**optional** `package` contains the import path of the additionally vulnerable module.
|
||||
|
||||
```
|
||||
symbols = ["Parser.Parse"]
|
||||
```
|
||||
**optional** `symbols` contains an array of vulnerable symbols. If included only programs which use these symbols will be marked as vulnerable. If omitted any program which imports this module will be marked vulnerable.
|
||||
|
||||
```
|
||||
[[additional_packages.versions]]
|
||||
```
|
||||
The `additional_packages.versions` sections contain version ranges for each additional package, following the same semantics as the `versions` section.
|
||||
|
||||
```
|
||||
[links]
|
||||
```
|
||||
The `links` section of the TOML contains further information about the vulnerability.
|
||||
|
||||
```
|
||||
commit = "https://github.com/example/module/commit/abcd"
|
||||
```
|
||||
**optional*** `commit` contains a link to the commit which fixes the vulnerability.
|
||||
|
||||
```
|
||||
pr = "https://github.com/example/module/pulls/123"
|
||||
```
|
||||
**optional** `pr` contains a link to the PR/CL which fixes the vulnerability.
|
||||
|
||||
```
|
||||
context = ["https://github.com/example/module/issues/50"]
|
||||
```
|
||||
**optional** `context` contains an array of additional links which provide additional context about the vulnerability, i.e. GitHub issues, vulnerability reports, etc.
|
||||
|
||||
# Example
|
||||
|
||||
```
|
||||
package = "github.com/example/module"
|
||||
description = """A description of the vulnerability present in this module.
|
||||
|
||||
The description can contain newlines, and a limited set of markup.
|
||||
"""
|
||||
cve = "CVE-2021-3185"
|
||||
credit = "John Smith"
|
||||
symbols = ["Type.MethodA", "MethodB"]
|
||||
|
||||
[[versions]]
|
||||
# The vulnerability is present in all versions up to
|
||||
# version v0.2.0
|
||||
fixed = "v0.2.0"
|
||||
|
||||
[[versions]]
|
||||
# The vulnerability is present in all versions since
|
||||
# version v0.2.5
|
||||
introduced = "v0.2.5
|
||||
|
||||
[[additional_packages]]
|
||||
# Major versions must be explicitly specified
|
||||
package = "github.com/example/module/v2"
|
||||
symbols = ["MethodB"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v2.5.0"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/example/module/v3"
|
||||
symbols = ["MethodB"]
|
||||
[[additional_packages.versions]]
|
||||
introduced = "v3.0.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/example/module/commit/aabbccdd"
|
||||
pr = "https://github.com/example/module/pull/10"
|
||||
context = [
|
||||
"https://www.openwall.com/lists/oss-security/2016/11/03/1",
|
||||
"https://github.com/example/module/advisories/1"
|
||||
]
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
module golang.org/x/vulndb
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/google/go-cmp v0.5.4
|
||||
golang.org/x/mod v0.4.1
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
prev=$(find reports/GO-* | tail -n 1 | sed -n 's/reports\/GO-[0-9]*-\([0-9]*\).toml/\1/p')
|
||||
new=$(printf "%04d" $(expr $prev + 1))
|
||||
year=$(date +"%Y")
|
||||
cp template reports/GO-$year-$new.toml
|
|
@ -0,0 +1,173 @@
|
|||
package osv
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
"golang.org/x/vulndb/report"
|
||||
)
|
||||
|
||||
type Severity int
|
||||
|
||||
const (
|
||||
SevNone Severity = iota
|
||||
SevLow
|
||||
SevMedium
|
||||
SevHigh
|
||||
SevCritical
|
||||
)
|
||||
|
||||
var strToSev = map[string]Severity{
|
||||
// "": SevNone,
|
||||
"low": SevLow,
|
||||
"medium": SevMedium,
|
||||
"high": SevHigh,
|
||||
"critical": SevCritical,
|
||||
}
|
||||
|
||||
type Type int
|
||||
|
||||
const (
|
||||
TypeUnspecified Type = iota
|
||||
TypeGit
|
||||
TypeSemver
|
||||
)
|
||||
|
||||
type Ecosystem string
|
||||
|
||||
const GoEcosystem Ecosystem = "go"
|
||||
|
||||
type Package struct {
|
||||
Name string
|
||||
Ecosystem Ecosystem
|
||||
}
|
||||
|
||||
type AffectsRange struct {
|
||||
Type Type
|
||||
Introduced string
|
||||
Fixed string
|
||||
}
|
||||
|
||||
func (ar AffectsRange) containsSemver(v string) bool {
|
||||
if ar.Type != TypeSemver {
|
||||
return false
|
||||
}
|
||||
|
||||
return (ar.Introduced == "" || semver.Compare(v, ar.Introduced) >= 0) &&
|
||||
(ar.Fixed == "" || semver.Compare(v, ar.Fixed) < 0)
|
||||
}
|
||||
|
||||
type Affects struct {
|
||||
Ranges []AffectsRange
|
||||
}
|
||||
|
||||
func generateAffects(versions []report.VersionRange) Affects {
|
||||
a := Affects{}
|
||||
for _, v := range versions {
|
||||
a.Ranges = append(a.Ranges, AffectsRange{
|
||||
Type: TypeSemver,
|
||||
Introduced: v.Introduced,
|
||||
Fixed: v.Fixed,
|
||||
})
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (a Affects) AffectsSemver(v string) bool {
|
||||
if len(a.Ranges) == 0 {
|
||||
// No ranges implies all versions are affected
|
||||
return true
|
||||
}
|
||||
var semverRangePresent bool
|
||||
for _, r := range a.Ranges {
|
||||
if r.Type != TypeSemver {
|
||||
continue
|
||||
}
|
||||
semverRangePresent = true
|
||||
if r.containsSemver(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// If there were no semver ranges present we
|
||||
// assume that all semvers are affected, similarly
|
||||
// to how to we assume all semvers are affected
|
||||
// if there are no ranges at all.
|
||||
return !semverRangePresent
|
||||
}
|
||||
|
||||
type GoSpecific struct {
|
||||
Symbols []string `json:",omitempty"`
|
||||
GOOS []string `json:",omitempty"`
|
||||
GOARCH []string `json:",omitempty"`
|
||||
URL string
|
||||
}
|
||||
|
||||
// Entry represents a OSV style JSON vulnerability database
|
||||
// entry
|
||||
type Entry struct {
|
||||
ID string
|
||||
Package Package
|
||||
Summary string
|
||||
Details string
|
||||
Severity Severity
|
||||
Affects Affects
|
||||
ReferenceURLs []string `json:"reference_urls,omitempty"`
|
||||
Aliases []string `json:",omitempty"`
|
||||
EcosystemSpecific GoSpecific `json:"ecosystem_specific,omitempty"`
|
||||
LastModified time.Time `json:"last_modified"`
|
||||
}
|
||||
|
||||
func Generate(id string, url string, r report.Report) []Entry {
|
||||
entry := Entry{
|
||||
ID: id,
|
||||
Package: Package{
|
||||
Name: r.Package,
|
||||
Ecosystem: GoEcosystem,
|
||||
},
|
||||
Summary: "", // TODO: think if we want to populate this in reports
|
||||
Details: r.Description,
|
||||
Affects: generateAffects(r.Versions),
|
||||
LastModified: time.Now(),
|
||||
EcosystemSpecific: GoSpecific{
|
||||
Symbols: r.Symbols,
|
||||
GOOS: r.OS,
|
||||
GOARCH: r.Arch,
|
||||
URL: url,
|
||||
},
|
||||
}
|
||||
|
||||
if r.Severity != "" {
|
||||
entry.Severity = strToSev[r.Severity]
|
||||
} else {
|
||||
// Default to medium or none?
|
||||
entry.Severity = SevMedium
|
||||
}
|
||||
|
||||
if r.Links.PR != "" {
|
||||
entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.PR)
|
||||
}
|
||||
if r.Links.Commit != "" {
|
||||
entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.Commit)
|
||||
}
|
||||
if r.Links.Context != nil {
|
||||
entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.Context...)
|
||||
}
|
||||
|
||||
if r.CVE != "" {
|
||||
entry.Aliases = []string{r.CVE}
|
||||
}
|
||||
|
||||
entries := []Entry{entry}
|
||||
|
||||
// It would be better if this was just a recursive thing probably
|
||||
for _, additional := range r.AdditionalPackages {
|
||||
entryCopy := entry
|
||||
entryCopy.Package.Name = additional.Package
|
||||
entryCopy.EcosystemSpecific.Symbols = additional.Symbols
|
||||
entryCopy.Affects = generateAffects(additional.Versions)
|
||||
|
||||
entries = append(entries, entryCopy)
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
package osv
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"golang.org/x/vulndb/report"
|
||||
)
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
r := report.Report{
|
||||
Package: "example.com/vulnerable/v2",
|
||||
AdditionalPackages: []struct {
|
||||
Package string
|
||||
Symbols []string
|
||||
Versions []report.VersionRange
|
||||
}{
|
||||
{
|
||||
Package: "example.com/vulnerable",
|
||||
Symbols: []string{"b", "A.b"},
|
||||
Versions: []report.VersionRange{
|
||||
{Fixed: "v2.1.1"},
|
||||
{Introduced: "v2.3.4", Fixed: "v2.3.5"},
|
||||
{Introduced: "v2.5.0"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Versions: []report.VersionRange{
|
||||
{Fixed: "v2.1.1"},
|
||||
{Introduced: "v2.3.4", Fixed: "v2.3.5"},
|
||||
{Introduced: "v2.5.0"},
|
||||
},
|
||||
Description: "It's a real bad one, I'll tell you that",
|
||||
Severity: "medium",
|
||||
CVE: "CVE-0000-0000",
|
||||
Credit: "ignored",
|
||||
Symbols: []string{"A", "B.b"},
|
||||
OS: []string{"windows"},
|
||||
Arch: []string{"arm64"},
|
||||
Links: struct {
|
||||
PR string
|
||||
Commit string
|
||||
Context []string
|
||||
}{
|
||||
PR: "pr",
|
||||
Commit: "commit",
|
||||
Context: []string{"issue-a", "issue-b"},
|
||||
},
|
||||
}
|
||||
|
||||
want := []Entry{
|
||||
{
|
||||
ID: "GO-1991-0001",
|
||||
Package: Package{
|
||||
Name: "example.com/vulnerable/v2",
|
||||
Ecosystem: "go",
|
||||
},
|
||||
Details: "It's a real bad one, I'll tell you that",
|
||||
Severity: 2,
|
||||
Affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Fixed: "v2.1.1",
|
||||
},
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Introduced: "v2.3.4",
|
||||
Fixed: "v2.3.5",
|
||||
},
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Introduced: "v2.5.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
ReferenceURLs: []string{
|
||||
"pr",
|
||||
"commit",
|
||||
"issue-a",
|
||||
"issue-b",
|
||||
},
|
||||
Aliases: []string{"CVE-0000-0000"},
|
||||
EcosystemSpecific: GoSpecific{
|
||||
Symbols: []string{"A", "B.b"},
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
URL: "https://vulns.golang.org/GO-1991-0001.html",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
ID: "GO-1991-0001",
|
||||
Package: Package{
|
||||
Name: "example.com/vulnerable",
|
||||
Ecosystem: "go",
|
||||
},
|
||||
Details: "It's a real bad one, I'll tell you that",
|
||||
Severity: 2,
|
||||
Affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Fixed: "v2.1.1",
|
||||
},
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Introduced: "v2.3.4",
|
||||
Fixed: "v2.3.5",
|
||||
},
|
||||
{
|
||||
Type: TypeSemver,
|
||||
Introduced: "v2.5.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
ReferenceURLs: []string{
|
||||
"pr",
|
||||
"commit",
|
||||
"issue-a",
|
||||
"issue-b",
|
||||
},
|
||||
Aliases: []string{"CVE-0000-0000"},
|
||||
EcosystemSpecific: GoSpecific{
|
||||
Symbols: []string{"b", "A.b"},
|
||||
GOOS: []string{"windows"},
|
||||
GOARCH: []string{"arm64"},
|
||||
URL: "https://vulns.golang.org/GO-1991-0001.html",
|
||||
},
|
||||
},
|
||||
}
|
||||
got := Generate("GO-1991-0001", "https://vulns.golang.org/GO-1991-0001.html", r)
|
||||
if diff := cmp.Diff(want, got, cmp.Comparer(func(_, _ time.Time) bool { return true })); diff != "" {
|
||||
t.Errorf("Generate returned unexpected result (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAffectsSemver(t *testing.T) {
|
||||
cases := []struct {
|
||||
affects Affects
|
||||
version string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
// empty Affects indicates everything is affected
|
||||
affects: Affects{},
|
||||
version: "v0.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v1.0.0 < v2.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Fixed: "v2.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v1.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v0.0.1 <= v1.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v0.0.1"},
|
||||
},
|
||||
},
|
||||
version: "v1.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v1.0.0 <= v1.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v1.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v1.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v1.0.0 <= v1.0.0 < v2.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v1.0.0", Fixed: "v2.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v1.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v0.0.1 <= v1.0.0 < v2.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v0.0.1", Fixed: "v2.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v1.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// v2.0.0 < v3.0.0
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v1.0.0", Fixed: "v2.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v3.0.0",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
// Multiple ranges
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeSemver, Introduced: "v1.0.0", Fixed: "v2.0.0"},
|
||||
{Type: TypeSemver, Introduced: "v3.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v3.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// Wrong type range
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeUnspecified, Introduced: "v3.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v3.0.0",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
// Semver ranges don't match
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeUnspecified, Introduced: "v3.0.0"},
|
||||
{Type: TypeSemver, Introduced: "v4.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v3.0.0",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
// Semver ranges do match
|
||||
affects: Affects{
|
||||
Ranges: []AffectsRange{
|
||||
{Type: TypeUnspecified, Introduced: "v3.0.0"},
|
||||
{Type: TypeSemver, Introduced: "v3.0.0"},
|
||||
},
|
||||
},
|
||||
version: "v3.0.0",
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
got := c.affects.AffectsSemver(c.version)
|
||||
if c.want != got {
|
||||
t.Errorf("%#v.AffectsSemver(%s): want %t, got %t", c.affects, c.version, c.want, got)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package report
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
type VersionRange struct {
|
||||
Introduced string
|
||||
Fixed string
|
||||
}
|
||||
|
||||
type Report struct {
|
||||
Package string
|
||||
// TODO: could also be GoToolchain, but we might want
|
||||
// this for other things?
|
||||
//
|
||||
// could we also automate this by just looking for
|
||||
// things prefixed with cmd/go?
|
||||
DoNotExport bool `json:"do_not_export"`
|
||||
// TODO: how does this interact with Versions etc?
|
||||
Stdlib bool `json:"stdlib"`
|
||||
// TODO: the most common usage of additional package should
|
||||
// really be replaced with 'aliases', we'll still need
|
||||
// additional packages for some cases, but it's too heavy
|
||||
// for most
|
||||
AdditionalPackages []struct {
|
||||
Package string
|
||||
Symbols []string
|
||||
Versions []VersionRange
|
||||
} `toml:"additional_packages"`
|
||||
Versions []VersionRange
|
||||
Description string
|
||||
Severity string
|
||||
CVE string
|
||||
Credit string
|
||||
Symbols []string
|
||||
OS []string
|
||||
Arch []string
|
||||
Links struct {
|
||||
PR string
|
||||
Commit string
|
||||
Context []string
|
||||
}
|
||||
CVEMetadata *struct {
|
||||
ID string
|
||||
CWE string
|
||||
Description string
|
||||
} `toml:"cve_metadata"`
|
||||
}
|
||||
|
||||
var cveRegex = regexp.MustCompile(`^CVE-\d{4}-\d{4,}$`)
|
||||
|
||||
func (vuln *Report) Lint() error {
|
||||
if vuln.Package == "" {
|
||||
return errors.New("missing package")
|
||||
}
|
||||
if err := module.CheckImportPath(vuln.Package); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, additionalPackage := range vuln.AdditionalPackages {
|
||||
if err := module.CheckImportPath(additionalPackage.Package); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, version := range vuln.Versions {
|
||||
if version.Introduced != "" {
|
||||
if !semver.IsValid(version.Introduced) {
|
||||
return fmt.Errorf("bad version.introduced")
|
||||
}
|
||||
if err := module.Check(vuln.Package, version.Introduced); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if version.Fixed != "" {
|
||||
if !semver.IsValid(version.Fixed) {
|
||||
return fmt.Errorf("bad version.fixed")
|
||||
}
|
||||
if err := module.Check(vuln.Package, version.Fixed); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vuln.Description == "" {
|
||||
return errors.New("missing description")
|
||||
}
|
||||
|
||||
sevs := map[string]bool{
|
||||
"low": true,
|
||||
"medium": true,
|
||||
"high": true,
|
||||
"critical": true,
|
||||
}
|
||||
// Could also just default to medium if not provided?
|
||||
// Need to document what the default case is and what factors lower
|
||||
// or raise the sev
|
||||
if vuln.Severity != "" && !sevs[vuln.Severity] {
|
||||
return fmt.Errorf("unknown severity %q", vuln.Severity)
|
||||
}
|
||||
|
||||
if vuln.CVE != "" && vuln.CVEMetadata.ID != "" {
|
||||
// TODO: may just want to use one of these? :shrug:
|
||||
return errors.New("only one of cve and cve_metadata.id should be present")
|
||||
}
|
||||
|
||||
if vuln.CVE != "" && !cveRegex.MatchString(vuln.CVE) {
|
||||
return fmt.Errorf("malformed CVE number: %s", vuln.CVE)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package = "github.com/gin-gonic/gin"
|
||||
|
||||
description = """
|
||||
The default [`Formatter`][LoggerConfig.Formatter] for the [`Logger`][] middleware
|
||||
(included in the [`Default`][] engine) allows attackers to inject arbitrary log
|
||||
entries by manipulating the request path.
|
||||
"""
|
||||
|
||||
credit = "@thinkerou <thinkerou@gmail.com>"
|
||||
|
||||
# Better static analysis: LoggerWithConfig called with nil conf.Formatter.
|
||||
# Test symbol inclusion by making a gin handler without Default or Logger.
|
||||
symbols = ["defaultLogFormatter"]
|
||||
|
||||
[[versions]]
|
||||
# v1.5.1 doesn't exist? not sure how `go mod` is picking this pseudoversion
|
||||
fixed = "v1.6.0"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/gin-gonic/gin/pull/2237"
|
||||
commit = "https://github.com/gin-gonic/gin/commit/a71af9c144f9579f6dbe945341c1df37aaf09c0d"
|
||||
|
||||
[cve_metadata]
|
||||
id = "CVE-XXX"
|
||||
description = """
|
||||
Unsanitized input in the default logger in github.com/gin-gonic/gin before v1.6.0
|
||||
allows remote attackers to inject arbitary log lines.
|
||||
"""
|
||||
cwe = "CWE-20: Improper Input Validation"
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/proglottis/gpgme"
|
||||
|
||||
cve = "CVE-2020-8945"
|
||||
|
||||
description = """
|
||||
The [`Data`][], [`Context`][], or [`Key`][] finalizers might run during or
|
||||
before GPGME operations, releasing the C structures as they are still in use,
|
||||
leading to crashes and potentially code execution through a use-after-free.
|
||||
"""
|
||||
|
||||
credit = "Ulrich Obergfell <uobergfe@redhat.com>"
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.1.1"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/proglottis/gpgme/pull/23"
|
||||
commit = "https://github.com/proglottis/gpgme/commit/92153bcb59bd2f511e502262c46c7bd660e21733"
|
|
@ -0,0 +1,26 @@
|
|||
package = "github.com/revel/revel"
|
||||
|
||||
description = """
|
||||
If the application accepts
|
||||
[slice parameters](https://revel.github.io/manual/parameters.html#slices), an
|
||||
attacker can cause the application to allocate large amounts of memory and
|
||||
crash by manipulating the request query.
|
||||
"""
|
||||
|
||||
credit = "@SYM01"
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/revel/revel/commit/d160ecb72207824005b19778594cbdc272e8a605"
|
||||
pr = "https://github.com/revel/revel/pull/1427"
|
||||
context = ["https://github.com/revel/revel/issues/1424"]
|
||||
|
||||
[cve_metadata]
|
||||
id = "CVE-XXXX-0002"
|
||||
description = """
|
||||
Unsanitized input in the query parser in github.com/revel/revel before v1.0.0
|
||||
allows remote attackers to cause resource exhaustion via memory allocation.
|
||||
"""
|
||||
cwe = "CWE-400: Uncontrolled Resource Consumption"
|
|
@ -0,0 +1,31 @@
|
|||
package = "github.com/nanobox-io/golang-nanoauth"
|
||||
|
||||
description = """
|
||||
If any of the `ListenAndServe` functions are called with an empty token,
|
||||
token authentication is disabled globally for all listeners.
|
||||
|
||||
Also, a minor timing side channel was present allowing attackers with
|
||||
very low latency and able to make a lot of requests to potentially
|
||||
recover the token.
|
||||
"""
|
||||
|
||||
credit = "@bouk"
|
||||
|
||||
symbols = ["Auth.ServerHTTP", "Auth.ListenAndServeTLS", "Auth.ListenAndServe"]
|
||||
|
||||
[[versions]]
|
||||
introduced = "v0.0.0-20160722212129-ac0cc4484ad4"
|
||||
fixed = "v0.0.0-20200131131040-063a3fb69896"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/nanobox-io/golang-nanoauth/pull/5"
|
||||
commit = "https://github.com/nanobox-io/golang-nanoauth/commit/063a3fb69896acf985759f0fe3851f15973993f3"
|
||||
|
||||
[cve_metadata]
|
||||
id = "CVE-XXXX-0003"
|
||||
description = """
|
||||
Authentication is globally bypassed in github.com/nanobox-io/golang-nanoauth between
|
||||
v0.0.0-20160722212129-ac0cc4484ad4 and v0.0.0-20200131131040-063a3fb69896 if ListenAndServe
|
||||
is called with an empty token.
|
||||
"""
|
||||
cwe = "CWE-305: Authentication Bypass by Primary Weakness"
|
|
@ -0,0 +1,24 @@
|
|||
package = "github.com/etcd-io/etcd/wal"
|
||||
|
||||
description = """
|
||||
Malformed WALs can be constructed such that [`WAL.ReadAll`][] can cause attempted
|
||||
out of bounds reads, or creation of arbitarily sized slices, which may be used as
|
||||
a DoS vector.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-15106"
|
||||
|
||||
credit = "Trail of Bits"
|
||||
|
||||
symbols = ["WAL.ReadAll"]
|
||||
|
||||
[[versions]]
|
||||
# Do we also need a way to indicate "fixed after this version, but also these specific
|
||||
# earlier point releases are also fixed"? In this case >= 3.4.10 is fixed, but so was
|
||||
# 3.3.23
|
||||
fixed = "v0.5.0-alpha.5.0.20200423152442-f4b650b51dc4"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/etcd-io/etcd/pull/11793"
|
||||
commit = "https://github.com/etcd-io/etcd/commit/f4b650b51dc4a53a8700700dc12e1242ac56ba07"
|
||||
context = ["https://github.com/etcd-io/etcd/blob/master/security/SECURITY_AUDIT.pdf"]
|
|
@ -0,0 +1,20 @@
|
|||
package = "github.com/miekg/dns"
|
||||
|
||||
description = """
|
||||
An attacker may prevent TCP connections to a [`Server`][] by opening
|
||||
a connection and leaving it idle, until the connection is closed by
|
||||
the server no other connections will be accepted.
|
||||
"""
|
||||
|
||||
cve = "CVE-2017-15133"
|
||||
|
||||
credit = "Pedro Sampaio"
|
||||
|
||||
symbols = ["Server.serveTCP"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.4-0.20180125103619-43913f2f4fbd"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/miekg/dns/pull/631"
|
||||
commit = "https://github.com/miekg/dns/commit/43913f2f4fbd7dcff930b8a809e709591e4dd79e"
|
|
@ -0,0 +1,21 @@
|
|||
package = "github.com/seccomp/libseccomp-golang"
|
||||
|
||||
description = """
|
||||
Filters containing rules with multiple syscall arguments are improperly
|
||||
constructed, such that all arguments are required to match rather than
|
||||
any of the arguments (AND is used rather than OR). These filters can be
|
||||
bypassed by only specifying a subset of the arguments due to this
|
||||
behavior.
|
||||
"""
|
||||
|
||||
cve = "CVE-2017-18367"
|
||||
|
||||
credit = "@ihac"
|
||||
|
||||
symbols = ["ScmpFilter.addRuleGeneric"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.9.1-0.20170424173420-06e7a29f36a3"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/seccomp/libseccomp-golang/commit/06e7a29f36a34b8cf419aeb87b979ee508e58f9e"
|
|
@ -0,0 +1,22 @@
|
|||
package = "github.com/miekg/dns"
|
||||
|
||||
description = """
|
||||
DNS message transaction IDs are generated using [`math/rand`] which
|
||||
makes them relatively predictable. This reduces the complexity
|
||||
of response spoofing attacks against DNS clients.
|
||||
"""
|
||||
|
||||
cve = "CVE-2019-19794"
|
||||
|
||||
symbols = ["id"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.25-0.20191211073109-8ebf2e419df7"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/miekg/dns/pull/1044"
|
||||
commit = "https://github.com/miekg/dns/commit/8ebf2e419df7857ac8919baa05248789a8ffbf33"
|
||||
context = [
|
||||
"https://github.com/miekg/dns/issues/1037",
|
||||
"https://github.com/miekg/dns/issues/1043"
|
||||
]
|
|
@ -0,0 +1,40 @@
|
|||
package = "github.com/square/go-jose/cipher"
|
||||
|
||||
arch = [
|
||||
"386",
|
||||
"arm",
|
||||
"armbe",
|
||||
"amd64p32",
|
||||
"mips",
|
||||
"mipsle",
|
||||
"mips64p32",
|
||||
"mips64p32le",
|
||||
"ppc",
|
||||
"riscv",
|
||||
"s390",
|
||||
"sparc"
|
||||
]
|
||||
|
||||
description = """
|
||||
On 32-bit platforms an attacker can manipulate a ciphertext encrypted with AES-CBC
|
||||
with HMAC such that they can control how large the input buffer is when computing
|
||||
the HMAC authentication tag. This can can allow a manipulated ciphertext to be
|
||||
verified as authentic, opening the door for padding oracle attacks.
|
||||
"""
|
||||
|
||||
cve = "CVE-2016-9123"
|
||||
|
||||
credit = "Quan Nguyen from Google's Information Security Engineering Team"
|
||||
|
||||
symbols = ["cbcAEAD.computeAuthTag"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20160903044734-789a4c4bd4c1"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/square/go-jose"
|
||||
symbols = ["JsonWebEncryption.Decrypt", "JsonWebEncryption.DecryptMulti"]
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/square/go-jose/commit/789a4c4bd4c118f7564954f441b29c153ccd6a96"
|
||||
context = ["https://www.openwall.com/lists/oss-security/2016/11/03/1"]
|
|
@ -0,0 +1,24 @@
|
|||
package = "github.com/square/go-jose/cipher"
|
||||
|
||||
description = """
|
||||
When using ECDH-ES an attacker can mount an invalid curve attack during
|
||||
decryption as the supplied public key is not checked to be on the same
|
||||
curve as the recievers private key.
|
||||
"""
|
||||
|
||||
cve = "CVE-2016-9121"
|
||||
|
||||
credit = "Quan Nguyen from Google's Information Security Engineering Team"
|
||||
|
||||
symbols = ["DeriveECDHES", "ecDecrypterSigner.decryptKey", "rawJsonWebKey.ecPublicKey"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20160831185616-c7581939a365"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/square/go-jose"
|
||||
symbols = ["JsonWebEncryption.Decrypt"]
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/square/go-jose/commit/c7581939a3656bb65e89d64da0a52364a33d2507"
|
||||
context = ["https://www.openwall.com/lists/oss-security/2016/11/03/1"]
|
|
@ -0,0 +1,22 @@
|
|||
package = "github.com/square/go-jose"
|
||||
|
||||
description = """
|
||||
When decrypting JsonWebEncryption objects with multiple recipients
|
||||
or JsonWebSignature objects with multiple signatures the Decrypt
|
||||
and Verify methods do not indicate which recipient or signature was
|
||||
valid. This may lead a caller to rely on protected headers from an
|
||||
invalid recipient or signature.
|
||||
"""
|
||||
|
||||
cve = "CVE-2016-9122"
|
||||
|
||||
credit = "Quan Nguyen from Google's Information Security Engineering Team"
|
||||
|
||||
symbols = ["JsonWebEncryption.Decrypt", "JsonWebSignature.Verify"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20160922232413-2c5656adca99"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/square/go-jose/commit/2c5656adca9909843c4ff50acf1d2cf8f32da7e6"
|
||||
context = ["https://www.openwall.com/lists/oss-security/2016/11/03/1"]
|
|
@ -0,0 +1,21 @@
|
|||
package = "golang.org/x/crypto/ssh"
|
||||
|
||||
description = """
|
||||
An attacker can craft an ssh-ed25519 or sk-ssh-ed25519@openssh.com public
|
||||
key, such that the library will panic when trying to verify a signature
|
||||
with it.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-9283"
|
||||
|
||||
credit = "Alex Gaynor, Fish in a Barrel"
|
||||
|
||||
symbols = ["parseED25519", "ed25519PublicKey.Verify", "parseSKEd25519", "skEd25519PublicKey.Verify", "NewPublicKey"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20200220183623-bac4c82f6975"
|
||||
|
||||
[links]
|
||||
pr = "https://go-review.googlesource.com/c/crypto/+/220357"
|
||||
commit = "https://github.com/golang/crypto/commit/bac4c82f69751a6dd76e702d54b3ceb88adab236"
|
||||
context = ["https://groups.google.com/g/golang-announce/c/3L45YRc91SY"]
|
|
@ -0,0 +1,24 @@
|
|||
package = "golang.org/x/crypto/ssh"
|
||||
|
||||
description = """
|
||||
By default host key verification is disabled which allows for
|
||||
man-in-the-middle attacks against SSH clients if
|
||||
[`ClientConfig.HostKeyCallback`] is not set.
|
||||
"""
|
||||
|
||||
cve = "CVE-2017-3204"
|
||||
|
||||
credit = "Phil Pennock"
|
||||
|
||||
symbols = ["NewClientConn"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20170330155735-e4e2799dd7aa"
|
||||
|
||||
[links]
|
||||
pr = "https://go-review.googlesource.com/38701"
|
||||
commit = "https://github.com/golang/crypto/commit/e4e2799dd7aab89f583e1d898300d96367750991"
|
||||
context = [
|
||||
"https://github.com/golang/go/issues/19767",
|
||||
"https://bridge.grumpy-troll.org/2017/04/golang-ssh-security/"
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
package = "golang.org/x/net/html"
|
||||
|
||||
description = """
|
||||
[`html.Parse`] does not properly handle "select" tags, which can lead
|
||||
to an infinite loop.
|
||||
"""
|
||||
cve = "CVE-2018-17846"
|
||||
|
||||
credit = "@tr3ee"
|
||||
|
||||
symbols = ["inSelectIM", "inSelectInTableIM"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20190125091013-d26f9f9a57f3"
|
||||
|
||||
[links]
|
||||
pr = "https://go-review.googlesource.com/c/137275"
|
||||
commit = "https://github.com/golang/net/commit/d26f9f9a57f3fab6a695bec0d84433c2c50f8bbf"
|
||||
context = ["https://github.com/golang/go/issues/27842"]
|
|
@ -0,0 +1,31 @@
|
|||
package = "golang.org/x/text/encoding/unicode"
|
||||
|
||||
description = """
|
||||
An attacker could provide a single byte to a [`UTF16`] decoder instantiated with
|
||||
[`UseBOM`] or [`ExpectBOM`] to trigger an infinite loop if the [`String`] function on
|
||||
the [`Decoder`] is called, or the [`Decoder`] is passed to [`transform.String`].
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-14040"
|
||||
|
||||
# This was reported by two people, once publicly and once
|
||||
# to the security team. Perhaps this should be an array
|
||||
# to capture multiple reporters?
|
||||
credit = "@abacabadabacaba" # also Anton Gyllenberg
|
||||
|
||||
symbols = ["utf16Decoder.Transform"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.3.3"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "golang.org/x/text/transform"
|
||||
symbols = ["Transform"]
|
||||
|
||||
[links]
|
||||
pr = "https://go-review.googlesource.com/c/text/+/238238"
|
||||
commit = "https://github.com/golang/text/commit/23ae387dee1f90d29a23c0e87ee0b46038fbed0e"
|
||||
context = [
|
||||
"https://github.com/golang/go/issues/39491",
|
||||
"https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0"
|
||||
]
|
|
@ -0,0 +1,28 @@
|
|||
package = "github.com/ulikunitz/xz"
|
||||
|
||||
description = """
|
||||
An attacker can construct a series of bytes such that calling
|
||||
[`Reader.Read`] on the bytes could cause an infinite loop.
|
||||
"""
|
||||
|
||||
credit = "@0xdecaf"
|
||||
|
||||
symbols = ["readUvarint"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.5.8"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/ulikunitz/xz/commit/69c6093c7b2397b923acf82cb378f55ab2652b9b"
|
||||
context = [
|
||||
"https://github.com/ulikunitz/xz/issues/35",
|
||||
"https://github.com/ulikunitz/xz/security/advisories/GHSA-25xm-hr59-7c27"
|
||||
]
|
||||
|
||||
[cve_metadata]
|
||||
id = "CVE-XXXX-0004"
|
||||
description = """
|
||||
Integer overflow in github.com/ulikunitz/xz before v0.5.8 allows attackers
|
||||
to cause denial of service via maliciously crafted input.
|
||||
"""
|
||||
cwe = "CWE-190: Integer Overflow or Wraparound"
|
|
@ -0,0 +1,28 @@
|
|||
package = "github.com/dgrijalva/jwt-go"
|
||||
|
||||
description = """
|
||||
If a JWT contains an audience claim with an array of strings, rather
|
||||
than a single string, and `MapClaims.VerifyAudience` is called with
|
||||
`req` set to `false` then audience verification will be bypassed,
|
||||
allowing an invalid set of audiences to be provided.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-26160"
|
||||
|
||||
credit = "@christopher-wong"
|
||||
|
||||
symbols = ["MapClaims.VerifyAudience"]
|
||||
|
||||
[[versions]]
|
||||
introduced = "v0.0.0-20150717181359-44718f8a89b0"
|
||||
fixed = "v4.0.0-20190408214815-ec0a89a131e"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/dgrijalva/jwt-go/v4"
|
||||
symbols = ["MapClaims.VerifyAudience"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v4.0.0-20190408214815-ec0a89a131e3"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/dgrijalva/jwt-go/commit/ec0a89a131e3e8567adcb21254a5cd20a70ea4ab"
|
||||
context = ["https://github.com/dgrijalva/jwt-go/issues/422"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/satori/go.uuid"
|
||||
|
||||
description = """
|
||||
UUIDs generated using [`NewV1`] and [`NewV4`] may not read the expected
|
||||
number of random bytes. These UUIDs may contain a significantly smaller
|
||||
amount of entropy than expected, possibly leading to collisions.
|
||||
"""
|
||||
|
||||
credit = "@josselin-c"
|
||||
|
||||
symbols = ["NewV4", "rfc4122Generator.getClockSequence", "rfc4122Generator.getHardwareAddr"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.2.1-0.20181016170032-d91630c85102"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/satori/go.uuid/pull/75"
|
||||
commit = "https://github.com/satori/go.uuid/commit/d91630c8510268e75203009fe7daf2b8e1d60c45"
|
||||
context = ["https://github.com/satori/go.uuid/issues/73"]
|
|
@ -0,0 +1,21 @@
|
|||
package = "github.com/gorilla/websocket"
|
||||
|
||||
description = """
|
||||
An attacker can craft malicious WebSocket frames that cause an integer
|
||||
overflow in a variable which tracks the number of bytes remaining. This
|
||||
can cause the server or client to get stuck attempting to read frames
|
||||
in a loop.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-27813"
|
||||
|
||||
credit = "Max Justicz"
|
||||
|
||||
symbols = ["Conn.advanceFrame", "messageReader.Read"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.4.1"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/gorilla/websocket/pull/537"
|
||||
commit = "https://github.com/gorilla/websocket/commit/5b740c29263eb386f33f265561c8262522f19d37"
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/gorilla/handlers"
|
||||
|
||||
description = """
|
||||
Usage of the [`CORS`] handler may apply improper CORS headers, allowing
|
||||
the requester to explicitly control the value of the Access-Control-Allow-Origin
|
||||
header, which bypasses the expected behavior of the Same Origin Policy.
|
||||
"""
|
||||
|
||||
credit = "Evan J Johnson"
|
||||
|
||||
symbols = ["cors.ServeHTTP"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.3.0"
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/gorilla/handlers/pull/116"
|
||||
commit = "https://github.com/gorilla/handlers/commit/90663712d74cb411cbef281bc1e08c19d1a76145"
|
|
@ -0,0 +1,20 @@
|
|||
package = "github.com/gogits/gogs"
|
||||
|
||||
description = """
|
||||
Multiple methods are vulnerable to SQL injection attacks as unsanitized
|
||||
user input is used to construct SQL statements.
|
||||
"""
|
||||
|
||||
cve = "CVE-2014-8681"
|
||||
|
||||
credit = "Pascal Turbing and Jiahua (Joe) Chen"
|
||||
|
||||
symbols = ["GetIssues", "SearchRepositoryByName", "SearchUserByName"]
|
||||
|
||||
[[versions]]
|
||||
introduced = "v0.3.1-9-g49dc57e"
|
||||
fixed = "v0.5.8"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/gogs/gogs/commit/83283bca4cb4e0f4ec48a28af680f0d88db3d2c8"
|
||||
context = ["https://seclists.org/fulldisclosure/2014/Nov/31"]
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/cloudflare/golz4"
|
||||
|
||||
description = """
|
||||
LZ4 bindings used a deprecated C API that is vulnerable to
|
||||
memory corruption which could lead to arbitrary code execution
|
||||
if successfully exploited.
|
||||
"""
|
||||
|
||||
credit = "Don A. Bailey"
|
||||
|
||||
symbols = ["Uncompress"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20140711154735-199f5f787806"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/cloudflare/golz4/commit/199f5f7878062ca17a98e079f2dbe1205e2ed898"
|
||||
context = ["https://github.com/cloudflare/golz4/issues/5"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/robbert229/jwt"
|
||||
|
||||
description = """
|
||||
[`Validate`] used non-constant time string comparison to
|
||||
compare a provided HMAC against expected HMAC, providing
|
||||
a timing side-channel.
|
||||
"""
|
||||
|
||||
symbols = ["Algorithm.validateSignature"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20170426191122-ca1404ee6e83"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/robbert229/jwt/commit/ca1404ee6e83fcbafb66b09ed0d543850a15b654"
|
||||
context = ["https://github.com/robbert229/jwt/issues/12"]
|
|
@ -0,0 +1,20 @@
|
|||
package = "github.com/btcsuite/go-socks/socks"
|
||||
|
||||
description = """
|
||||
The RemoteAddr and LocalAddr methods on the returned net.Conn may
|
||||
call themselves, leading to an infinite loop.
|
||||
"""
|
||||
|
||||
symbols = ["proxiedConn.LocalAddr", "proxiedConn.RemoteAddr"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20130808000456-233bccbb1abe"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/btcsuitereleases/go-socks/socks"
|
||||
symbols = ["proxiedConn.LocalAddr", "proxiedConn.RemoteAddr"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v0.0.0-20130808000456-233bccbb1abe"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/btcsuite/go-socks/commit/233bccbb1abe02f05750f7ace66f5bffdb13defc"
|
|
@ -0,0 +1,22 @@
|
|||
package = "github.com/cloudfoundry/archiver"
|
||||
|
||||
description = """
|
||||
Malicious Zip and Tar archives can be crafted that contain relative
|
||||
file paths, such that arbitary files outside of the target directory
|
||||
may be overwritten.
|
||||
"""
|
||||
|
||||
symbols = ["tgzExtractor.Extract", "zipExtractor.Extract"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20180523222229-09b5706aa936"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "code.cloudfoundry.org/archiver"
|
||||
symbols = ["tgzExtractor.Extract", "zipExtractor.Extract"]
|
||||
[[versions]]
|
||||
fixed = "v0.0.0-20180523222229-09b5706aa936"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/cloudfoundry/archiver/commit/09b5706aa9367972c09144a450bb4523049ee840"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/openshift/source-to-image/pkg/tar"
|
||||
|
||||
description = """
|
||||
Malicious Zip and Tar archives can be crafted that contain relative
|
||||
file paths, such that arbitary files outside of the target directory
|
||||
may be overwritten.
|
||||
"""
|
||||
|
||||
cve = "CVE-2018-1103"
|
||||
|
||||
symbols = ["stiTar.ExtractTarStreamFromTarReader", "stiTar.extractLink", "New"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.10-0.20180427153919-f5cbcbc5cc6f"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/openshift/source-to-image/commit/f5cbcbc5cc6f8cc2f479a7302443bea407a700cb"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,22 @@
|
|||
package = "github.com/google/fscrypt/pam"
|
||||
|
||||
description = """
|
||||
After dropping and then elevating process privileges euid, guid, and groups
|
||||
were not properly restored to their original values, allowing an unprivileged
|
||||
user to gain membership in the root group.
|
||||
"""
|
||||
|
||||
cve = "CVE-2018-6558"
|
||||
|
||||
symbols = ["NewHandle", "SetProcessPrivileges", "Handle.StopAsPamUser"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.2.4"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/google/fscrypt/security"
|
||||
symbols = ["UserKeyringID"]
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/google/fscrypt/commit/3022c1603d968c22f147b4a2c49c4637dd1be91b"
|
||||
context = ["https://github.com/google/fscrypt/issues/77"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/miekg/dns"
|
||||
|
||||
description = """
|
||||
An attacker can craft a malicious DNS zone file which will cause
|
||||
[`ParseZone`] to panic due to a nil pointer dereference.
|
||||
"""
|
||||
|
||||
cve = "CVE-2018-17419"
|
||||
|
||||
credit = "@tr3ee"
|
||||
|
||||
symbols = ["setTA"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.10"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/miekg/dns/commit/501e858f679edecd4a38a86317ce50271014a80d"
|
||||
context = ["https://github.com/miekg/dns/issues/742"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/gin-gonic/gin"
|
||||
|
||||
description = """
|
||||
An attacker can spoof their source IP address by setting the X-Forwarded-For
|
||||
HTTP header to an arbitrary value.
|
||||
"""
|
||||
|
||||
credit = "@nl5887"
|
||||
|
||||
symbols = ["Context.ClientIP"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.5.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/gin-gonic/gin/commit/0099840c98ae1473c5ff0f18bc93a8e13ceed829"
|
|
@ -0,0 +1,21 @@
|
|||
package = "github.com/go-gorm/gorm"
|
||||
|
||||
description = """
|
||||
Multiple methods are vulnerable to blind SQL injection attacks
|
||||
due to constructing SQL statements using unsantized user input.
|
||||
"""
|
||||
|
||||
credit = "@wahyuhadi"
|
||||
|
||||
symbols = ["Scope.buildCondition"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.2.0"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/jinzhu/gorm"
|
||||
symbols = ["Scope.buildCondition"]
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/go-gorm/gorm/commit/836fb2c19d84dac7b0272958dfb9af7cf0d0ade4"
|
||||
context = ["https://github.com/go-gorm/gorm/issues/2517"]
|
|
@ -0,0 +1,15 @@
|
|||
package = "github.com/proglottis/gpgme"
|
||||
|
||||
description = """
|
||||
The C bindings for the GPGME contain a number of use-after-free issues
|
||||
which may lead to memory corruption and possible code execution.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-8945"
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.1.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/proglottis/gpgme/commit/92153bcb59bd2f511e502262c46c7bd660e21733"
|
||||
context = ["https://bugzilla.redhat.com/show_bug.cgi?id=1795838"]
|
|
@ -0,0 +1,37 @@
|
|||
package = "github.com/goadesign/goa"
|
||||
|
||||
description = """
|
||||
[`Controller.FileHandler`] allows for directory traversal attacks due
|
||||
to usage of unsanitized user input.
|
||||
"""
|
||||
|
||||
credit = "@christi3k"
|
||||
|
||||
symbols = ["Controller.FileHandler"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.4.3"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/goadesign/goa/v2"
|
||||
symbols = ["Controller.FileHandler"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v2.0.10"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/goadesign/goa/v3"
|
||||
symbols = ["Controller.FileHandler"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v3.0.9"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/goadesign/goa/commit/70b5a199d0f813d74423993832c424e1fc73fb39"
|
||||
pr = "https://github.com/goadesign/goa/pull/2388"
|
||||
|
||||
[cve_metadata]
|
||||
id = "CVE-XXXX-0012"
|
||||
description = """
|
||||
Improper path santiziation in github.com/goadesign/goa before v3.0.9, v2.0.10, or
|
||||
v1.4.3 allow remote attackers to read files outside of the intended directory.
|
||||
"""
|
||||
cwe = "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')"
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/go-aah/aah"
|
||||
|
||||
description = """
|
||||
[`HTTPEngine.Handle`] allows for directory traversal attacks due
|
||||
to usage of unsanitized user input.
|
||||
"""
|
||||
|
||||
credit = "@snyff"
|
||||
|
||||
symbols = ["HTTPEngine.Handle"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.12.4"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/go-aah/aah/commit/881dc9f71d1f7a4e8a9a39df9c5c081d3a2da1ec"
|
||||
pr = "https://github.com/go-aah/aah/pull/267"
|
||||
context = ["https://github.com/go-aah/aah/issues/266"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/artdarek/go-unzip"
|
||||
|
||||
description = """
|
||||
Malicious Zip archives can be crafted that contain relative file paths,
|
||||
such that arbitary files outside of the target directory may be overwritten.
|
||||
"""
|
||||
|
||||
symbols = ["Unzip.Extract"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/artdarek/go-unzip/commit/4975cbe0a719dc50b12da8585f1f207c82f7dfe0"
|
||||
pr = "https://github.com/artdarek/go-unzip/pull/2"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/yi-ge/unzip"
|
||||
|
||||
description = """
|
||||
Malicious Zip archives can be crafted that contain relative file paths,
|
||||
such that arbitary files outside of the target directory may be overwritten.
|
||||
"""
|
||||
|
||||
symbols = ["Unzip.Extract"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.3-0.20200308084313-2adbaa4891b9"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/yi-ge/unzip/commit/2adbaa4891b9690853ef10216189189f5ad7dc73"
|
||||
pr = "https://github.com/yi-ge/unzip/pull/1"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,24 @@
|
|||
package = "gopkg.in/yaml.v2"
|
||||
|
||||
description = """
|
||||
An attacker can craft malicious YAML which will consume significant
|
||||
system resources when Unmarshalled.
|
||||
"""
|
||||
|
||||
cve = "CVE-2019-11254"
|
||||
|
||||
symbols = ["yaml_parser_fetch_more_tokens"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v2.2.8"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/go-yaml/yaml"
|
||||
symbols = ["yaml_parser_fetch_more_tokens"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v2.2.8"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/go-yaml/yaml/commit/53403b58ad1b561927d19068c655246f2db79d48"
|
||||
pr = "https://github.com/go-yaml/yaml/pull/555"
|
||||
context = ["https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18496"]
|
|
@ -0,0 +1,17 @@
|
|||
package = "github.com/tendermint/tendermint/rpc/client"
|
||||
|
||||
description = """
|
||||
A malicious server can exploit support for gzip compression to force
|
||||
the client to consume significant system resources, leading to crashes.
|
||||
"""
|
||||
|
||||
credit = "@guagualvcha"
|
||||
|
||||
symbols = ["makeHTTPClient"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.31.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/tendermint/tendermint/commit/03085c2da23b179c4a51f59a03cb40aa4e85a613"
|
||||
pr = "https://github.com/tendermint/tendermint/pull/3430"
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/pion/dtls"
|
||||
|
||||
description = """
|
||||
An attacker can craft records that allow the processing of arbitrary
|
||||
unencrypted application data at any point after the initial handshake
|
||||
is completed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2019-20786"
|
||||
|
||||
symbols = ["Conn.handleIncomingPacket"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.5.2"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/pion/dtls/commit/fd73a5df2ff0e1fb6ae6a51e2777d7a16cc4f4e0"
|
||||
pr = "https://github.com/pion/dtls/pull/128"
|
||||
context = ["https://www.usenix.org/system/files/sec20fall_fiterau-brostean_prepub.pdf"]
|
|
@ -0,0 +1,26 @@
|
|||
package = "github.com/go-macaron/macaron"
|
||||
|
||||
description = """
|
||||
An attacker can craft a malicious URL which will cause the server
|
||||
to redirect a user to a secondary URL.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-12666"
|
||||
|
||||
credit = "@ev0A"
|
||||
|
||||
symbols = ["staticHandler"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.3.7"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "gopkg.in/macaron.v1"
|
||||
symbols = ["staticHandler"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v1.3.7"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/go-macaron/macaron/commit/addc7461c3a90a040e79aa75bfd245107a210245"
|
||||
pr = "https://github.com/go-macaron/macaron/pull/199"
|
||||
context = ["https://github.com/go-macaron/macaron/issues/198"]
|
|
@ -0,0 +1,11 @@
|
|||
package = "github.com/shiyanhui/dht"
|
||||
|
||||
description = """
|
||||
A malicious peer can craft messages which will cause panics due to
|
||||
unchecked type assertions.
|
||||
"""
|
||||
|
||||
credit = "@hMihaiDavid"
|
||||
|
||||
[links]
|
||||
context = ["https://github.com/shiyanhui/dht/issues/57"]
|
|
@ -0,0 +1,24 @@
|
|||
package = "github.com/unknwon/cae/tz"
|
||||
|
||||
description = """
|
||||
Malicious Zip and Tar archives can be crafted that contain relative
|
||||
file paths, such that arbitary files outside of the target directory
|
||||
may be overwritten.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-7668"
|
||||
|
||||
symbols = ["TzArchive.syncFiles", "TzArchive.ExtractToFunc"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.0.1"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/unknwon/cae/zip"
|
||||
symbols = ["ZipArchive.Open", "ZipArchive.ExtractToFunc"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v1.0.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/unknwon/cae/commit/07971c00a1bfd9dc171c3ad0bfab5b67c2287e11"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/sassoftware/go-rpmutils/cpio"
|
||||
|
||||
description = """
|
||||
Malicious RPM archives can be crafted that contain relative
|
||||
file paths, such that arbitary files outside of the target directory
|
||||
may be overwritten.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-7667"
|
||||
|
||||
symbols = ["Extract"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.1.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/sassoftware/go-rpmutils/commit/a64058cf21b8aada501bba923c9aab66fb6febf0"
|
||||
context = ["https://snyk.io/research/zip-slip-vulnerability"]
|
|
@ -0,0 +1,26 @@
|
|||
package = "github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
|
||||
description = """
|
||||
Where the server is listening for multiple SNI names an attacker can
|
||||
complete a TLS handshake for a host name that does not require TLS
|
||||
client authentication and then send HTTP requests for a host name that
|
||||
does require TLS client authentication, thereby bypassing those checks.
|
||||
"""
|
||||
|
||||
cve = "CVE-2018-21246"
|
||||
|
||||
symbols = ["httpContext.MakeServers", "Server.serveHTTP", "assertConfigsCompatible"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.10.13"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
symbols = ["httpContext.MakeServers", "Server.serveHTTP", "assertConfigsCompatible"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v0.10.13"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/caddyserver/caddy/commit/4d9ee000c8d2cbcdd8284007c1e0f2da7bc3c7c3"
|
||||
pr = "https://github.com/caddyserver/caddy/pull/2099"
|
||||
context = ["https://bugs.gentoo.org/715214"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/beego/beego/session"
|
||||
|
||||
description = """
|
||||
An attacker can craft a malicious URL which lead to XSS due to
|
||||
usage of unsantized user controlled URL parameters.
|
||||
"""
|
||||
|
||||
credit = "@Kevil-hui"
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.12.2"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/beego/beego/commit/6eeea141d885c16c2a01349d57da62c6379a45a2"
|
||||
pr = "https://github.com/beego/beego/pull/4018"
|
||||
context = ["https://github.com/beego/beego/issues/3983"]
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/dinever/golf"
|
||||
|
||||
description = """
|
||||
CSRF tokens are generated using math/rand, making predicting their values
|
||||
relatively trivial.
|
||||
"""
|
||||
|
||||
credit = "@elithrar"
|
||||
|
||||
symbols = ["randomBytes"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.3.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/dinever/golf/commit/3776f338be48b5bc5e8cf9faff7851fc52a3f1fe"
|
||||
pr = "https://github.com/dinever/golf/pull/24"
|
||||
context = ["https://github.com/dinever/golf/issues/20"]
|
|
@ -0,0 +1,24 @@
|
|||
package = "github.com/russellhaering/goxmldsig"
|
||||
|
||||
description = """
|
||||
An attacker can craft a malformed XML Digital Signature which when
|
||||
validated causes a panic due to nil pointer deference.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-7711"
|
||||
|
||||
credit = "@stevenjohnstone"
|
||||
|
||||
symbols = ["ValidationContext.validateSignature"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.0"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/russellhaering/gosaml2"
|
||||
symbols = ["SAMLServiceProvider.validateAssertionSignatures"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v0.6.0"
|
||||
|
||||
[links]
|
||||
context = ["https://github.com/russellhaering/goxmldsig/issues/48", "https://github.com/russellhaering/gosaml2/issues/59"]
|
|
@ -0,0 +1,12 @@
|
|||
package = "github.com/RobotsAndPencils/go-saml"
|
||||
|
||||
description = """
|
||||
XML Digital Signatures generated and validated using this package use
|
||||
SHA-1, as such an attacker may be able to craft input which cause
|
||||
hash collisions.
|
||||
"""
|
||||
|
||||
symbols = ["AuthnRequest.Validate", "NewAuthnRequest", "NewSignedResponse"]
|
||||
|
||||
[links]
|
||||
context = ["https://github.com/RobotsAndPencils/go-saml/pull/38"]
|
|
@ -0,0 +1,20 @@
|
|||
package = "github.com/antchfx/xmlquery"
|
||||
|
||||
description = """
|
||||
[`LoadURL`] does not check the Content-Type of loaded resources,
|
||||
which can cause a panic due to nil pointer deference if the loaded
|
||||
resource is not XML.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-25614"
|
||||
|
||||
credit = "@dwisiswant0"
|
||||
|
||||
symbols = ["LoadURL"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.3.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/antchfx/xmlquery/commit/5648b2f39e8d5d3fc903c45a4f1274829df71821"
|
||||
context = ["https://github.com/antchfx/xmlquery/issues/39"]
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/justinas/nosurf"
|
||||
|
||||
description = """
|
||||
[`VerifyToken`] can be bypassed if the expected token contains malformed Base64.
|
||||
"""
|
||||
|
||||
credit = "@aeneasr"
|
||||
|
||||
symbols = ["VerifyToken", "verifyToken"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/justinas/nosurf/commit/4d86df7a4affa1fa50ab39fb09aac56c3ce9c314"
|
||||
pr = "https://github.com/justinas/nosurf/pull/60"
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/russellhaering/goxmldsig"
|
||||
|
||||
description = """
|
||||
An attacker can craft an XML file which will cause signature verification
|
||||
to be entirely bypassed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-15216"
|
||||
|
||||
credit = "@jupenur"
|
||||
|
||||
symbols = ["ValidationContext.findSignature"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/russellhaering/goxmldsig/commit/f6188febf0c29d7ffe26a0436212b19cb9615e64"
|
||||
context = ["https://github.com/russellhaering/goxmldsig/security/advisories/GHSA-q547-gmf8-8jr7"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/labstack/echo/v4"
|
||||
|
||||
description = """
|
||||
On Windows the static route handler does not properly santize the
|
||||
request path, allowing for directory traversal.
|
||||
"""
|
||||
|
||||
credit = "@little-cui (Apache ServiceComb)"
|
||||
|
||||
symbols = ["common.static"]
|
||||
|
||||
os = ["windows"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v4.1.18-0.20201215153152-4422e3b66b9f"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/labstack/echo/commit/4422e3b66b9fd498ed1ae1d0242d660d0ed3faaa"
|
||||
pr = "https://github.com/labstack/echo/pull/1718"
|
|
@ -0,0 +1,16 @@
|
|||
package = "github.com/gin-gonic/gin"
|
||||
|
||||
description = """
|
||||
When used without an internet facing proxy, an adversary can spoof
|
||||
their IP address by setting the X-Forwarded-For header.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-28483"
|
||||
|
||||
credit = "@sorenh"
|
||||
|
||||
symbols = ["Context.ClientIP"]
|
||||
|
||||
[links]
|
||||
pr = "https://github.com/gin-gonic/gin/pull/2632"
|
||||
context = ["https://github.com/gin-gonic/gin/pull/2474"]
|
|
@ -0,0 +1,14 @@
|
|||
package = "github.com/gogo/protobuf"
|
||||
|
||||
description = """
|
||||
Generated Unmarshal methods do not include proper index bounds validation,
|
||||
allowing a maliciously crafted message to cause an out-of-bounds panic.
|
||||
"""
|
||||
|
||||
cve = "CVE-2021-3121"
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.3.2"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/gogo/protobuf/commit/b03c65ea87cdc3521ede29f62fe3ce239267c1bc"
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/tidwall/gjson"
|
||||
|
||||
description = """
|
||||
Maliciously crafted JSON messages can cause an out-of-bounds panic.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-36067"
|
||||
|
||||
credit = "@toptotu"
|
||||
|
||||
symbols = ["unwrap"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.6.6"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/tidwall/gjson/commit/bf4efcb3c18d1825b2988603dea5909140a5302b"
|
||||
context = ["https://github.com/tidwall/gjson/issues/196"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/dexidp/dex/connector/saml/v2"
|
||||
|
||||
description = """
|
||||
An XML message can be maliciously crafted such that signature
|
||||
verification is bypassed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-15216"
|
||||
|
||||
credit = "Juho Nurminen (Mattermost)"
|
||||
|
||||
symbols = ["provider.HandlePOST"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v2.27.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/dexidp/dex/commit/324b1c886b407594196113a3dbddebe38eecd4e8"
|
||||
context = ["https://github.com/dexidp/dex/security/advisories/GHSA-m9hp-7r99-94h5"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/russellhaering/goxmldsig"
|
||||
|
||||
description = """
|
||||
An XML message can be maliciously crafted such that signature
|
||||
verification is bypassed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-15216"
|
||||
|
||||
credit = "Juho Nurminen (Mattermost)"
|
||||
|
||||
symbols = ["ValidationContext.findSignature"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/dexidp/dex/commit/324b1c886b407594196113a3dbddebe38eecd4e8"
|
||||
context = ["https://github.com/russellhaering/goxmldsig/security/advisories/GHSA-q547-gmf8-8jr7"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/buger/jsonparser"
|
||||
|
||||
description = """
|
||||
Malicious input can cause an out-of-bounds panic.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-35381"
|
||||
|
||||
credit = "@toptotu"
|
||||
|
||||
symbols = ["searchKeys"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.1.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/buger/jsonparser/commit/df3ea76ece10095374fd1c9a22a4fb85a44efc42"
|
||||
pr = "https://github.com/buger/jsonparser/pull/221"
|
||||
context = ["https://github.com/buger/jsonparser/issues/219"]
|
|
@ -0,0 +1,36 @@
|
|||
package = "github.com/crewjam/saml"
|
||||
|
||||
description = """
|
||||
An XML message can be maliciously crafted such that signature
|
||||
verification is bypassed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-27846"
|
||||
|
||||
credit = ""
|
||||
|
||||
symbols = [
|
||||
"IdpAuthnRequest.Validate",
|
||||
"ServiceProvider.ParseXMLResponse",
|
||||
"ServiceProvider.ValidateLogoutResponseForm",
|
||||
"ServiceProvider.ValidateLogoutResponseRedirect"
|
||||
]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.4.3"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/crewjam/saml/samlidp"
|
||||
smybols = ["getSPMetadata"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v0.4.3"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/crewjam/saml/samlsp"
|
||||
smybols = ["ParseMetadata"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v0.4.3"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/crewjam/saml/commit/da4f1a0612c0a8dd0452cf8b3c7a6518f6b4d053"
|
||||
context = ["https://github.com/crewjam/saml/security/advisories/GHSA-4hq8-gmxx-h6w9"]
|
|
@ -0,0 +1,18 @@
|
|||
package = "github.com/tidwall/gjson"
|
||||
|
||||
description = """
|
||||
Maliciously crafted JSON messages can cause an out-of-bounds panic.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-35380"
|
||||
|
||||
credit = "@toptotu"
|
||||
|
||||
symbols = ["sqaush"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.6.4"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/tidwall/gjson/commit/f0ee9ebde4b619767ae4ac03e8e42addb530f6bc"
|
||||
context = ["https://github.com/tidwall/gjson/issues/192"]
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/russellhaering/gosaml2"
|
||||
|
||||
description = """
|
||||
An XML message can be maliciously crafted such that signature
|
||||
verification is bypassed.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-29509"
|
||||
|
||||
credit = "Juho Nurminen"
|
||||
|
||||
symbols = ["parseResponse"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.6.0"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/russellhaering/gosaml2/commit/42606dafba60c58c458f14f75c4c230459672ab9"
|
||||
context = ["https://github.com/russellhaering/gosaml2/security/advisories/GHSA-xhqq-x44f-9fgg"]
|
|
@ -0,0 +1,23 @@
|
|||
package = "gopkg.in/yaml.v2"
|
||||
|
||||
description = """
|
||||
A maliciously crafted input can cause resource exhaustion due to
|
||||
alias chasing.
|
||||
"""
|
||||
|
||||
credit = "@simonferquel"
|
||||
|
||||
symbols = ["decoder.unmarshal"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v2.2.3"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "github.com/go-yaml/yaml"
|
||||
symbols = ["decoder.unmarshal"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v2.2.3"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/go-yaml/yaml/commit/bb4e33bf68bf89cad44d386192cbed201f35b241"
|
||||
pr = "https://github.com/go-yaml/yaml/pull/375"
|
|
@ -0,0 +1,30 @@
|
|||
package = "k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||
|
||||
description = """
|
||||
A maliciously crafted YAML or JSON message can cause resource
|
||||
exhaustion.
|
||||
"""
|
||||
|
||||
cve = "CVE-2019-11253"
|
||||
|
||||
symbols = ["NewCustomResourceDefinitionHandler"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.17.0"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "k8s.io/kubernetes/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||
symbols = ["NewCustomResourceDefinitionHandler"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v1.17.0-alpha.2"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/kubernetes/apiextensions-apiserver/commit/9cfd100448d12f999fbf913ae5d4fef2fcd66871"
|
||||
pr = "https://github.com/kubernetes/kubernetes/pull/83261"
|
||||
context = [
|
||||
"https://github.com/kubernetes/kubernetes/issues/83253",
|
||||
"https://gist.github.com/bgeesaman/0e0349e94cd22c48bf14d8a9b7d6b8f2"
|
||||
]
|
||||
|
||||
# This is a really confusing one to classify becuase of how kubernetes
|
||||
# does their vendoring stuff.
|
|
@ -0,0 +1,19 @@
|
|||
package = "github.com/ethereum/go-ethereum/les"
|
||||
|
||||
description = """
|
||||
A maliciously crafted RPC message can cause a panic due
|
||||
to a nil pointer dereference.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-26264"
|
||||
|
||||
credit = "@zsfelfoldi"
|
||||
|
||||
symbols = ["serverHandler.handleMsg"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.9.25"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/ethereum/go-ethereum/commit/bddd103a9f0af27ef533f04e06ea429cf76b6d46"
|
||||
pr = "https://github.com/ethereum/go-ethereum/pull/21896"
|
|
@ -0,0 +1,29 @@
|
|||
package = "k8s.io/client-go/transport"
|
||||
|
||||
description = """
|
||||
Authorization tokens may be inappropriately logged if the verbosity
|
||||
level is set to a debug level.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-8565"
|
||||
|
||||
credit = "@sfowl"
|
||||
|
||||
symbols = ["requestInfo.toCurl"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.20.0-alpha.2"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "k8s.io/kubernetes/staging/src/k8s.io/client-go/transport"
|
||||
symbols = ["requestInfo.toCurl"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v1.20.0-alpha.2"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/kubernetes/kubernetes/commit/e99df0e5a75eb6e86123b56d53e9b7ca0fd00419"
|
||||
pr = "https://github.com/kubernetes/kubernetes/pull/95316"
|
||||
context = ["https://github.com/kubernetes/kubernetes/issues/95623"]
|
||||
|
||||
# This is a really confusing one to classify becuase of how kubernetes
|
||||
# does their vendoring stuff.
|
|
@ -0,0 +1,27 @@
|
|||
package = "k8s.io/client-go/transport"
|
||||
|
||||
description = """
|
||||
Authorization tokens may be inappropriately logged if the verbosity
|
||||
level is set to a debug level.
|
||||
"""
|
||||
|
||||
cve = "CVE-2019-11250"
|
||||
|
||||
symbols = ["debuggingRoundTripper.RoundTrip"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v0.17.0"
|
||||
|
||||
[[additional_packages]]
|
||||
package = "k8s.io/kubernetes/staging/src/k8s.io/client-go/transport"
|
||||
symbols = ["debuggingRoundTripper.RoundTrip"]
|
||||
[[additional_packages.versions]]
|
||||
fixed = "v1.16.0-beta.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/kubernetes/kubernetes/commit/4441f1d9c3e94d9a3d93b4f184a591cab02a5245"
|
||||
pr = "https://github.com/kubernetes/kubernetes/pull/81330"
|
||||
context = ["https://github.com/kubernetes/kubernetes/issues/81114"]
|
||||
|
||||
# This is a really confusing one to classify becuase of how kubernetes
|
||||
# does their vendoring stuff.
|
|
@ -0,0 +1,23 @@
|
|||
package = "k8s.io/kubernetes/pkg/credentialprovider"
|
||||
|
||||
description = """
|
||||
Attempting to read a malformed .dockercfg may cause secrets to be
|
||||
inappropriately logged.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-8564"
|
||||
|
||||
credit = "@sfowl"
|
||||
|
||||
symbols = ["readDockerConfigFileFromBytes", "readDockerConfigJSONFileFromBytes"]
|
||||
|
||||
[[versions]]
|
||||
fixed = "v1.20.0-alpha.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/kubernetes/kubernetes/commit/11793434dac97a49bfed0150b56ac63e5dc34634"
|
||||
pr = "https://github.com/kubernetes/kubernetes/pull/94712"
|
||||
context = ["https://github.com/kubernetes/kubernetes/issues/95622"]
|
||||
|
||||
# This is a really confusing one to classify becuase of how kubernetes
|
||||
# does their vendoring stuff.
|
|
@ -0,0 +1,21 @@
|
|||
package = "archive/zip"
|
||||
|
||||
stdlib = true
|
||||
|
||||
description = """
|
||||
Using Reader.Open on an archive containing a file with a path
|
||||
prefixed by "../" will cause a panic due to a stack overflow.
|
||||
"""
|
||||
|
||||
cve = "CVE-2021-27919"
|
||||
|
||||
symbols = ["toValidName"]
|
||||
|
||||
[[versions]]
|
||||
introduced = "go1.16"
|
||||
fixed = "go1.16.1"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/golang/go/commit/cd3b4ca9f20fd14187ed4cdfdee1a02ea87e5cd8"
|
||||
pr = "https://go-review.googlesource.com/c/go/+/300489"
|
||||
context = ["https://github.com/golang/go/issues/44916"]
|
|
@ -0,0 +1,31 @@
|
|||
package = "cmd/go"
|
||||
|
||||
stdlib = true
|
||||
do_not_export = true
|
||||
|
||||
description = """
|
||||
The go command may execute arbitrary code at build time when using cgo on Windows.
|
||||
This can be triggered by running go get on a malicious module, or any other time
|
||||
the code is built.
|
||||
"""
|
||||
|
||||
os = ["windows"]
|
||||
|
||||
cve = "CVE-2021-3115"
|
||||
|
||||
credit = "RyotaK"
|
||||
|
||||
[[versions]]
|
||||
fixed = "go1.14.14"
|
||||
|
||||
[[versions]]
|
||||
fixed = "go1.15.7"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/golang/go/commit/953d1feca9b21af075ad5fc8a3dad096d3ccc3a0"
|
||||
pr = "https://golang.org/cl/284783"
|
||||
context = [
|
||||
"https://github.com/golang/go/issues/43783",
|
||||
"https://golang.org/cl/284780",
|
||||
"https://github.com/golang/go/commit/46e2e2e9d99925bbf724b12693c6d3e27a95d6a0"
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
package = "math/big"
|
||||
|
||||
stdlib = true
|
||||
|
||||
description = """
|
||||
A number of math/big.Int methods can panic when provided large inputs due
|
||||
to a flawed division method.
|
||||
"""
|
||||
|
||||
cve = "CVE-2020-28362"
|
||||
|
||||
symbols = ["nat.divRecursiveStep"]
|
||||
|
||||
[[versions]]
|
||||
introduced = "go1.14"
|
||||
fixed = "go1.14.12"
|
||||
|
||||
[[versions]]
|
||||
introduced = "go1.15"
|
||||
fixed = "go1.15.5"
|
||||
|
||||
[links]
|
||||
commit = "https://github.com/golang/go/commit/1e1fa5903b760c6714ba17e50bf850b01f49135c"
|
||||
pr = "https://go-review.googlesource.com/c/go/+/269657"
|
||||
context = ["https://github.com/golang/go/issues/42552"]
|
|
@ -0,0 +1,20 @@
|
|||
package = ""
|
||||
|
||||
description = """
|
||||
|
||||
"""
|
||||
|
||||
cve = ""
|
||||
|
||||
credit = ""
|
||||
|
||||
symbols = [""]
|
||||
|
||||
[[versions]]
|
||||
introduced = ""
|
||||
fixed = ""
|
||||
|
||||
[links]
|
||||
commit = ""
|
||||
pr = ""
|
||||
context = [""]
|
Загрузка…
Ссылка в новой задаче