Update trivy from 0.35.0 to 0.49.1 (#1806)

* Update trivy 0.35.0->0.48.0

- Specify oras-go 1.2.4 in indirect dependencies

  docker/docker changes a part of its API at 24.0
  - registry: return concrete service type · moby/moby@7b3acdf
    - 7b3acdff5d (diff-8325eae896b1149bf92c826d07fc29005b1b102000b766ffa5a238d791e0849bR18-R21)

  oras-go 1.2.3 uses 23.0.1 and trivy transitively depends on docker/docker 24.y.z.
  There is a build error between oras-go and docker/dockr.

- Update disabled analyzers
- Update language scanners, enable all of them

* move javadb init to scan.go

* Add options for java db init()

* Update scanner/base.go

* Remove unused codes

* Add some lock file names

* Typo fix

* Remove space character (0x20)

* Add java-db options for integration scan

* Minor fomartting fix

* minor fix

* conda is NOT supported by Trivy for library scan

* Configure trivy log in report command too

* Init trivy in scanner

* Use trivy's jar.go and replace client which does almost nothing

* mv jar.go

* Add sha1 hash to result and add filepath for report phase

* Undo added 'vuls scan' options

* Update oras-go to 1.2.4

* Move Java DB related config items to report side

* Add java db search in detect phase

* filter top level jar only

* Update trivy to 0.49.1

* go mod tidy

* Update to newer interface

* Refine lock file list, h/t MaineK00n

* Avoid else clauses if possible, h/t MaineK00n

* Avoid missing word for find and lang types, h/t MaineK00n

* Add missing ecosystems, h/t MaineK00n

* Add comments why to use custom jar analyzer, h/t MaineK00n

* Misc

* Misc

* Misc

* Include go-dep-parser's pares.go for modification

* Move digest field from LibraryScanner to Library

* Use inner jars sha1 for each

* Add Seek to file head before handling zip file entry

* Leave Digest feild empty for entries from pom.xml

* Don't import python/pkg (don't look into package.json)

* Make privete where private is sufficient

* Remove duplicate after Java DB lookup

* misc

* go mod tidy

* Comment out ruby/gemspec

* misc

* Comment out python/packaging

* misc

* Use custom jar

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/jar.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update detector/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update models/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/base.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/parse.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Missing changes in name change

* Update models/github.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update models/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update models/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update models/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/base.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/base.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update scanner/trivy/jar/jar.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Don't import fanal/types at github.go

* Rewrite code around java db initialization

* Add comment

* refactor

* Close java db client

* rename

* Let LibraryScanner have java db client

* Update detector/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update detector/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update detector/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* Update detector/library.go

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>

* inline variable

* misc

* Fix typo

---------

Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>
This commit is contained in:
Shunichi Shinohara
2024-02-28 14:25:58 +09:00
committed by GitHub
parent d7e1e82299
commit 351cf4f712
22 changed files with 1600 additions and 318 deletions

View File

@@ -3,7 +3,7 @@
install \
all \
vendor \
lint \
lint \
vet \
fmt \
fmtcheck \

View File

