mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 07:29:00 -08:00
Compare commits
5 Commits
dependabot
...
v0.64.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86ee3c1176 | ||
|
|
4e1272283a | ||
|
|
9a7d38432c | ||
|
|
53adfba3c2 | ||
|
|
8cf1bf9f6f |
1
.github/workflows/semantic-pr.yaml
vendored
1
.github/workflows/semantic-pr.yaml
vendored
@@ -67,6 +67,7 @@ jobs:
|
||||
distroless
|
||||
windows
|
||||
minimos
|
||||
rootio
|
||||
|
||||
# Languages
|
||||
ruby
|
||||
|
||||
@@ -1 +1 @@
|
||||
{".":"0.64.0"}
|
||||
{".":"0.64.1"}
|
||||
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [0.64.1](https://github.com/aquasecurity/trivy/compare/v0.64.0...v0.64.1) (2025-07-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **alma:** parse epochs from rpmqa file [backport: release/v0.64] ([#9119](https://github.com/aquasecurity/trivy/issues/9119)) ([8cf1bf9](https://github.com/aquasecurity/trivy/commit/8cf1bf9f6f86936ee7dcd29e0d1cd1ec106e28f6))
|
||||
* **cli:** Add more non-sensitive flags to telemetry [backport: release/v0.64] ([#9124](https://github.com/aquasecurity/trivy/issues/9124)) ([9a7d384](https://github.com/aquasecurity/trivy/commit/9a7d38432cf00f00970259e5ac3edd060e00ccff))
|
||||
* **misconf:** skip rewriting expr if attr is nil [backport: release/v0.64] ([#9127](https://github.com/aquasecurity/trivy/issues/9127)) ([4e12722](https://github.com/aquasecurity/trivy/commit/4e1272283a643bfca2d7231d286006219715fada))
|
||||
* **rootio:** check full version to detect `root.io` packages [backport: release/v0.64] ([#9120](https://github.com/aquasecurity/trivy/issues/9120)) ([53adfba](https://github.com/aquasecurity/trivy/commit/53adfba3c25664b01e3a36fdec334b39b53c07f1))
|
||||
|
||||
## [0.64.0](https://github.com/aquasecurity/trivy/compare/v0.63.0...v0.64.0) (2025-06-30)
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,40 @@
|
||||
```
|
||||
--clear-cache
|
||||
--debug
|
||||
--dependency-tree
|
||||
--detection-priority
|
||||
--distro
|
||||
--exit-code
|
||||
--exit-on-eol
|
||||
--format
|
||||
--ignore-status
|
||||
--ignore-unfixed
|
||||
--image-config-scanners
|
||||
--include-deprecated-checks
|
||||
--include-dev-deps
|
||||
--include-non-failures
|
||||
--insecure
|
||||
--license-full
|
||||
--list-all-pkgs
|
||||
--misconfig-scanners
|
||||
--offline-scan
|
||||
--parallel
|
||||
--password-stdin
|
||||
--pkg-relationships
|
||||
--pkg-types
|
||||
--quiet
|
||||
--redis-tls
|
||||
--removed-pkgs
|
||||
--report
|
||||
--scanners
|
||||
--severity
|
||||
--show-suppressed
|
||||
--skip-check-update
|
||||
--skip-version-check
|
||||
--skip-vex-repo-update
|
||||
--slow
|
||||
--tf-exclude-downloaded-modules
|
||||
--timeout
|
||||
--trace
|
||||
--vuln-severity-source
|
||||
```
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/detector/ospkg/driver"
|
||||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/scan/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -37,7 +38,7 @@ func isRootIOEnvironment(osFamily ftypes.OSType, pkgs []ftypes.Package) bool {
|
||||
// hasPackageWithPattern checks if any package version matches the specified pattern
|
||||
func hasPackageWithPattern(pkgs []ftypes.Package, pattern *regexp.Regexp) bool {
|
||||
for _, pkg := range pkgs {
|
||||
if pattern.MatchString(pkg.Version) {
|
||||
if pattern.MatchString(utils.FormatVersion(pkg)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestProvider(t *testing.T) {
|
||||
name: "Debian with .root.io package",
|
||||
osFamily: ftypes.Debian,
|
||||
pkgs: []ftypes.Package{
|
||||
{Name: "libc6", Version: "2.31-13+deb11u4.root.io"},
|
||||
{Name: "libc6", Version: "2.31", Release: "13+deb11u4.root.io"},
|
||||
{Name: "bash", Version: "5.1-2+deb11u1"},
|
||||
},
|
||||
want: true,
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
@@ -50,6 +51,7 @@ func (a rpmqaPkgAnalyzer) parseRpmqaManifest(r xio.ReadSeekerAt) ([]types.Packag
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
var name, ver, rel, sourceRpm, arch string
|
||||
var epoch int
|
||||
// %{NAME}\t%{VERSION}-%{RELEASE}\t%{INSTALLTIME}\t%{BUILDTIME}\t%{VENDOR}\t(none)\t%{SIZE}\t%{ARCH}\t%{EPOCHNUM}\t%{SOURCERPM}
|
||||
s := strings.Split(line, "\t")
|
||||
if len(s) != 10 {
|
||||
@@ -68,12 +70,18 @@ func (a rpmqaPkgAnalyzer) parseRpmqaManifest(r xio.ReadSeekerAt) ([]types.Packag
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to split source rpm: %w", err)
|
||||
}
|
||||
epoch, err = strconv.Atoi(s[8])
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to parse epoch number (%s): %w", s[8], err)
|
||||
}
|
||||
pkgs = append(pkgs, types.Package{
|
||||
Name: name,
|
||||
Version: ver,
|
||||
Epoch: epoch,
|
||||
Release: rel,
|
||||
Arch: arch,
|
||||
SrcName: srcName,
|
||||
SrcEpoch: epoch,
|
||||
SrcVersion: srcVer,
|
||||
SrcRelease: srcRel,
|
||||
})
|
||||
|
||||
@@ -21,7 +21,8 @@ func TestParseMarinerDistrolessManifest(t *testing.T) {
|
||||
name: "happy path",
|
||||
content: `mariner-release 2.0-12.cm2 1653816591 1653753130 Microsoft Corporation (none) 580 noarch 0 mariner-release-2.0-12.cm2.src.rpm
|
||||
filesystem 1.1-9.cm2 1653816591 1653628924 Microsoft Corporation (none) 7596 x86_64 0 filesystem-1.1-9.cm2.src.rpm
|
||||
glibc 2.35-2.cm2 1653816591 1653628955 Microsoft Corporation (none) 10855265 x86_64 0 glibc-2.35-2.cm2.src.rpm`,
|
||||
glibc 2.35-2.cm2 1653816591 1653628955 Microsoft Corporation (none) 10855265 x86_64 0 glibc-2.35-2.cm2.src.rpm
|
||||
ca-certificates-base 3.0.0-8.azl3 1748892790 1735838940 Microsoft Corporation (none) 130628 noarch 1 ca-certificates-3.0.0-8.azl3.src.rpm`,
|
||||
wantPkgs: []types.Package{
|
||||
{
|
||||
Name: "mariner-release",
|
||||
@@ -50,6 +51,17 @@ glibc 2.35-2.cm2 1653816591 1653628955 Microsoft Corporation (none) 10855265 x86
|
||||
SrcVersion: "2.35",
|
||||
SrcRelease: "2.cm2",
|
||||
},
|
||||
{
|
||||
Name: "ca-certificates-base",
|
||||
Version: "3.0.0",
|
||||
Epoch: 1,
|
||||
Release: "8.azl3",
|
||||
Arch: "noarch",
|
||||
SrcName: "ca-certificates",
|
||||
SrcEpoch: 1,
|
||||
SrcVersion: "3.0.0",
|
||||
SrcRelease: "8.azl3",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ var (
|
||||
ConfigName: "cache.clear",
|
||||
Usage: "clear image caches without scanning",
|
||||
Removed: `Use "trivy clean --scan-cache" instead`,
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
CacheBackendFlag = Flag[string]{
|
||||
Name: "cache-backend",
|
||||
@@ -36,6 +37,7 @@ var (
|
||||
Name: "redis-tls",
|
||||
ConfigName: "cache.redis.tls",
|
||||
Usage: "enable redis TLS with public certificates, if using redis as cache backend",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
RedisCACertFlag = Flag[string]{
|
||||
Name: "redis-ca",
|
||||
|
||||
@@ -24,11 +24,13 @@ var (
|
||||
types.SecretScanner,
|
||||
}),
|
||||
Usage: "comma-separated list of what security issues to detect on container image configurations",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ScanRemovedPkgsFlag = Flag[bool]{
|
||||
Name: "removed-pkgs",
|
||||
ConfigName: "image.removed-pkgs",
|
||||
Usage: "detect vulnerabilities of removed packages (only for Alpine)",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
InputFlag = Flag[string]{
|
||||
Name: "input",
|
||||
|
||||
@@ -10,6 +10,7 @@ var (
|
||||
Name: "license-full",
|
||||
ConfigName: "license.full",
|
||||
Usage: "eagerly look for licenses in source code headers and license files",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
IgnoredLicenses = Flag[[]string]{
|
||||
Name: "ignored-licenses",
|
||||
|
||||
@@ -36,6 +36,7 @@ var (
|
||||
Name: "include-non-failures",
|
||||
ConfigName: "misconfiguration.include-non-failures",
|
||||
Usage: "include successes, available with '--scanners misconfig'",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
HelmValuesFileFlag = Flag[[]string]{
|
||||
Name: "helm-values",
|
||||
@@ -82,6 +83,7 @@ var (
|
||||
Name: "tf-exclude-downloaded-modules",
|
||||
ConfigName: "misconfiguration.terraform.exclude-downloaded-modules",
|
||||
Usage: "exclude misconfigurations for downloaded terraform modules",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ChecksBundleRepositoryFlag = Flag[string]{
|
||||
Name: "checks-bundle-repository",
|
||||
|
||||
@@ -25,6 +25,7 @@ var (
|
||||
Name: "password-stdin",
|
||||
ConfigName: "registry.password-stdin",
|
||||
Usage: "password from stdin. Comma-separated passwords are not supported.",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
RegistryTokenFlag = Flag[string]{
|
||||
Name: "registry-token",
|
||||
|
||||
@@ -11,6 +11,7 @@ var (
|
||||
Name: "include-deprecated-checks",
|
||||
ConfigName: "rego.include-deprecated-checks",
|
||||
Usage: "include deprecated checks",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
SkipCheckUpdateFlag = Flag[bool]{
|
||||
Name: "skip-check-update",
|
||||
@@ -23,11 +24,13 @@ var (
|
||||
Deprecated: true,
|
||||
},
|
||||
},
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
TraceFlag = Flag[bool]{
|
||||
Name: "trace",
|
||||
ConfigName: "rego.trace",
|
||||
Usage: "enable more verbose trace output for custom queries",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ConfigCheckFlag = Flag[[]string]{
|
||||
Name: "config-check",
|
||||
|
||||
@@ -55,6 +55,7 @@ var (
|
||||
Name: "dependency-tree",
|
||||
ConfigName: "dependency-tree",
|
||||
Usage: "[EXPERIMENTAL] show dependency origin tree of vulnerable packages",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ListAllPkgsFlag = Flag[bool]{
|
||||
Name: "list-all-pkgs",
|
||||
@@ -77,11 +78,13 @@ var (
|
||||
Name: "exit-code",
|
||||
ConfigName: "exit-code",
|
||||
Usage: "specify exit code when any security issues are found",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ExitOnEOLFlag = Flag[int]{
|
||||
Name: "exit-on-eol",
|
||||
ConfigName: "exit-on-eol",
|
||||
Usage: "exit with the specified code when the OS reaches end of service/life",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
OutputFlag = Flag[string]{
|
||||
Name: "output",
|
||||
|
||||
@@ -30,6 +30,7 @@ var (
|
||||
Name: "offline-scan",
|
||||
ConfigName: "scan.offline",
|
||||
Usage: "do not issue API requests to identify dependencies",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ScannersFlag = Flag[[]string]{
|
||||
Name: "scanners",
|
||||
@@ -79,12 +80,14 @@ var (
|
||||
Default: false,
|
||||
Usage: "scan over time with lower CPU and memory utilization",
|
||||
Deprecated: `Use "--parallel 1" instead.`,
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
ParallelFlag = Flag[int]{
|
||||
Name: "parallel",
|
||||
ConfigName: "scan.parallel",
|
||||
Default: 5,
|
||||
Usage: "number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
SBOMSourcesFlag = Flag[[]string]{
|
||||
Name: "sbom-sources",
|
||||
@@ -119,11 +122,13 @@ var (
|
||||
Name: "distro",
|
||||
ConfigName: "scan.distro",
|
||||
Usage: "[EXPERIMENTAL] specify a distribution, <family>/<version>",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
SkipVersionCheckFlag = Flag[bool]{
|
||||
Name: "skip-version-check",
|
||||
ConfigName: "scan.skip-version-check",
|
||||
Usage: "suppress notices about version updates and Trivy announcements",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
DisableTelemetryFlag = Flag[bool]{
|
||||
Name: "disable-telemetry",
|
||||
|
||||
@@ -15,6 +15,7 @@ var (
|
||||
Name: "ignore-unfixed",
|
||||
ConfigName: "vulnerability.ignore-unfixed",
|
||||
Usage: "display only fixed vulnerabilities",
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
IgnoreStatusFlag = Flag[[]string]{
|
||||
Name: "ignore-status",
|
||||
@@ -32,6 +33,7 @@ var (
|
||||
Name: "skip-vex-repo-update",
|
||||
ConfigName: "vulnerability.skip-vex-repo-update",
|
||||
Usage: `[EXPERIMENTAL] Skip VEX Repository update`,
|
||||
TelemetrySafe: true,
|
||||
}
|
||||
VulnSeveritySourceFlag = Flag[[]string]{
|
||||
Name: "vuln-severity-source",
|
||||
|
||||
@@ -17,6 +17,11 @@ type wrappedDocument struct {
|
||||
}
|
||||
|
||||
func ParsePolicyFromAttr(attr *terraform.Attribute, owner *terraform.Block, modules terraform.Modules) (*iam.Document, error) {
|
||||
if attr == nil {
|
||||
return &iam.Document{
|
||||
Metadata: owner.GetMetadata(),
|
||||
}, nil
|
||||
}
|
||||
attr.RewriteExpr(func(e hclsyntax.Expression) hclsyntax.Expression {
|
||||
if te, ok := e.(*hclsyntax.TemplateExpr); ok {
|
||||
return &terraform.PartialTemplateExpr{TemplateExpr: te}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
|
||||
"github.com/aquasecurity/iamgo"
|
||||
"github.com/aquasecurity/trivy/pkg/iac/providers/aws/iam"
|
||||
"github.com/aquasecurity/trivy/pkg/iac/terraform"
|
||||
@@ -140,11 +142,20 @@ func findAttachmentPolicy(modules terraform.Modules) func(resource *terraform.Bl
|
||||
}
|
||||
}
|
||||
|
||||
// Searching for a referenced block only makes sense for traversal expressions,
|
||||
// since only they can directly reference other blocks in the configuration.
|
||||
switch attr.HCLAttribute().Expr.(type) {
|
||||
case *hclsyntax.RelativeTraversalExpr, *hclsyntax.ScopeTraversalExpr:
|
||||
if block, err := modules.GetReferencedBlock(attr, resource); err == nil {
|
||||
return findPolicy(modules)(block)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
return &iam.Policy{
|
||||
Metadata: resource.GetMetadata(),
|
||||
Document: iam.Document{
|
||||
Metadata: resource.GetMetadata(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,6 +338,32 @@ resource "aws_iam_role_policy_attachment" "test" {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "policy is template with unknown part",
|
||||
terraform: `resource "aws_iam_role" "default" {
|
||||
name = "test"
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "amazon_eks_cluster_policy" {
|
||||
role = aws_iam_role.default.name
|
||||
policy_arn = format("arn:%s:iam::aws:policy/AmazonEKSClusterPolicy", data.aws_partition.current.partition)
|
||||
}
|
||||
|
||||
|
||||
data "aws_partition" "current" {}
|
||||
`,
|
||||
expected: []iam.Role{
|
||||
{
|
||||
Name: iacTypes.StringTest("test"),
|
||||
Policies: []iam.Policy{
|
||||
{
|
||||
Name: iacTypes.StringTest(""),
|
||||
Document: iam.Document{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -834,7 +834,14 @@ func safeOp[T any](a *Attribute, fn func(cty.Value) T) T {
|
||||
// RewriteExpr applies the given function `transform` to the expression of the attribute,
|
||||
// recursively traversing and transforming it.
|
||||
func (a *Attribute) RewriteExpr(transform func(hclsyntax.Expression) hclsyntax.Expression) {
|
||||
a.hclAttribute.Expr = RewriteExpr(a.hclAttribute.Expr.(hclsyntax.Expression), transform)
|
||||
if a == nil || a.hclAttribute == nil {
|
||||
return
|
||||
}
|
||||
expr, ok := a.hclAttribute.Expr.(hclsyntax.Expression)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
a.hclAttribute.Expr = RewriteExpr(expr, transform)
|
||||
}
|
||||
|
||||
// nolint: gocyclo
|
||||
|
||||
Reference in New Issue
Block a user