Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding new source for debian and amazon linux for advisory and captur… #128

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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