@@ -76,7 +76,6 @@ type ScanOpts struct {
type ReportOpts struct {
CvssScoreOver float64 `json:"cvssScoreOver,omitempty"`
ConfidenceScoreOver int `json:"confidenceScoreOver,omitempty"`
TrivyCacheDBDir string `json:"trivyCacheDBDir,omitempty"`
NoProgress bool `json:"noProgress,omitempty"`
RefreshCve bool `json:"refreshCve,omitempty"`
IgnoreUnfixed bool `json:"ignoreUnfixed,omitempty"`
@@ -85,6 +84,15 @@ type ReportOpts struct {
DiffMinus bool `json:"diffMinus,omitempty"`
Diff bool `json:"diff,omitempty"`
Lang string `json:"lang,omitempty"`
TrivyOpts
}
// TrivyOpts is options for trivy DBs
type TrivyOpts struct {
TrivyCacheDBDir string `json:"trivyCacheDBDir,omitempty"`
TrivyJavaDBRepository string `json:"trivyJavaDBRepository,omitempty"`
TrivySkipJavaDBUpdate bool `json:"trivySkipJavaDBUpdate,omitempty"`
}
// ValidateOnConfigtest validates

View File

@@ -6,11 +6,11 @@
- upload vuls results json to future-vuls
- `future-vuls discover`
- Explore hosts within the CIDR range using the ping command
- Describe the information including CPE on the found hosts in a toml-formatted file.
- Exec snmp2cpe(https://github.com/future-architect/vuls/pull/1625) to active hosts to obtain CPE<br>
Commands running internally  `snmp2cpe v2c {IPAddr} public | snmp2cpe convert`<br>
- Explores hosts within the CIDR range using the ping command
- Describes the information including CPEs on the found hosts in a toml-formatted file
- Executes snmp2cpe(https://github.com/future-architect/vuls/pull/1625) to active hosts to obtain CPE,
Commands running internally `snmp2cpe v2c {IPAddr} public | snmp2cpe convert`
Structure of toml-formatted file
```
[server.{ip}]
@@ -23,12 +23,12 @@ fvuls_sync = false
- `future-vuls add-cpe`
- Create pseudo server to Fvuls to obtain uuid and Upload CPE information on the specified(FvulsSync is true and UUID is obtained) hosts to Fvuls
- Fvuls_Sync must be rewritten to true to designate it as the target of the command<br><br>
- Fvuls_Sync must be rewritten to true to designate it as the target of the command
1. `future-vuls discover`
1. `future-vuls discover`
2. `future-vuls add-cpe`
2. `future-vuls add-cpe`
These two commands are used to manage the CPE of network devices, and by executing the commands in the order from the top, you can manage the CPE of each device in Fvuls

View File

@@ -46,15 +46,13 @@ func setScanResultMeta(scanResult *models.ScanResult, report *types.Report) erro
scanResult.ServerName = report.ArtifactName
if report.ArtifactType == "container_image" {
matches := dockerTagPattern.FindStringSubmatch(report.ArtifactName)
var imageName, imageTag string
// initial values are for without image tag
var imageName = report.ArtifactName
var imageTag = "latest" // Complement if the tag is omitted
if 2 < len(matches) {
// including the image tag
imageName = matches[1]
imageTag = matches[2]
} else {
// no image tag
imageName = report.ArtifactName
imageTag = "latest" // Complement if the tag is omitted
}
scanResult.ServerName = fmt.Sprintf("%s:%s", imageName, imageTag)
if scanResult.Optional == nil {
@@ -64,11 +62,10 @@ func setScanResultMeta(scanResult *models.ScanResult, report *types.Report) erro
scanResult.Optional["TRIVY_IMAGE_TAG"] = imageTag
}
scanResult.Family = constant.ServerTypePseudo
if report.Metadata.OS != nil {
scanResult.Family = report.Metadata.OS.Family
scanResult.Family = string(report.Metadata.OS.Family)
scanResult.Release = report.Metadata.OS.Name
} else {
scanResult.Family = constant.ServerTypePseudo
}
scanResult.ScannedAt = time.Now()

View File

@@ -5,7 +5,7 @@ import (
"sort"
"time"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/os"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/future-architect/vuls/models"
@@ -92,7 +92,7 @@ func Convert(results types.Results) (result *models.ScanResult, err error) {
})
} else {
vulnInfo.LibraryFixedIns = append(vulnInfo.LibraryFixedIns, models.LibraryFixedIn{
Key: trivyResult.Type,
Key: string(trivyResult.Type),
Name: vuln.PkgName,
Path: trivyResult.Target,
FixedIn: vuln.FixedVersion,
@@ -190,24 +190,26 @@ func Convert(results types.Results) (result *models.ScanResult, err error) {
return scanResult, nil
}
func isTrivySupportedOS(family string) bool {
supportedFamilies := map[string]struct{}{
os.RedHat: {},
os.Debian: {},
os.Ubuntu: {},
os.CentOS: {},
os.Rocky: {},
os.Alma: {},
os.Fedora: {},
os.Amazon: {},
os.Oracle: {},
os.Windows: {},
os.OpenSUSE: {},
os.OpenSUSELeap: {},
os.OpenSUSETumbleweed: {},
os.SLES: {},
os.Photon: {},
os.Alpine: {},
func isTrivySupportedOS(family ftypes.TargetType) bool {
supportedFamilies := map[ftypes.TargetType]struct{}{
ftypes.Alma: {},
ftypes.Alpine: {},
ftypes.Amazon: {},
ftypes.CBLMariner: {},
ftypes.CentOS: {},
ftypes.Chainguard: {},
ftypes.Debian: {},
ftypes.Fedora: {},
ftypes.OpenSUSE: {},
ftypes.OpenSUSELeap: {},
ftypes.OpenSUSETumbleweed: {},
ftypes.Oracle: {},
ftypes.Photon: {},
ftypes.RedHat: {},
ftypes.Rocky: {},
ftypes.SLES: {},
ftypes.Ubuntu: {},
ftypes.Wolfi: {},
}
_, ok := supportedFamilies[family]
return ok

View File

@@ -46,7 +46,7 @@ func Detect(rs []models.ScanResult, dir string) ([]models.ScanResult, error) {
r.ScannedCves = models.VulnInfos{}
}
if err := DetectLibsCves(&r, config.Conf.TrivyCacheDBDir, config.Conf.NoProgress); err != nil {
if err := DetectLibsCves(&r, config.Conf.TrivyOpts, config.Conf.LogOpts, config.Conf.NoProgress); err != nil {
return nil, xerrors.Errorf("Failed to fill with Library dependency: %w", err)
}

View File

@@ -9,40 +9,56 @@ import (
trivydb "github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/pkg/db"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/javadb"
"github.com/aquasecurity/trivy/pkg/log"
"golang.org/x/xerrors"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/logging"
"github.com/future-architect/vuls/models"
)
// DetectLibsCves fills LibraryScanner information
func DetectLibsCves(r *models.ScanResult, cacheDir string, noProgress bool) (err error) {
func DetectLibsCves(r *models.ScanResult, trivyOpts config.TrivyOpts, logOpts logging.LogOpts, noProgress bool) (err error) {
totalCnt := 0
if len(r.LibraryScanners) == 0 {
return
}
// initialize trivy's logger and db
err = log.InitLogger(false, false)
err = log.InitLogger(logOpts.Debug, logOpts.Quiet)
if err != nil {
return err
return xerrors.Errorf("Failed to init trivy logger. err: %w", err)
}
logging.Log.Info("Updating library db...")
if err := downloadDB("", cacheDir, noProgress, false); err != nil {
return err
if err := downloadDB("", trivyOpts, noProgress, false); err != nil {
return xerrors.Errorf("Failed to download trivy DB. err: %w", err)
}
if err := trivydb.Init(cacheDir); err != nil {
return err
if err := trivydb.Init(trivyOpts.TrivyCacheDBDir); err != nil {
return xerrors.Errorf("Failed to init trivy DB. err: %w", err)
}
defer trivydb.Close()
var javaDBClient *javadb.DB
defer javaDBClient.Close()
for _, lib := range r.LibraryScanners {
if lib.Type == ftypes.Jar {
if javaDBClient == nil {
javadb.Init(trivyOpts.TrivyCacheDBDir, trivyOpts.TrivyJavaDBRepository, trivyOpts.TrivySkipJavaDBUpdate, noProgress, ftypes.RegistryOptions{})
javaDBClient, err = javadb.NewClient()
if err != nil {
return xerrors.Errorf("Failed to download or open trivy Java DB. err: %w", err)
}
}
lib.JavaDBClient = javaDBClient
}
vinfos, err := lib.Scan()
if err != nil {
return err
return xerrors.Errorf("Failed to scan library. err: %w", err)
}
for _, vinfo := range vinfos {
vinfo.Confidences.AppendIfMissing(models.TrivyMatch)
@@ -62,8 +78,8 @@ func DetectLibsCves(r *models.ScanResult, cacheDir string, noProgress bool) (err
return nil
}
func downloadDB(appVersion, cacheDir string, quiet, skipUpdate bool) error {
client := db.NewClient(cacheDir, quiet, false)
func downloadDB(appVersion string, trivyOpts config.TrivyOpts, noProgress, skipUpdate bool) error {
client := db.NewClient(trivyOpts.TrivyCacheDBDir, noProgress)
ctx := context.Background()
needsUpdate, err := client.NeedsUpdate(appVersion, skipUpdate)
if err != nil {
@@ -73,14 +89,14 @@ func downloadDB(appVersion, cacheDir string, quiet, skipUpdate bool) error {
if needsUpdate {
logging.Log.Info("Need to update DB")
logging.Log.Info("Downloading DB...")
if err := client.Download(ctx, cacheDir); err != nil {
return xerrors.Errorf("failed to download vulnerability DB: %w", err)
if err := client.Download(ctx, trivyOpts.TrivyCacheDBDir, ftypes.RegistryOptions{}); err != nil {
return xerrors.Errorf("Failed to download vulnerability DB. err: %w", err)
}
}
// for debug
if err := showDBInfo(cacheDir); err != nil {
return xerrors.Errorf("failed to show database info: %w", err)
if err := showDBInfo(trivyOpts.TrivyCacheDBDir); err != nil {
return xerrors.Errorf("Failed to show database info. err: %w", err)
}
return nil
}
@@ -89,7 +105,7 @@ func showDBInfo(cacheDir string) error {
m := metadata.NewClient(cacheDir)
meta, err := m.Get()
if err != nil {
return xerrors.Errorf("something wrong with DB: %w", err)
return xerrors.Errorf("Failed to get DB metadata. err: %w", err)
}
log.Logger.Debugf("DB Schema: %d, UpdatedAt: %s, NextUpdate: %s, DownloadedAt: %s",
meta.Version, meta.UpdatedAt, meta.NextUpdate, meta.DownloadedAt)

223
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/future-architect/vuls
go 1.20
go 1.21
require (
github.com/3th1nk/cidr v0.2.0
@@ -8,11 +8,11 @@ require (
github.com/BurntSushi/toml v1.3.2
github.com/CycloneDX/cyclonedx-go v0.8.0
github.com/Ullaakut/nmap/v2 v2.2.2
github.com/aquasecurity/go-dep-parser v0.0.0-20221114145626-35ef808901e8
github.com/aquasecurity/trivy v0.35.0
github.com/aquasecurity/trivy-db v0.0.0-20231212124729-c8b1552fd5ae
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/aws/aws-sdk-go v1.45.6
github.com/aquasecurity/go-dep-parser v0.0.0-20240202105001-4f19ab402b0b
github.com/aquasecurity/trivy v0.49.1
github.com/aquasecurity/trivy-db v0.0.0-20231005141211-4fc651f7ac8d
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/aws/aws-sdk-go v1.49.21
github.com/c-robinson/iplib v1.0.8
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b
@@ -29,7 +29,7 @@ require (
github.com/k0kubun/pp v3.0.1+incompatible
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
github.com/knqyf263/go-cpe v0.0.0-20230627041855-cb0794d06872
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/knqyf263/go-deb-version v0.0.0-20230223133812-3ed183d23422
github.com/knqyf263/go-rpm-version v0.0.0-20220614171824-631e686d1075
github.com/kotakanbe/go-pingscanner v0.1.0
github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96
@@ -41,6 +41,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
github.com/samber/lo v1.39.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/vulsio/go-cti v0.0.5-0.20231217191918-27dd65e7bf4a
@@ -51,6 +52,7 @@ require (
github.com/vulsio/gost v0.4.6-0.20231217202927-253ae3c1e8fb
github.com/vulsio/goval-dictionary v0.9.5-0.20231217193624-5a5a38b48f60
go.etcd.io/bbolt v1.3.9
go.uber.org/zap v1.26.0
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611
golang.org/x/oauth2 v0.17.0
golang.org/x/sync v0.6.0
@@ -64,105 +66,242 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.35.1 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
github.com/PuerkitoBio/goquery v1.8.1 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/aquasecurity/defsec v0.94.1 // indirect
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce // indirect
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 // indirect
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect
github.com/aquasecurity/trivy-iac v0.8.0 // indirect
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 // indirect
github.com/aquasecurity/trivy-policies v0.8.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.26.3 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.6 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/briandowns/spinner v1.23.0 // indirect
github.com/caarlos0/env/v6 v6.10.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cheggaaa/pb/v3 v3.1.4 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/containerd v1.7.12 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dnaeon/go-vcr v1.2.0 // indirect
github.com/docker/cli v20.10.20+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/docker/cli v25.0.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v25.0.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/glebarez/sqlite v1.10.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-git/v5 v5.11.0 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.20.1 // indirect
github.com/go-openapi/jsonreference v0.20.3 // indirect
github.com/go-openapi/swag v0.22.5 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/uuid v4.3.1+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-containerregistry v0.12.0 // indirect
github.com/google/licenseclassifier/v2 v2.0.0-pre6 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-containerregistry v0.19.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/licenseclassifier/v2 v2.0.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.0 // indirect
github.com/hashicorp/go-getter v1.7.3 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/log15 v3.0.0-testing.5+incompatible // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.1 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/liamg/iamgo v0.0.9 // indirect
github.com/liamg/jfather v0.0.7 // indirect
github.com/liamg/memoryfs v1.6.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 // indirect
github.com/masahiro331/go-xfs-filesystem v0.0.0-20221127135739-051c25f1becd // indirect
github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/buildkit v0.12.5 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/open-policy-agent/opa v0.61.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/image-spec v1.1.0-rc6 // indirect
github.com/owenrumney/squealer v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/smartystreets/assertions v1.13.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spdx/tools-golang v0.3.0 // indirect
github.com/spdx/tools-golang v0.5.4-0.20231108154018-0c0f394b5e1a // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.1 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yashtewari/glob-intersection v0.2.0 // indirect
github.com/zclconf/go-cty v1.13.0 // indirect
github.com/zclconf/go-cty-yaml v1.0.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.21.0 // indirect
@@ -171,21 +310,41 @@ require (
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/api v0.153.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/grpc v1.61.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.2 // indirect
gorm.io/driver/postgres v1.5.4 // indirect
gorm.io/gorm v1.25.5 // indirect
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
helm.sh/helm/v3 v3.14.0 // indirect
k8s.io/api v0.29.1 // indirect
k8s.io/apiextensions-apiserver v0.29.0 // indirect
k8s.io/apimachinery v0.29.1 // indirect
k8s.io/apiserver v0.29.0 // indirect
k8s.io/cli-runtime v0.29.0 // indirect
k8s.io/client-go v0.29.0 // indirect
k8s.io/component-base v0.29.0 // indirect
k8s.io/klog/v2 v2.120.0 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/kubectl v0.29.0 // indirect
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
modernc.org/libc v1.37.6 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/sqlite v1.28.0 // indirect
moul.io/http2curl v1.0.0 // indirect
oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

758
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,6 @@ package models
import (
"fmt"
"strings"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
)
// DependencyGraphManifests has a map of DependencyGraphManifest
@@ -30,45 +28,49 @@ func (m DependencyGraphManifest) Ecosystem() string {
switch {
case strings.HasSuffix(m.Filename, "Cargo.lock"),
strings.HasSuffix(m.Filename, "Cargo.toml"):
return ftypes.Cargo // Rust
return "cargo" // Rust
case strings.HasSuffix(m.Filename, "composer.lock"),
strings.HasSuffix(m.Filename, "composer.json"):
return ftypes.Composer // PHP
return "composer" // PHP
case strings.HasSuffix(m.Filename, ".csproj"),
strings.HasSuffix(m.Filename, ".vbproj"),
strings.HasSuffix(m.Filename, ".nuspec"),
strings.HasSuffix(m.Filename, ".vcxproj"),
strings.HasSuffix(m.Filename, ".fsproj"),
strings.HasSuffix(m.Filename, "packages.config"):
return ftypes.NuGet // .NET languages (C#, F#, VB), C++
return "nuget" // .NET languages (C#, F#, VB), C++
case strings.HasSuffix(m.Filename, "go.sum"),
strings.HasSuffix(m.Filename, "go.mod"):
return ftypes.GoModule // Go
return "gomod" // Go
case strings.HasSuffix(m.Filename, "pom.xml"):
return ftypes.Pom // Java, Scala
return "pom" // Java, Scala
case strings.HasSuffix(m.Filename, "package-lock.json"),
strings.HasSuffix(m.Filename, "package.json"):
return ftypes.Npm // JavaScript
return "npm" // JavaScript
case strings.HasSuffix(m.Filename, "yarn.lock"):
return ftypes.Yarn // JavaScript
return "yarn" // JavaScript
case strings.HasSuffix(m.Filename, "pnpm-lock.yaml"):
return "pnpm" // JavaScript
case strings.HasSuffix(m.Filename, "requirements.txt"),
strings.HasSuffix(m.Filename, "requirements-dev.txt"),
strings.HasSuffix(m.Filename, "setup.py"):
return ftypes.Pip // Python
return "pip" // Python
case strings.HasSuffix(m.Filename, "Pipfile.lock"),
strings.HasSuffix(m.Filename, "Pipfile"):
return ftypes.Pipenv // Python
return "pipenv" // Python
case strings.HasSuffix(m.Filename, "poetry.lock"),
strings.HasSuffix(m.Filename, "pyproject.toml"):
return ftypes.Poetry // Python
return "poetry" // Python
case strings.HasSuffix(m.Filename, "Gemfile.lock"),
strings.HasSuffix(m.Filename, "Gemfile"):
return ftypes.Bundler // Ruby
return "bundler" // Ruby
case strings.HasSuffix(m.Filename, ".gemspec"):
return ftypes.GemSpec // Ruby
return "gemspec" // Ruby
case strings.HasSuffix(m.Filename, "pubspec.lock"),
strings.HasSuffix(m.Filename, "pubspec.yaml"):
return "pub" // Dart
case strings.HasSuffix(m.Filename, "Package.resolved"):
return "swift" // Swift
case strings.HasSuffix(m.Filename, ".yml"),
strings.HasSuffix(m.Filename, ".yaml"):
return "actions" // GitHub Actions workflows

View File

@@ -1,11 +1,18 @@
package models
import (
"errors"
"fmt"
"strings"
"github.com/aquasecurity/go-dep-parser/pkg/java/jar"
"github.com/aquasecurity/trivy-db/pkg/db"
trivyDBTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/detector/library"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/javadb"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/samber/lo"
"golang.org/x/xerrors"
"github.com/future-architect/vuls/logging"
@@ -38,11 +45,13 @@ func (lss LibraryScanners) Total() (total int) {
// LibraryScanner has libraries information
type LibraryScanner struct {
Type string
Type ftypes.LangType
Libs []Library
// The path to the Lockfile is stored.
LockfilePath string `json:"path,omitempty"`
JavaDBClient *javadb.DB `json:"-"`
}
// Library holds the attribute of a package library
@@ -53,19 +62,25 @@ type Library struct {
// The Path to the library in the container image. Empty string when Lockfile scan.
// This field is used to convert the result JSON of a `trivy image` using trivy-to-vuls.
FilePath string
Digest string
}
// Scan : scan target library
func (s LibraryScanner) Scan() ([]VulnInfo, error) {
scanner, err := library.NewDriver(s.Type)
if err != nil {
return nil, xerrors.Errorf("Failed to new a library driver %s: %w", s.Type, err)
if s.Type == ftypes.Jar {
if err := s.improveJARInfo(); err != nil {
return nil, xerrors.Errorf("Failed to improve JAR information by trivy Java DB. err: %w", err)
}
}
scanner, ok := library.NewDriver(s.Type)
if !ok {
return nil, xerrors.Errorf("Failed to new a library driver for %s", s.Type)
}
var vulnerabilities = []VulnInfo{}
for _, pkg := range s.Libs {
tvulns, err := scanner.DetectVulnerabilities("", pkg.Name, pkg.Version)
if err != nil {
return nil, xerrors.Errorf("failed to detect %s vulnerabilities: %w", scanner.Type(), err)
return nil, xerrors.Errorf("Failed to detect %s vulnerabilities. err: %w", scanner.Type(), err)
}
if len(tvulns) == 0 {
continue
@@ -78,6 +93,45 @@ func (s LibraryScanner) Scan() ([]VulnInfo, error) {
return vulnerabilities, nil
}
func (s *LibraryScanner) improveJARInfo() error {
libs := make([]Library, 0, len(s.Libs))
for _, l := range s.Libs {
if l.Digest == "" {
// This is the case from pom.properties, it should be respected as is.
libs = append(libs, l)
continue
}
algorithm, sha1, found := strings.Cut(l.Digest, ":")
if !found || algorithm != "sha1" {
logging.Log.Debugf("No SHA1 hash found for %s in the digest: %q", l.FilePath, l.Digest)
libs = append(libs, l)
continue
}
foundProps, err := s.JavaDBClient.SearchBySHA1(sha1)
if err != nil {
if !errors.Is(err, jar.ArtifactNotFoundErr) {
return xerrors.Errorf("Failed to search trivy Java DB. err: %w", err)
}
logging.Log.Debugf("No record in Java DB for %s by SHA1: %s", l.FilePath, sha1)
libs = append(libs, l)
continue
}
foundLib := foundProps.Library()
l.Name = foundLib.Name
l.Version = foundLib.Version
libs = append(libs, l)
}
s.Libs = lo.UniqBy(libs, func(lib Library) string {
return fmt.Sprintf("%s::%s::%s", lib.Name, lib.Version, lib.FilePath)
})
return nil
}
func (s LibraryScanner) convertFanalToVuln(tvulns []types.DetectedVulnerability) (vulns []VulnInfo) {
for _, tvuln := range tvulns {
vinfo, err := s.getVulnDetail(tvuln)
@@ -131,10 +185,14 @@ func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[
// FindLockFiles is a list of filenames that is the target of findLock
var FindLockFiles = []string{
// dart/pub
ftypes.PubSpecLock,
// elixir/mix
ftypes.MixLock,
// node
ftypes.NpmPkgLock, ftypes.YarnLock, ftypes.PnpmLock,
// ruby
ftypes.GemfileLock,
ftypes.GemfileLock, "*.gemspec",
// rust
ftypes.CargoLock,
// php
@@ -142,13 +200,15 @@ var FindLockFiles = []string{
// python
ftypes.PipRequirements, ftypes.PipfileLock, ftypes.PoetryLock,
// .net
ftypes.NuGetPkgsLock, ftypes.NuGetPkgsConfig, "*.deps.json",
ftypes.NuGetPkgsLock, ftypes.NuGetPkgsConfig, "*.deps.json", "*Packages.props",
// gomod
ftypes.GoMod, ftypes.GoSum,
// java
ftypes.MavenPom, "*.jar", "*.war", "*.ear", "*.par", "*gradle.lockfile",
// C / C++
ftypes.ConanLock,
// Swift
ftypes.CocoaPodsLock, ftypes.SwiftResolved,
}
// GetLibraryKey returns target library key
@@ -156,7 +216,7 @@ func (s LibraryScanner) GetLibraryKey() string {
switch s.Type {
case ftypes.Bundler, ftypes.GemSpec:
return "ruby"
case ftypes.Cargo:
case ftypes.Cargo, ftypes.RustBinary:
return "rust"
case ftypes.Composer:
return "php"
@@ -170,8 +230,14 @@ func (s LibraryScanner) GetLibraryKey() string {
return ".net"
case ftypes.Pipenv, ftypes.Poetry, ftypes.Pip, ftypes.PythonPkg:
return "python"
case ftypes.ConanLock:
case ftypes.Conan:
return "c"
case ftypes.Pub:
return "dart"
case ftypes.Hex:
return "elixir"
case ftypes.Swift, ftypes.Cocoapods:
return "swift"
default:
return ""
}

View File

@@ -252,14 +252,14 @@ func libpkgToCdxComponents(libscanner models.LibraryScanner, libpkgToPURL map[st
Properties: &[]cdx.Property{
{
Name: "future-architect:vuls:Type",
Value: libscanner.Type,
Value: string(libscanner.Type),
},
},
},
}
for _, lib := range libscanner.Libs {
purl := packageurl.NewPackageURL(libscanner.Type, "", lib.Name, lib.Version, packageurl.Qualifiers{{Key: "file_path", Value: libscanner.LockfilePath}}, "").ToString()
purl := packageurl.NewPackageURL(string(libscanner.Type), "", lib.Name, lib.Version, packageurl.Qualifiers{{Key: "file_path", Value: libscanner.LockfilePath}}, "").ToString()
components = append(components, cdx.Component{
BOMRef: purl,
Type: cdx.ComponentTypeLibrary,

View File

@@ -16,7 +16,8 @@ import (
"time"
dio "github.com/aquasecurity/go-dep-parser/pkg/io"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
fanal "github.com/aquasecurity/trivy/pkg/fanal/analyzer"
tlog "github.com/aquasecurity/trivy/pkg/log"
debver "github.com/knqyf263/go-deb-version"
"github.com/future-architect/vuls/config"
@@ -29,12 +30,17 @@ import (
// Import library scanner
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/c/conan"
// Conda package is supported for SBOM, not for vulnerability scanning
// https://github.com/aquasecurity/trivy/blob/v0.49.1/pkg/detector/library/driver.go#L75-L77
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/conda/meta"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dart/pub"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/deps"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/packagesprops"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/elixir/mix"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/gradle"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/jar"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/pom"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/npm"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/pnpm"
@@ -44,13 +50,24 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/python/pipenv"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/python/poetry"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/ruby/bundler"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/rust/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/rust/cargo"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/swift/cocoapods"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/swift/swift"
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/ruby/gemspec"
// Excleded ones:
// Trivy can parse package.json but doesn't use dependencies info. Not use here
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/pkg"
// No dependency information included
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/ruby/gemspec"
// No dependency information included
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/python/packaging"
nmap "github.com/Ullaakut/nmap/v2"
// To avoid downloading Java DB at scan phase, use custom one for JAR files
_ "github.com/future-architect/vuls/scanner/trivy/jar"
// _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/jar"
)
type base struct {
@@ -609,6 +626,8 @@ func (l *base) parseSystemctlStatus(stdout string) string {
return ss[1]
}
var trivyLoggerInit = sync.OnceValue(func() error { return tlog.InitLogger(config.Conf.Debug, config.Conf.Quiet) })
func (l *base) scanLibraries() (err error) {
if len(l.LibraryScanners) != 0 {
return nil
@@ -621,6 +640,10 @@ func (l *base) scanLibraries() (err error) {
l.log.Info("Scanning Language-specific Packages...")
if err := trivyLoggerInit(); err != nil {
return xerrors.Errorf("Failed to init trivy logger. err: %w", err)
}
found := map[string]bool{}
detectFiles := l.ServerInfo.Lockfiles
@@ -720,8 +743,8 @@ func (l *base) scanLibraries() (err error) {
// AnalyzeLibrary : detects library defined in artifact such as lockfile or jar
func AnalyzeLibrary(ctx context.Context, path string, contents []byte, filemode os.FileMode, isOffline bool) (libraryScanners []models.LibraryScanner, err error) {
anal, err := analyzer.NewAnalyzerGroup(analyzer.AnalyzerOptions{
Group: analyzer.GroupBuiltin,
ag, err := fanal.NewAnalyzerGroup(fanal.AnalyzerOptions{
Group: fanal.GroupBuiltin,
DisabledAnalyzers: disabledAnalyzers,
})
if err != nil {
@@ -729,23 +752,51 @@ func AnalyzeLibrary(ctx context.Context, path string, contents []byte, filemode
}
var wg sync.WaitGroup
result := new(analyzer.AnalysisResult)
if err := anal.AnalyzeFile(
result := new(fanal.AnalysisResult)
info := &DummyFileInfo{name: filepath.Base(path), size: int64(len(contents)), filemode: filemode}
opts := fanal.AnalysisOptions{Offline: isOffline}
if err := ag.AnalyzeFile(
ctx,
&wg,
semaphore.NewWeighted(1),
result,
"",
path,
&DummyFileInfo{name: filepath.Base(path), size: int64(len(contents)), filemode: filemode},
info,
func() (dio.ReadSeekCloserAt, error) { return dio.NopCloser(bytes.NewReader(contents)), nil },
nil,
analyzer.AnalysisOptions{Offline: isOffline},
opts,
); err != nil {
return nil, xerrors.Errorf("Failed to get libs. err: %w", err)
}
wg.Wait()
// Post-analysis
composite, err := ag.PostAnalyzerFS()
if err != nil {
return nil, xerrors.Errorf("Failed to prepare filesystem for post-analysis. err: %w", err)
}
defer func() {
_ = composite.Cleanup()
}()
analyzerTypes := ag.RequiredPostAnalyzers(path, info)
if len(analyzerTypes) != 0 {
opener := func() (dio.ReadSeekCloserAt, error) { return dio.NopCloser(bytes.NewReader(contents)), nil }
tmpFilePath, err := composite.CopyFileToTemp(opener, info)
if err != nil {
return nil, xerrors.Errorf("Failed to copy file to temp. err: %w", err)
}
if err := composite.CreateLink(analyzerTypes, "", path, tmpFilePath); err != nil {
return nil, xerrors.Errorf("Failed to create link. err: %w", err)
}
if err = ag.PostAnalyze(ctx, composite, result, opts); err != nil {
return nil, xerrors.Errorf("Failed at post-analysis. err: %w", err)
}
}
libscan, err := convertLibWithScanner(result.Applications)
if err != nil {
return nil, xerrors.Errorf("Failed to convert libs. err: %w", err)
@@ -754,66 +805,76 @@ func AnalyzeLibrary(ctx context.Context, path string, contents []byte, filemode
return libraryScanners, nil
}
// https://github.com/aquasecurity/trivy/blob/84677903a6fa1b707a32d0e8b2bffc23dde52afa/pkg/fanal/analyzer/const.go
var disabledAnalyzers = []analyzer.Type{
// https://github.com/aquasecurity/trivy/blob/v0.49.1/pkg/fanal/analyzer/const.go
var disabledAnalyzers = []fanal.Type{
// ======
// OS
// ======
analyzer.TypeOSRelease,
analyzer.TypeAlpine,
analyzer.TypeAmazon,
analyzer.TypeCBLMariner,
analyzer.TypeDebian,
analyzer.TypePhoton,
analyzer.TypeCentOS,
analyzer.TypeRocky,
analyzer.TypeAlma,
analyzer.TypeFedora,
analyzer.TypeOracle,
analyzer.TypeRedHatBase,
analyzer.TypeSUSE,
analyzer.TypeUbuntu,
fanal.TypeOSRelease,
fanal.TypeAlpine,
fanal.TypeAmazon,
fanal.TypeCBLMariner,
fanal.TypeDebian,
fanal.TypePhoton,
fanal.TypeCentOS,
fanal.TypeRocky,
fanal.TypeAlma,
fanal.TypeFedora,
fanal.TypeOracle,
fanal.TypeRedHatBase,
fanal.TypeSUSE,
fanal.TypeUbuntu,
fanal.TypeUbuntuESM,
// OS Package
analyzer.TypeApk,
analyzer.TypeDpkg,
analyzer.TypeDpkgLicense,
analyzer.TypeRpm,
analyzer.TypeRpmqa,
fanal.TypeApk,
fanal.TypeDpkg,
fanal.TypeDpkgLicense,
fanal.TypeRpm,
fanal.TypeRpmqa,
// OS Package Repository
analyzer.TypeApkRepo,
fanal.TypeApkRepo,
// ============
// Non-packaged
// ============
fanal.TypeExecutable,
fanal.TypeSBOM,
// ============
// Image Config
// ============
analyzer.TypeApkCommand,
fanal.TypeApkCommand,
fanal.TypeHistoryDockerfile,
fanal.TypeImageConfigSecret,
// =================
// Structured Config
// =================
analyzer.TypeYaml,
analyzer.TypeJSON,
analyzer.TypeDockerfile,
analyzer.TypeTerraform,
analyzer.TypeCloudFormation,
analyzer.TypeHelm,
fanal.TypeAzureARM,
fanal.TypeCloudFormation,
fanal.TypeDockerfile,
fanal.TypeHelm,
fanal.TypeKubernetes,
fanal.TypeTerraform,
fanal.TypeTerraformPlan,
// ========
// License
// ========
analyzer.TypeLicenseFile,
fanal.TypeLicenseFile,
// ========
// Secrets
// ========
analyzer.TypeSecret,
fanal.TypeSecret,
// =======
// Red Hat
// =======
analyzer.TypeRedHatContentManifestType,
analyzer.TypeRedHatDockerfileType,
fanal.TypeRedHatContentManifestType,
fanal.TypeRedHatDockerfileType,
}
// DummyFileInfo is a dummy struct for libscan

View File

@@ -8,7 +8,6 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/jar"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/pom"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/npm"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/pnpm"
@@ -19,6 +18,8 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/python/poetry"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/ruby/bundler"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/rust/cargo"
_ "github.com/future-architect/vuls/scanner/trivy/jar"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)

View File

@@ -14,6 +14,7 @@ func convertLibWithScanner(apps []types.Application) ([]models.LibraryScanner, e
Name: lib.Name,
Version: lib.Version,
FilePath: lib.FilePath,
Digest: string(lib.Digest),
})
}
scanners = append(scanners, models.LibraryScanner{

115
scanner/trivy/jar/jar.go Normal file
View File

@@ -0,0 +1,115 @@
package jar
import (
"context"
"io/fs"
"os"
"path/filepath"
"strings"
"golang.org/x/xerrors"
dio "github.com/aquasecurity/go-dep-parser/pkg/io"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/parallel"
)
func init() {
analyzer.RegisterPostAnalyzer(analyzer.TypeJar, newJavaLibraryAnalyzer)
}
const version = 1
var requiredExtensions = []string{
".jar",
".war",
".ear",
".par",
}
// javaLibraryAnalyzer analyzes jar/war/ear/par files
type javaLibraryAnalyzer struct {
parallel int
}
func newJavaLibraryAnalyzer(options analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
return &javaLibraryAnalyzer{
parallel: options.Parallel,
}, nil
}
func (a *javaLibraryAnalyzer) PostAnalyze(ctx context.Context, input analyzer.PostAnalysisInput) (*analyzer.AnalysisResult, error) {
// It will be called on each JAR file
onFile := func(path string, info fs.FileInfo, r dio.ReadSeekerAt) (*types.Application, error) {
p := newParser(withSize(info.Size()), withFilePath(path))
parsedLibs, err := p.parse(r)
if err != nil {
return nil, xerrors.Errorf("Failed to parse %s. err: %w", path, err)
}
return toApplication(path, parsedLibs), nil
}
var apps []types.Application
onResult := func(app *types.Application) error {
if app == nil {
return nil
}
apps = append(apps, *app)
return nil
}
if err := parallel.WalkDir(ctx, input.FS, ".", a.parallel, onFile, onResult); err != nil {
return nil, xerrors.Errorf("Failed to walk dir. err: %w", err)
}
return &analyzer.AnalysisResult{
Applications: apps,
}, nil
}
func toApplication(rootFilePath string, libs []jarLibrary) *types.Application {
if len(libs) == 0 {
return nil
}
pkgs := make([]types.Package, 0, len(libs))
for _, lib := range libs {
libPath := rootFilePath
if lib.filePath != "" {
libPath = lib.filePath
}
pkgs = append(pkgs, types.Package{
Name: lib.name,
Version: lib.version,
FilePath: libPath,
Digest: lib.digest,
})
}
return &types.Application{
Type: types.Jar,
FilePath: rootFilePath,
Libraries: pkgs,
}
}
func (a *javaLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
ext := filepath.Ext(filePath)
for _, required := range requiredExtensions {
if strings.EqualFold(ext, required) {
return true
}
}
return false
}
func (a *javaLibraryAnalyzer) Type() analyzer.Type {
return analyzer.TypeJar
}
func (a *javaLibraryAnalyzer) Version() int {
return version
}

401
scanner/trivy/jar/parse.go Normal file
View File

@@ -0,0 +1,401 @@
package jar
import (
"archive/zip"
"bufio"
"fmt"
"io"
"os"
"path"
"path/filepath"
"regexp"
"strings"
dio "github.com/aquasecurity/go-dep-parser/pkg/io"
"github.com/aquasecurity/go-dep-parser/pkg/log"
"github.com/aquasecurity/trivy/pkg/digest"
"github.com/samber/lo"
"go.uber.org/zap"
"golang.org/x/xerrors"
)
var (
jarFileRegEx = regexp.MustCompile(`^([a-zA-Z0-9\._-]*[^-*])-(\d\S*(?:-SNAPSHOT)?).[jwep]ar$`)
)
type jarLibrary struct {
id string
name string
version string
filePath string
// SHA1 hash for later use at detect phase.
// When this record has come from pom.properties, no Java DB look up needed and this field must be left empty.
digest digest.Digest
}
type properties struct {
groupID string
artifactID string
version string
filePath string // path to file containing these props
digest digest.Digest
}
func (p properties) library() jarLibrary {
return jarLibrary{
name: fmt.Sprintf("%s:%s", p.groupID, p.artifactID),
version: p.version,
filePath: p.filePath,
digest: p.digest,
}
}
func (p properties) valid() bool {
return p.groupID != "" && p.artifactID != "" && p.version != ""
}
func (p properties) string() string {
return fmt.Sprintf("%s:%s:%s", p.groupID, p.artifactID, p.version)
}
type parser struct {
rootFilePath string
size int64
}
type option func(*parser)
func withFilePath(filePath string) option {
return func(p *parser) {
p.rootFilePath = filePath
}
}
func withSize(size int64) option {
return func(p *parser) {
p.size = size
}
}
func newParser(opts ...option) *parser {
p := &parser{}
for _, opt := range opts {
opt(p)
}
return p
}
func (p *parser) parse(r dio.ReadSeekerAt) ([]jarLibrary, error) {
libs, err := p.parseArtifact(p.rootFilePath, p.size, r)
if err != nil {
return nil, xerrors.Errorf("Failed to parse %s. err: %w", p.rootFilePath, err)
}
return removeLibraryDuplicates(libs), nil
}
// This function MUST NOT return empty list unless an error occurred.
// The least element contains file path and SHA1 digest, they can be used at detect phase to
// determine actual name and version.
func (p *parser) parseArtifact(filePath string, size int64, r dio.ReadSeekerAt) ([]jarLibrary, error) {
log.Logger.Debugw("Parsing Java artifacts...", zap.String("file", filePath))
sha1, err := digest.CalcSHA1(r)
if err != nil {
return nil, xerrors.Errorf("Failed to calculate SHA1. err: %w", err)
}
zr, err := zip.NewReader(r, size)
if err != nil {
return nil, xerrors.Errorf("Failed to open zip. err: %w", err)
}
// Try to extract artifactId and version from the file name
// e.g. spring-core-5.3.4-SNAPSHOT.jar => sprint-core, 5.3.4-SNAPSHOT
fileProps := parseFileName(filePath, sha1)
var libs []jarLibrary
var m manifest
var foundPomProps bool
for _, fileInJar := range zr.File {
switch {
case filepath.Base(fileInJar.Name) == "pom.properties":
props, err := parsePomProperties(fileInJar, filePath)
if err != nil {
return nil, xerrors.Errorf("Failed to parse %s. err: %w", fileInJar.Name, err)
}
libs = append(libs, props.library())
// Check if the pom.properties is for the original JAR/WAR/EAR
if fileProps.artifactID == props.artifactID && fileProps.version == props.version {
foundPomProps = true
}
case filepath.Base(fileInJar.Name) == "MANIFEST.MF":
m, err = parseManifest(fileInJar)
if err != nil {
return nil, xerrors.Errorf("Failed to parse MANIFEST.MF. err: %w", err)
}
case isArtifact(fileInJar.Name):
innerLibs, err := p.parseInnerJar(fileInJar, filePath) //TODO process inner deps
if err != nil {
log.Logger.Debugf("Failed to parse %s. err: %s", fileInJar.Name, err)
continue
}
libs = append(libs, innerLibs...)
}
}
// If pom.properties is found, it should be preferred than MANIFEST.MF.
if foundPomProps {
return libs, nil
}
manifestProps := m.properties(filePath, sha1)
if manifestProps.valid() {
return append(libs, manifestProps.library()), nil
}
// At this point, no library information from pom nor manifests.
// Add one from fileProps, which may have no artifact ID or version, but it will be
// rescued at detect phase by SHA1.
return append(libs, fileProps.library()), nil
}
func (p *parser) parseInnerJar(zf *zip.File, rootPath string) ([]jarLibrary, error) {
fr, err := zf.Open()
if err != nil {
return nil, xerrors.Errorf("Failed to open file %s. err: %w", zf.Name, err)
}
f, err := os.CreateTemp("", "inner-*")
if err != nil {
return nil, xerrors.Errorf("Failed to create tmp file for %s. err: %w", zf.Name, err)
}
defer func() {
f.Close()
os.Remove(f.Name())
}()
// Copy the file content to the temp file and rewind it at the beginning
if _, err = io.Copy(f, fr); err != nil {
return nil, xerrors.Errorf("Failed to copy file %s. err: %w", zf.Name, err)
}
if _, err = f.Seek(0, io.SeekStart); err != nil {
return nil, xerrors.Errorf("Failed to seek file %s. err: %w", zf.Name, err)
}
// build full path to inner jar
fullPath := path.Join(rootPath, zf.Name)
// Parse jar/war/ear recursively
innerLibs, err := p.parseArtifact(fullPath, int64(zf.UncompressedSize64), f)
if err != nil {
return nil, xerrors.Errorf("Failed to parse file %s. err: %w", zf.Name, err)
}
return innerLibs, nil
}
func isArtifact(name string) bool {
ext := filepath.Ext(name)
if ext == ".jar" || ext == ".ear" || ext == ".war" {
return true
}
return false
}
func parseFileName(filePath string, sha1 digest.Digest) properties {
fileName := filepath.Base(filePath)
packageVersion := jarFileRegEx.FindStringSubmatch(fileName)
if len(packageVersion) != 3 {
return properties{
filePath: filePath,
digest: sha1,
}
}
return properties{
artifactID: packageVersion[1],
version: packageVersion[2],
filePath: filePath,
digest: sha1,
}
}
func parsePomProperties(f *zip.File, filePath string) (properties, error) {
file, err := f.Open()
if err != nil {
return properties{}, xerrors.Errorf("Failed to open pom.properties. err: %w", err)
}
defer file.Close()
p := properties{
filePath: filePath,
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
switch {
case strings.HasPrefix(line, "groupId="):
p.groupID = strings.TrimPrefix(line, "groupId=")
case strings.HasPrefix(line, "artifactId="):
p.artifactID = strings.TrimPrefix(line, "artifactId=")
case strings.HasPrefix(line, "version="):
p.version = strings.TrimPrefix(line, "version=")
}
}
if err = scanner.Err(); err != nil {
return properties{}, xerrors.Errorf("Failed to scan %s. err: %w", f.Name, err)
}
return p, nil
}
type manifest struct {
implementationVersion string
implementationTitle string
implementationVendor string
implementationVendorID string
specificationTitle string
specificationVersion string
specificationVendor string
bundleName string
bundleVersion string
bundleSymbolicName string
}
func parseManifest(f *zip.File) (manifest, error) {
file, err := f.Open()
if err != nil {
return manifest{}, xerrors.Errorf("Failed to open MANIFEST.MF. err: %w", err)
}
defer file.Close()
var m manifest
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Skip variables. e.g. Bundle-Name: %bundleName
ss := strings.Fields(line)
if len(ss) <= 1 || (len(ss) > 1 && strings.HasPrefix(ss[1], "%")) {
continue
}
// It is not determined which fields are present in each application.
// In some cases, none of them are included, in which case they cannot be detected.
switch {
case strings.HasPrefix(line, "Implementation-Version:"):
m.implementationVersion = strings.TrimPrefix(line, "Implementation-Version:")
case strings.HasPrefix(line, "Implementation-Title:"):
m.implementationTitle = strings.TrimPrefix(line, "Implementation-Title:")
case strings.HasPrefix(line, "Implementation-Vendor:"):
m.implementationVendor = strings.TrimPrefix(line, "Implementation-Vendor:")
case strings.HasPrefix(line, "Implementation-Vendor-Id:"):
m.implementationVendorID = strings.TrimPrefix(line, "Implementation-Vendor-Id:")
case strings.HasPrefix(line, "Specification-Version:"):
m.specificationVersion = strings.TrimPrefix(line, "Specification-Version:")
case strings.HasPrefix(line, "Specification-Title:"):
m.specificationTitle = strings.TrimPrefix(line, "Specification-Title:")
case strings.HasPrefix(line, "Specification-Vendor:"):
m.specificationVendor = strings.TrimPrefix(line, "Specification-Vendor:")
case strings.HasPrefix(line, "Bundle-Version:"):
m.bundleVersion = strings.TrimPrefix(line, "Bundle-Version:")
case strings.HasPrefix(line, "Bundle-Name:"):
m.bundleName = strings.TrimPrefix(line, "Bundle-Name:")
case strings.HasPrefix(line, "Bundle-SymbolicName:"):
m.bundleSymbolicName = strings.TrimPrefix(line, "Bundle-SymbolicName:")
}
}
if err = scanner.Err(); err != nil {
return manifest{}, xerrors.Errorf("Failed to scan %s. err: %w", f.Name, err)
}
return m, nil
}
func (m manifest) properties(filePath string, sha1 digest.Digest) properties {
groupID, err := m.determineGroupID()
if err != nil {
return properties{}
}
artifactID, err := m.determineArtifactID()
if err != nil {
return properties{}
}
version, err := m.determineVersion()
if err != nil {
return properties{}
}
return properties{
groupID: groupID,
artifactID: artifactID,
version: version,
filePath: filePath,
digest: sha1,
}
}
func (m manifest) determineGroupID() (string, error) {
var groupID string
switch {
case m.implementationVendorID != "":
groupID = m.implementationVendorID
case m.bundleSymbolicName != "":
groupID = m.bundleSymbolicName
// e.g. "com.fasterxml.jackson.core.jackson-databind" => "com.fasterxml.jackson.core"
idx := strings.LastIndex(m.bundleSymbolicName, ".")
if idx > 0 {
groupID = m.bundleSymbolicName[:idx]
}
case m.implementationVendor != "":
groupID = m.implementationVendor
case m.specificationVendor != "":
groupID = m.specificationVendor
default:
return "", xerrors.New("No groupID found")
}
return strings.TrimSpace(groupID), nil
}
func (m manifest) determineArtifactID() (string, error) {
var artifactID string
switch {
case m.implementationTitle != "":
artifactID = m.implementationTitle
case m.specificationTitle != "":
artifactID = m.specificationTitle
case m.bundleName != "":
artifactID = m.bundleName
default:
return "", xerrors.New("No artifactID found")
}
return strings.TrimSpace(artifactID), nil
}
func (m manifest) determineVersion() (string, error) {
var version string
switch {
case m.implementationVersion != "":
version = m.implementationVersion
case m.specificationVersion != "":
version = m.specificationVersion
case m.bundleVersion != "":
version = m.bundleVersion
default:
return "", xerrors.New("No version found")
}
return strings.TrimSpace(version), nil
}
func removeLibraryDuplicates(libs []jarLibrary) []jarLibrary {
return lo.UniqBy(libs, func(lib jarLibrary) string {
return fmt.Sprintf("%s::%s::%s", lib.name, lib.version, lib.filePath)
})
}

View File

@@ -8,7 +8,7 @@ import (
"os"
"path/filepath"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
"github.com/google/subcommands"
"github.com/k0kubun/pp"
@@ -94,6 +94,8 @@ func (*ReportCmd) Usage() string {
[-pipe]
[-http="http://vuls-report-server"]
[-trivy-cachedb-dir=/path/to/dir]
[-trivy-java-db-repository="OCI-repository-for-trivy-java-db"]
[-trivy-skip-java-db-update]
[RFC3339 datetime format under results dir]
`
@@ -174,7 +176,11 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&config.Conf.Pipe, "pipe", false, "Use args passed via PIPE")
f.StringVar(&config.Conf.TrivyCacheDBDir, "trivy-cachedb-dir",
utils.DefaultCacheDir(), "/path/to/dir")
fsutils.CacheDir(), "/path/to/dir")
f.StringVar(&config.Conf.TrivyJavaDBRepository, "trivy-java-db-repository",
"ghcr.io/aquasecurity/trivy-java-db", "Trivy Java DB Repository")
f.BoolVar(&config.Conf.TrivySkipJavaDBUpdate, "trivy-skip-java-db-update",
false, "Skip Trivy Java DB Update")
}
// Execute execute

View File

@@ -8,7 +8,7 @@ import (
"os"
"path/filepath"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
"github.com/google/subcommands"
"github.com/k0kubun/pp"
@@ -172,7 +172,7 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&config.Conf.Pipe, "pipe", false, "Use args passed via PIPE")
f.StringVar(&config.Conf.TrivyCacheDBDir, "trivy-cachedb-dir",
utils.DefaultCacheDir(), "/path/to/dir")
fsutils.CacheDir(), "/path/to/dir")
}
// Execute execute

View File

@@ -50,7 +50,6 @@ func (*ScanCmd) Usage() string {
[-vvv]
[-ips]
[SERVER]...
`
}

View File

@@ -9,7 +9,7 @@ import (
"os"
"path/filepath"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/detector"
"github.com/future-architect/vuls/logging"
@@ -103,7 +103,7 @@ func (p *TuiCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&config.Conf.Pipe, "pipe", false, "Use stdin via PIPE")
f.StringVar(&config.Conf.TrivyCacheDBDir, "trivy-cachedb-dir",
utils.DefaultCacheDir(), "/path/to/dir")
fsutils.CacheDir(), "/path/to/dir")
}
// Execute execute