mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-06 12:51:17 -08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
073b315737 | ||
|
|
47c46fbe17 | ||
|
|
39572968bb | ||
|
|
4383764cae | ||
|
|
e0ef0563ce | ||
|
|
d9cf2c487d |
@@ -1 +1,2 @@
|
||||
.circleci
|
||||
imgs
|
||||
|
||||
123
README.md
123
README.md
@@ -136,7 +136,7 @@ $ sudo dpkg -i trivy_0.0.15_Linux-64bit.deb
|
||||
|
||||
## Mac OS X / Homebrew
|
||||
|
||||
You can use homebrew on OS X.
|
||||
You can use homebrew on Mac OS.
|
||||
|
||||
```
|
||||
$ brew tap knqyf263/trivy
|
||||
@@ -145,7 +145,7 @@ $ brew install knqyf263/trivy/trivy
|
||||
|
||||
## Binary (Including Windows)
|
||||
|
||||
Go to [the releases page](https://github.com/knqyf263/trivy/releases), find the version you want, and download the zip file. Unpack the zip file, and put the binary to somewhere you want (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
|
||||
Get the latest version from [this page](https://github.com/knqyf263/trivy/releases/latest), and download the archive file for your operating system/architecture. Unpack the archive, and put the binary somewhere in your `$PATH` (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
|
||||
|
||||
You need to install `rpm` command for scanning RHEL/CentOS.
|
||||
|
||||
@@ -516,6 +516,115 @@ $ trivy -f json -o results.json golang:1.12-alpine
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
```
|
||||
[
|
||||
{
|
||||
"Target": "php-app/composer.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "node-app/package-lock.json",
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16487",
|
||||
"PkgName": "lodash",
|
||||
"InstalledVersion": "4.17.4",
|
||||
"FixedVersion": "\u003e=4.17.11",
|
||||
"Title": "lodash: Prototype pollution in utilities function",
|
||||
"Description": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487",
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Target": "trivy-ci-test (alpine 3.7.1)",
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16840",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r1",
|
||||
"Title": "curl: Use-after-free when closing \"easy\" handle in Curl_close()",
|
||||
"Description": "A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. ",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2019-3822",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r2",
|
||||
"Title": "curl: NTLMv2 type-3 header stack buffer overflow",
|
||||
"Description": "libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. ",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://curl.haxx.se/docs/CVE-2019-3822.html",
|
||||
"https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E"
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16839",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r1",
|
||||
"Title": "curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()",
|
||||
"Description": "Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-19486",
|
||||
"PkgName": "git",
|
||||
"InstalledVersion": "2.15.2-r0",
|
||||
"FixedVersion": "2.15.3-r0",
|
||||
"Title": "git: Improper handling of PATH allows for commands to be executed from the current directory",
|
||||
"Description": "Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://usn.ubuntu.com/3829-1/",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-17456",
|
||||
"PkgName": "git",
|
||||
"InstalledVersion": "2.15.2-r0",
|
||||
"FixedVersion": "2.15.3-r0",
|
||||
"Title": "git: arbitrary code execution via .gitmodules",
|
||||
"Description": "Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \"git clone\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"http://www.securitytracker.com/id/1041811",
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Target": "python-app/Pipfile.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "ruby-app/Gemfile.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "rust-app/Cargo.lock",
|
||||
"Vulnerabilities": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Filter the vulnerabilities by severities
|
||||
|
||||
```
|
||||
@@ -942,7 +1051,7 @@ The results of [composer:1.7.2](https://hub.docker.com/_/composer?tab=tags) usin
|
||||
|
||||
<img src="imgs/alpine.png" width="500">
|
||||
|
||||
`Trivy` has high accuracy and high precision, while GCR did not detect any vulnerability. Althogh Docker Hub has many True Positive, it also has many False Positive.
|
||||
`Trivy` has high accuracy and high precision, while GCR did not detect any vulnerability. Although Docker Hub has many True Positive, it also has many False Positive.
|
||||
|
||||
### RHEL/CentOS
|
||||
|
||||
@@ -968,8 +1077,8 @@ In the case of other OS, the result is similar to other container scanners.
|
||||
However, the purpose of this database is to make it possible to know what packages has backported fixes.
|
||||
As README says, it is not a complete database of all security issues in Alpine.
|
||||
|
||||
`Trivy` collects vulnerability information in Alpine Linux from [Alpine LInux Redmine](https://bugs.alpinelinux.org/projects/alpine/issues).
|
||||
Then, those vulnerabilities will be saved on [vuln-list](https://github.com/knqyf263/vuln-list/tree/master/alpine)
|
||||
`Trivy` collects vulnerability information in Alpine Linux from [Alpine Linux Redmine](https://bugs.alpinelinux.org/projects/alpine/issues).
|
||||
Then, those vulnerabilities will be saved on [vuln-list](https://github.com/knqyf263/vuln-list/tree/master/alpine).
|
||||
|
||||
`alpine-secdb` has 6959 vulnerabilities (as of 2019/05/12).
|
||||
`vuln-list` has 11101 vulnerabilities related with Alpine Linux (as of 2019/05/12).
|
||||
@@ -977,7 +1086,7 @@ There is a difference in detection accuracy because the number of vulnerabilitie
|
||||
|
||||
In addition, `Trivy` analyzes the middle layer as well and find out which version of the library was used for static linking.
|
||||
|
||||
`Clair` can not handle the following cases because it analyzes the image after applying the all layers.
|
||||
`Clair` can not handle the following cases because it analyzes the image after applying all layers.
|
||||
|
||||
```
|
||||
RUN apk add --no-cache sqlite-dev \
|
||||
@@ -1001,7 +1110,7 @@ Also, `Anchore Engine` needs some steps to start scanning.
|
||||
|
||||
## vs Quay, Docker Hub, GCR
|
||||
|
||||
As `Quay` seems to use `Clair` internally, it has the same accuracy with `Clair`. `Docker Hub` can scan only official images. `GCR` hardly detects vulnerability on Alpine Linux. Also, it is locked to a specific registry.
|
||||
As `Quay` seems to use `Clair` internally, it has the same accuracy than `Clair`. `Docker Hub` can scan only official images. `GCR` hardly detects vulnerabilities on Alpine Linux. Also, it is locked to a specific registry.
|
||||
|
||||
`Trivy` can be used regardless of the registry. In addition, it is easy to be integrated with CI/CD services.
|
||||
|
||||
|
||||
@@ -103,9 +103,7 @@ OPTIONS:
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return pkg.Run(c)
|
||||
}
|
||||
app.Action = pkg.Run
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
|
||||
@@ -105,9 +105,7 @@ func Put(root *bolt.Bucket, nestedBucket, key string, value interface{}) error {
|
||||
return nested.Put([]byte(key), v)
|
||||
}
|
||||
func BatchUpdate(fn func(tx *bolt.Tx) error) error {
|
||||
err := db.Batch(func(tx *bolt.Tx) error {
|
||||
return fn(tx)
|
||||
})
|
||||
err := db.Batch(fn)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error in batch update: %w", err)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
type Results []Result
|
||||
|
||||
type Result struct {
|
||||
FileName string `json:"file"`
|
||||
Vulnerabilities []vulnerability.DetectedVulnerability
|
||||
FileName string `json:"Target"`
|
||||
Vulnerabilities []vulnerability.DetectedVulnerability `json:"Vulnerabilities"`
|
||||
}
|
||||
|
||||
type Writer interface {
|
||||
@@ -84,11 +84,7 @@ type JsonWriter struct {
|
||||
}
|
||||
|
||||
func (jw JsonWriter) Write(results Results) error {
|
||||
out := map[string][]vulnerability.DetectedVulnerability{}
|
||||
for _, result := range results {
|
||||
out[result.FileName] = result.Vulnerabilities
|
||||
}
|
||||
output, err := json.MarshalIndent(out, "", " ")
|
||||
output, err := json.MarshalIndent(results, "", " ")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to marshal json: %w", err)
|
||||
}
|
||||
|
||||
12
pkg/run.go
12
pkg/run.go
@@ -102,6 +102,10 @@ func Run(c *cli.Context) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.SetVersion(cliVersion); err != nil {
|
||||
return xerrors.Errorf("unexpected error: %w", err)
|
||||
}
|
||||
|
||||
// When specifying no image name and file name
|
||||
if noTarget {
|
||||
return nil
|
||||
@@ -156,23 +160,19 @@ func Run(c *cli.Context) (err error) {
|
||||
}
|
||||
|
||||
var writer report.Writer
|
||||
switch c.String("format") {
|
||||
switch format := c.String("format"); format {
|
||||
case "table":
|
||||
writer = &report.TableWriter{Output: output}
|
||||
case "json":
|
||||
writer = &report.JsonWriter{Output: output}
|
||||
default:
|
||||
xerrors.New("unknown format")
|
||||
return xerrors.Errorf("unknown format: %v", format)
|
||||
}
|
||||
|
||||
if err = writer.Write(results); err != nil {
|
||||
return xerrors.Errorf("failed to write results: %w", err)
|
||||
}
|
||||
|
||||
if err = db.SetVersion(cliVersion); err != nil {
|
||||
return xerrors.Errorf("unexpected error: %w", err)
|
||||
}
|
||||
|
||||
exitCode := c.Int("exit-code")
|
||||
if exitCode != 0 {
|
||||
for _, result := range results {
|
||||
|
||||
@@ -41,7 +41,8 @@ func Scan(files extractor.FileMap) (string, string, []vulnerability.DetectedVuln
|
||||
case fos.RedHat, fos.CentOS:
|
||||
s = redhat.NewScanner()
|
||||
default:
|
||||
return "", "", nil, xerrors.Errorf("unsupported os : %s", os.Family)
|
||||
log.Logger.Warnf("unsupported os : %s", os.Family)
|
||||
return "", "", nil, nil
|
||||
}
|
||||
pkgs, err := analyzer.GetPackages(files)
|
||||
if err != nil {
|
||||
|
||||
@@ -48,8 +48,10 @@ func ScanImage(imageName, filePath string) (map[string][]vulnerability.DetectedV
|
||||
return nil, xerrors.Errorf("failed to scan image: %w", err)
|
||||
|
||||
}
|
||||
imageDetail := fmt.Sprintf("%s (%s %s)", target, osFamily, osVersion)
|
||||
results[imageDetail] = osVulns
|
||||
if osFamily != "" {
|
||||
imageDetail := fmt.Sprintf("%s (%s %s)", target, osFamily, osVersion)
|
||||
results[imageDetail] = osVulns
|
||||
}
|
||||
|
||||
libVulns, err := library.Scan(files)
|
||||
if err != nil {
|
||||
|
||||
@@ -89,17 +89,16 @@ func getDetail(vulnID string) (Severity, string, string, []string) {
|
||||
|
||||
func getSeverity(details map[string]Vulnerability) Severity {
|
||||
for _, source := range sources {
|
||||
d, ok := details[source]
|
||||
if !ok {
|
||||
switch d, ok := details[source]; {
|
||||
case !ok:
|
||||
continue
|
||||
}
|
||||
if d.CvssScore > 0 {
|
||||
case d.CvssScore > 0:
|
||||
return scoreToSeverity(d.CvssScore)
|
||||
} else if d.CvssScoreV3 > 0 {
|
||||
case d.CvssScoreV3 > 0:
|
||||
return scoreToSeverity(d.CvssScoreV3)
|
||||
} else if d.Severity != 0 {
|
||||
case d.Severity != 0:
|
||||
return d.Severity
|
||||
} else if d.SeverityV3 != 0 {
|
||||
case d.SeverityV3 != 0:
|
||||
return d.SeverityV3
|
||||
}
|
||||
}
|
||||
@@ -151,14 +150,16 @@ func getReferences(details map[string]Vulnerability) []string {
|
||||
}
|
||||
|
||||
func scoreToSeverity(score float64) Severity {
|
||||
if score >= 9.0 {
|
||||
switch {
|
||||
case score >= 9.0:
|
||||
return SeverityCritical
|
||||
} else if score >= 7.0 {
|
||||
case score >= 7.0:
|
||||
return SeverityHigh
|
||||
} else if score >= 4.0 {
|
||||
case score >= 4.0:
|
||||
return SeverityMedium
|
||||
} else if score > 0.0 {
|
||||
case score > 0.0:
|
||||
return SeverityLow
|
||||
default:
|
||||
return SeverityUnknown
|
||||
}
|
||||
return SeverityUnknown
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func Update() (err error) {
|
||||
return xerrors.Errorf("error in Alpine OVAL update: %w", err)
|
||||
}
|
||||
|
||||
//Update RedHat
|
||||
// Update RedHat
|
||||
log.Logger.Info("Updating RedHat data...")
|
||||
if err = redhat.Update(dir, updatedFiles); err != nil {
|
||||
return xerrors.Errorf("error in RedHat update: %w", err)
|
||||
@@ -65,7 +65,7 @@ func Update() (err error) {
|
||||
return xerrors.Errorf("error in Debian OVAL update: %w", err)
|
||||
}
|
||||
|
||||
//Update Ubuntu
|
||||
// Update Ubuntu
|
||||
log.Logger.Info("Updating Ubuntu data...")
|
||||
if err = ubuntu.Update(dir, updatedFiles); err != nil {
|
||||
return xerrors.Errorf("error in Ubuntu update: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user