mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 15:37:50 -08:00
109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package composer
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/etcd-io/bbolt"
|
|
"github.com/aquasecurity/trivy/pkg/db"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/aquasecurity/trivy/pkg/utils"
|
|
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
|
|
|
|
"github.com/aquasecurity/trivy/pkg/git"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
const (
|
|
dbURL = "https://github.com/FriendsOfPHP/security-advisories"
|
|
)
|
|
|
|
var (
|
|
repoPath = filepath.Join(utils.CacheDir(), "php-security-advisories")
|
|
)
|
|
|
|
type AdvisoryDB map[string][]Advisory
|
|
|
|
type Advisory struct {
|
|
Cve string
|
|
Title string
|
|
Link string
|
|
Reference string
|
|
Branches map[string]Branch
|
|
}
|
|
|
|
type Branch struct {
|
|
Versions []string
|
|
}
|
|
|
|
func (s *Scanner) UpdateDB() (err error) {
|
|
if _, err := git.CloneOrPull(dbURL, repoPath); err != nil {
|
|
return err
|
|
}
|
|
s.db, err = s.walk()
|
|
return err
|
|
}
|
|
|
|
func (s *Scanner) walk() (AdvisoryDB, error) {
|
|
advisoryDB := AdvisoryDB{}
|
|
var vulns []vulnerability.Vulnerability
|
|
err := filepath.Walk(repoPath, func(path string, info os.FileInfo, err error) error {
|
|
if info.IsDir() || !strings.HasPrefix(info.Name(), "CVE-") {
|
|
return nil
|
|
}
|
|
buf, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
advisory := Advisory{}
|
|
err = yaml.Unmarshal(buf, &advisory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// for detecting vulnerabilities
|
|
advisories, ok := advisoryDB[advisory.Reference]
|
|
if !ok {
|
|
advisories = []Advisory{}
|
|
}
|
|
advisoryDB[advisory.Reference] = append(advisories, advisory)
|
|
|
|
vulnerabilityID := advisory.Cve
|
|
if vulnerabilityID == "" {
|
|
// e.g. CVE-2019-12139.yaml => CVE-2019-12139
|
|
vulnerabilityID = strings.TrimSuffix(info.Name(), ".yaml")
|
|
}
|
|
|
|
// for displaying vulnerability detail
|
|
vulns = append(vulns, vulnerability.Vulnerability{
|
|
ID: vulnerabilityID,
|
|
References: []string{advisory.Link},
|
|
Title: advisory.Title,
|
|
})
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("error in file walk: %w", err)
|
|
}
|
|
if err = s.saveVulnerabilities(vulns); err != nil {
|
|
return nil, err
|
|
}
|
|
return advisoryDB, nil
|
|
}
|
|
|
|
func (s Scanner) saveVulnerabilities(vulns []vulnerability.Vulnerability) error {
|
|
return vulnerability.BatchUpdate(func(b *bbolt.Bucket) error {
|
|
for _, vuln := range vulns {
|
|
if err := db.Put(b, vuln.ID, vulnerability.PhpSecurityAdvisories, vuln); err != nil {
|
|
return xerrors.Errorf("failed to save %s vulnerability: %w", s.Type(), err)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|