Skip to content

Commit

Permalink
Changed trivy DB for below changes
Browse files Browse the repository at this point in the history
1. New debian source will added in new buckets, called debain-salsa 7/ debian-salsa 8 etc
2. CVE and advisory relation is captured in advisory bucket. If a CVE is fixed inside a advisory, that advisory ID is saved along with CVE.
3. All advisory details are saved in vulnerability bucket.
4. In ubuntu needs-traiged status CVEs are also captured into bolt DB now.
5. Added advisory details for Amazon Linux
  • Loading branch information
tonaim committed Jul 18, 2021
1 parent 4c76bb5 commit 2e164aa
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 24 deletions.
39 changes: 39 additions & 0 deletions pkg/db/advisory_detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,42 @@ func (dbc Config) GetAdvisoryDetails(cveID string) ([]types.AdvisoryDetail, erro
func (dbc Config) DeleteAdvisoryDetailBucket() error {
return dbc.deleteBucket(advisoryDetailBucket)
}

func (dbc Config) GetAdvisoryDetail(tx *bolt.Tx, cveID string, platformName string, pkgName string) (types.AdvisoryDetail, error) {
advisory := types.AdvisoryDetail{}
root := tx.Bucket([]byte(advisoryDetailBucket))
if root == nil {
return advisory, nil
}
cveBucket := root.Bucket([]byte(cveID))
if cveBucket == nil {
return advisory, nil
}
err := cveBucket.ForEach(func(platform, v []byte) error {
packageBucket := cveBucket.Bucket(platform)
if packageBucket == nil {
return nil
}
err := packageBucket.ForEach(func(packageName, v []byte) error {
var detail types.Advisory
if err := json.Unmarshal(v, &detail); err != nil {
return xerrors.Errorf("failed to unmarshall advisory_detail: %w", err)
}
if string(packageName) == pkgName && string(platform) == platformName {
advisory = types.AdvisoryDetail{
PlatformName: string(platform),
PackageName: string(packageName),
AdvisoryItem: detail,
}

return nil
}
return nil
})
return err
})
if err != nil {
return advisory, xerrors.Errorf("error in db foreach: %w", err)
}
return advisory, nil
}
5 changes: 5 additions & 0 deletions pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ type Operation interface {
GetAdvisoryDetails(cveID string) ([]types.AdvisoryDetail, error)
PutAdvisoryDetail(tx *bolt.Tx, vulnerabilityID string, source string, pkgName string,
advisory interface{}) (err error)
GetAdvisoryDetail(tx *bolt.Tx, cveID string, platformName string, pkgName string) (types.AdvisoryDetail, error)
DeleteAdvisoryDetailBucket() error

GetSecurityAdvisoryDetails(cveId string) (types.SecurityAdvisories, error)
PutSecurityAdvisoryDetails(tx *bolt.Tx, platform string, advisoryId string, securityAdvisory map[string]types.SecurityAdvisory) error
DeleteSecurityAdvisoryBucket() error
}

type Metadata struct {
Expand Down
82 changes: 82 additions & 0 deletions pkg/db/security_advisory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package db

import (
"encoding/json"

"github.com/aquasecurity/trivy-db/pkg/types"
bolt "go.etcd.io/bbolt"
"golang.org/x/xerrors"
)

const (
securityAdvisoryBucket = "security-advisory"
)

func (dbc Config) GetSecurityAdvisoryDetails(cveId string) (types.SecurityAdvisories, error) {
SecurityAdvisories := types.SecurityAdvisories{}
err := db.View(func(tx *bolt.Tx) error {
root := tx.Bucket([]byte(securityAdvisoryBucket))
if root == nil {
return nil
}
cveBucket := root.Bucket([]byte(cveId))
if cveBucket == nil {
return nil
}
err := cveBucket.ForEach(func(platform, v []byte) error {
securityAdvisory := make(map[string]types.SecurityAdvisory)
advisoryBucket := cveBucket.Bucket(platform)
if advisoryBucket == nil {
return nil
}
err := advisoryBucket.ForEach(func(advisoryID, v []byte) error {
detail := types.SecurityAdvisory{}
if err := json.Unmarshal(v, &detail); err != nil {
return xerrors.Errorf("failed to unmarshall advisory_detail: %w", err)
}
securityAdvisory[string(advisoryID)] = detail
return nil
})
SecurityAdvisories[string(platform)] = securityAdvisory
return err
})
if err != nil {
return xerrors.Errorf("error in db foreach: %w", err)
}
return nil
})
return SecurityAdvisories, err
}

func (dbc Config) PutSecurityAdvisoryDetails(tx *bolt.Tx, cveId string, osName string, securityAdvisory map[string]types.SecurityAdvisory) error {
root, err := tx.CreateBucketIfNotExists([]byte(securityAdvisoryBucket))
if err != nil {
return err
}

cveBucket, err := root.CreateBucketIfNotExists([]byte(cveId))
if err != nil {
return err
}

osBucket, err := cveBucket.CreateBucketIfNotExists([]byte(osName))
if err != nil {
return err
}

for secAdvId, advisoryDetail := range securityAdvisory {
jsonVal, err := json.Marshal(advisoryDetail)
if err != nil {
return xerrors.Errorf("failed to marshal JSON: %w", err)
}
err = osBucket.Put([]byte(secAdvId), jsonVal)
if err != nil {
return err
}
}
return nil
}

func (dbc Config) DeleteSecurityAdvisoryBucket() error {
return dbc.deleteBucket(securityAdvisoryBucket)
}
59 changes: 37 additions & 22 deletions pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
type Severity int

type VendorSeverity map[string]Severity
type SecurityAdvisories map[string]map[string]SecurityAdvisory

type CVSS struct {
V2Vector string `json:"V2Vector,omitempty"`
Expand Down Expand Up @@ -82,19 +83,20 @@ type LastUpdated struct {
Date time.Time
}
type VulnerabilityDetail struct {
ID string `json:",omitempty"` // e.g. CVE-2019-8331, OSVDB-104365
CvssScore float64 `json:",omitempty"`
CvssVector string `json:",omitempty"`
CvssScoreV3 float64 `json:",omitempty"`
CvssVectorV3 string `json:",omitempty"`
Severity Severity `json:",omitempty"`
SeverityV3 Severity `json:",omitempty"`
CweIDs []string `json:",omitempty"` // e.g. CWE-78, CWE-89
References []string `json:",omitempty"`
Title string `json:",omitempty"`
Description string `json:",omitempty"`
PublishedDate *time.Time `json:",omitempty"`
LastModifiedDate *time.Time `json:",omitempty"`
ID string `json:",omitempty"` // e.g. CVE-2019-8331, OSVDB-104365
CvssScore float64 `json:",omitempty"`
CvssVector string `json:",omitempty"`
CvssScoreV3 float64 `json:",omitempty"`
CvssVectorV3 string `json:",omitempty"`
Severity Severity `json:",omitempty"`
SeverityV3 Severity `json:",omitempty"`
AdvisoryDetails SecurityAdvisories `json:",omitempty"`
CweIDs []string `json:",omitempty"` // e.g. CWE-78, CWE-89
References []string `json:",omitempty"`
Title string `json:",omitempty"`
Description string `json:",omitempty"`
PublishedDate *time.Time `json:",omitempty"`
LastModifiedDate *time.Time `json:",omitempty"`
}

type AdvisoryDetail struct {
Expand All @@ -103,30 +105,43 @@ type AdvisoryDetail struct {
AdvisoryItem interface{}
}

type SecurityAdvisory struct {
SecurityAdvisoryId string `json:"security_advisory_id,omitempty"`
Severity string `json:"severity,omitempty"`
PublishDate time.Time `json:"publish_date,omitempty"`
Description string `json:"description,omitempty"`
}

type Advisory struct {
VulnerabilityID string `json:",omitempty"`

// Versions for os package
FixedVersion string `json:",omitempty"`
AffectedVersion string `json:",omitempty"` // Only for Arch Linux

WillNotFix bool `json:"will_not_fix,omitempty"`

// Version ranges for language-specific package
// Some advisories provide VulnerableVersions only, others provide PatchedVersions and UnaffectedVersions
VulnerableVersions []string `json:",omitempty"`
PatchedVersions []string `json:",omitempty"`
UnaffectedVersions []string `json:",omitempty"`
// Security Advisories
SecurityAdvisory []string `json:",omitempty"`
}

type Vulnerability struct {
Title string `json:",omitempty"`
Description string `json:",omitempty"`
Severity string `json:",omitempty"` // Selected from VendorSeverity, depending on a scan target
CweIDs []string `json:",omitempty"` // e.g. CWE-78, CWE-89
VendorSeverity VendorSeverity `json:",omitempty"`
CVSS VendorCVSS `json:",omitempty"`
References []string `json:",omitempty"`
PublishedDate *time.Time `json:",omitempty"`
LastModifiedDate *time.Time `json:",omitempty"`
Title string `json:",omitempty"`
Description string `json:",omitempty"`
Severity string `json:",omitempty"` // Selected from VendorSeverity, depending on a scan target
CweIDs []string `json:",omitempty"` // e.g. CWE-78, CWE-89
VendorSeverity VendorSeverity `json:",omitempty"`
CVSS VendorCVSS `json:",omitempty"`
AdvisoryDetails SecurityAdvisories `json:",omitempty"`
References []string `json:",omitempty"`
PublishedDate *time.Time `json:",omitempty"`
LastModifiedDate *time.Time `json:",omitempty"`
VendorURL string `json:",omitempty"`
}

type VulnSrc interface {
Expand Down
29 changes: 29 additions & 0 deletions pkg/vulnsrc/amazon/amazon.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"path/filepath"
"strings"
"time"

"github.com/aquasecurity/trivy-db/pkg/types"

Expand Down Expand Up @@ -105,6 +106,22 @@ func (vs VulnSrc) commitFunc(tx *bolt.Tx) error {
advisory := types.Advisory{
FixedVersion: constructVersion(pkg.Epoch, pkg.Version, pkg.Release),
}
existingAdvisory, err := vs.dbc.GetAdvisoryDetail(tx, cveID, platformName, pkg.Name)
if err != nil {
return xerrors.Errorf("failed to get Amazon advisory: %w", err)
}
if existingAdvisory.AdvisoryItem != nil {
existingAdvisoryDetails := existingAdvisory.AdvisoryItem.(types.Advisory)

if len(existingAdvisoryDetails.SecurityAdvisory) > 0 {
advisory.SecurityAdvisory = existingAdvisoryDetails.SecurityAdvisory
}
}

if !utils.StringInSlice(alas.ID, advisory.SecurityAdvisory) {
advisory.SecurityAdvisory = append(advisory.SecurityAdvisory, alas.ID)
}

if err := vs.dbc.PutAdvisoryDetail(tx, cveID, platformName, pkg.Name, advisory); err != nil {
return xerrors.Errorf("failed to save Amazon advisory: %w", err)
}
Expand All @@ -123,6 +140,18 @@ func (vs VulnSrc) commitFunc(tx *bolt.Tx) error {
if err := vs.dbc.PutVulnerabilityDetail(tx, cveID, vulnerability.Amazon, vuln); err != nil {
return xerrors.Errorf("failed to save Amazon vulnerability detail: %w", err)
}
publishDate, err := time.Parse("2006-01-02 15:04", alas.Issued.Date)
if err != nil {
log.Println("Error in publish Date, %w", err)
}
securityAdvisory := map[string]types.SecurityAdvisory{alas.ID: types.SecurityAdvisory{
Severity: alas.Severity,
PublishDate: publishDate,
Description: alas.Description,
}}
if err := vs.dbc.PutSecurityAdvisoryDetails(tx, cveID, vulnerability.Amazon, securityAdvisory); err != nil {
return xerrors.Errorf("failed to save Debian vulnerability: %w", err)
}

// for light DB
if err := vs.dbc.PutSeverity(tx, cveID, types.SeverityUnknown); err != nil {
Expand Down
Loading

0 comments on commit 2e164aa

Please sign in to comment.