Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(vuln): add --pkg-relationships #7237

Merged
merged 12 commits into from
Jul 29, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ trivy filesystem [flags] PATH
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/references/configuration/cli/trivy_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ trivy image [flags] IMAGE_NAME
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--platform string set platform in the form os/arch if image is multi-platform capable
--podman-host string unix podman socket path to use for podman scanning
--redis-ca string redis ca file location, if using redis as cache backend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ trivy kubernetes [flags] [CONTEXT]
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--qps float specify the maximum QPS to the master from this client (default 5)
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/references/configuration/cli/trivy_rootfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ trivy rootfs [flags] ROOTDIR
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/references/configuration/cli/trivy_sbom.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ trivy sbom [flags] SBOM_PATH
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/references/configuration/cli/trivy_vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ trivy vm [flags] VM_IMAGE
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--pkg-types strings comma-separated list of package types (os,library) (default [os,library])
--pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Expand Down
39 changes: 38 additions & 1 deletion docs/docs/scanner/vulnerability.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ Currently, specifying a username and password is not supported.
This section describes vulnerability-specific configuration.
Other common options are documented [here](../configuration/index.md).

### Enabling a subset of package types
### Enabling a Subset of Package Types

It's possible to only enable certain package types if you prefer.
You can do so by passing the `--pkg-types` option.
This flag takes a comma-separated list of package types.
Expand Down Expand Up @@ -268,6 +269,42 @@ Total: 7 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 3, CRITICAL: 2)

</details>

!!! info
This flag filters the packages themselves, so it also affects the `--list-all-pkgs` option and SBOM generation.

### Filtering by Package Relationships


Trivy supports filtering vulnerabilities based on the relationship of packages within a project.
This is achieved through the `--pkg-relationships` flag.
This feature allows you to focus on vulnerabilities in specific types of dependencies, such as only those in direct dependencies.

In Trivy, there are four types of package relationships:

1. `root`: The root package being scanned
2. `direct`: Direct dependencies of the root package
3. `indirect`: Transitive dependencies
4. `unknown`: Packages whose relationship cannot be determined

The available relationships may vary depending on the ecosystem.
To see which relationships are supported for a particular project, you can use the JSON output format and check the `Relationship` field:

```
$ trivy repo -f json --list-all-pkgs /path/to/project
```

To scan only the root package and its direct dependencies, you can use the flag as follows:

```
$ trivy repo --pkg-relationships root,direct /path/to/project
```

By default, all relationships are included in the scan.

!!! info
This flag filters the packages themselves, so it also affects the `--list-all-pkgs` option and SBOM generation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add warning that this flag can't be used with --dependency-tree, --vex or --format spdx|spdx-json|cyclonedx|github.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted the warning in aaea1ea as it now returns an error. Do you want to document it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it won't be superfluous

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done
f0e1104



[^1]: https://github.com/GoogleContainerTools/distroless

[nvd-CVE-2023-0464]: https://nvd.nist.gov/vuln/detail/CVE-2023-0464
Expand Down
37 changes: 20 additions & 17 deletions pkg/commands/app.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that users will want to use new flag in convert mode.
e.g. scan image once, but show 2 tables - with direct and indirect dependencies.

But for this change we need to change location of new logic.
So I suggest waiting for user requests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I was also thinking about it. --include-dev-deps and --pkg-types cannot be used in convert now. Detecting vulnerabilities is not expensive. We might want to move it in the filtering process.

Copy link
Contributor

@DmitriyLewen DmitriyLewen Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--include-dev-deps and --pkg-types cannot be used in convert now.

Users can't use --pkg-types (--vuln-type) in v0.53.0 (or earlier) in convert mode:

➜ trivy -d convert --vuln-type os
...
2024-07-29T11:42:11+06:00	FATAL	Fatal error	unknown flag: --vuln-type

But I haven't seen any requests to add this flag for convert mode.

We might want to wait for user feedback on --pkg-relationships.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,6 @@ func NewRootCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
}

func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
scanFlagGroup := flag.NewScanFlagGroup()
scanFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'

reportFlagGroup := flag.NewReportFlagGroup()
report := flag.ReportFormatFlag.Clone()
report.Default = "summary" // override the default value as the summary is preferred for the compliance report
Expand All @@ -256,27 +253,28 @@ func NewImageCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
compliance.Values = []string{types.ComplianceDockerCIS160}
reportFlagGroup.Compliance = compliance // override usage as the accepted values differ for each subcommand.

misconfFlagGroup := flag.NewMisconfFlagGroup()
misconfFlagGroup.CloudformationParamVars = nil // disable '--cf-params'
misconfFlagGroup.TerraformTFVars = nil // disable '--tf-vars'

imageFlags := &flag.Flags{
GlobalFlagGroup: globalFlags,
CacheFlagGroup: flag.NewCacheFlagGroup(),
DBFlagGroup: flag.NewDBFlagGroup(),
ImageFlagGroup: flag.NewImageFlagGroup(), // container image specific
LicenseFlagGroup: flag.NewLicenseFlagGroup(),
MisconfFlagGroup: misconfFlagGroup,
MisconfFlagGroup: flag.NewMisconfFlagGroup(),
ModuleFlagGroup: flag.NewModuleFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
RegistryFlagGroup: flag.NewRegistryFlagGroup(),
RegoFlagGroup: flag.NewRegoFlagGroup(),
ReportFlagGroup: reportFlagGroup,
ScanFlagGroup: scanFlagGroup,
ScanFlagGroup: flag.NewScanFlagGroup(),
SecretFlagGroup: flag.NewSecretFlagGroup(),
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
}

imageFlags.PackageFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
imageFlags.MisconfFlagGroup.CloudformationParamVars = nil // disable '--cf-params'
imageFlags.MisconfFlagGroup.TerraformTFVars = nil // disable '--tf-vars'

cmd := &cobra.Command{
Use: "image [flags] IMAGE_NAME",
Aliases: []string{"i"},
Expand Down Expand Up @@ -342,6 +340,7 @@ func NewFilesystemCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
LicenseFlagGroup: flag.NewLicenseFlagGroup(),
MisconfFlagGroup: flag.NewMisconfFlagGroup(),
ModuleFlagGroup: flag.NewModuleFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
RegistryFlagGroup: flag.NewRegistryFlagGroup(),
RegoFlagGroup: flag.NewRegoFlagGroup(),
Expand Down Expand Up @@ -400,6 +399,7 @@ func NewRootfsCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
LicenseFlagGroup: flag.NewLicenseFlagGroup(),
MisconfFlagGroup: flag.NewMisconfFlagGroup(),
ModuleFlagGroup: flag.NewModuleFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
RegistryFlagGroup: flag.NewRegistryFlagGroup(),
RegoFlagGroup: flag.NewRegoFlagGroup(),
Expand All @@ -411,7 +411,7 @@ func NewRootfsCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
rootfsFlags.ReportFlagGroup.ReportFormat = nil // TODO: support --report summary
rootfsFlags.ReportFlagGroup.Compliance = nil // disable '--compliance'
rootfsFlags.ReportFlagGroup.ReportFormat = nil // disable '--report'
rootfsFlags.ScanFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
rootfsFlags.PackageFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
rootfsFlags.CacheFlagGroup.CacheBackend.Default = string(cache.TypeMemory) // Use memory cache by default

cmd := &cobra.Command{
Expand Down Expand Up @@ -460,6 +460,7 @@ func NewRepositoryCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
LicenseFlagGroup: flag.NewLicenseFlagGroup(),
MisconfFlagGroup: flag.NewMisconfFlagGroup(),
ModuleFlagGroup: flag.NewModuleFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RegistryFlagGroup: flag.NewRegistryFlagGroup(),
RegoFlagGroup: flag.NewRegoFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
Expand Down Expand Up @@ -516,7 +517,6 @@ func NewConvertCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
ScanFlagGroup: &flag.ScanFlagGroup{},
ReportFlagGroup: flag.NewReportFlagGroup(),
}
convertFlags.ReportFlagGroup.PkgTypes = nil // disable '--pkg-types'

cmd := &cobra.Command{
Use: "convert [flags] RESULT_JSON",
Expand Down Expand Up @@ -685,7 +685,6 @@ func NewConfigCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
configFlags.ReportFlagGroup.ListAllPkgs = nil // disable '--list-all-pkgs'
configFlags.ReportFlagGroup.ExitOnEOL = nil // disable '--exit-on-eol'
configFlags.ReportFlagGroup.ShowSuppressed = nil // disable '--show-suppressed'
configFlags.ReportFlagGroup.PkgTypes = nil // disable '--pkg-types'
configFlags.ReportFlagGroup.ReportFormat.Usage = "specify a compliance report format for the output" // @TODO: support --report summary for non compliance reports
configFlags.CacheFlagGroup.CacheBackend.Default = string(cache.TypeMemory)

Expand Down Expand Up @@ -960,7 +959,6 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
})
scanners.Default = scanners.Values
scanFlags.Scanners = scanners
scanFlags.IncludeDevDeps = nil // disable '--include-dev-deps'

// required only SourceFlag
imageFlags := &flag.ImageFlagGroup{ImageSources: flag.SourceFlag.Clone()}
Expand Down Expand Up @@ -997,13 +995,16 @@ func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
ImageFlagGroup: imageFlags,
K8sFlagGroup: flag.NewK8sFlagGroup(), // kubernetes-specific flags
MisconfFlagGroup: misconfFlagGroup,
PackageFlagGroup: flag.NewPackageFlagGroup(),
RegoFlagGroup: flag.NewRegoFlagGroup(),
ReportFlagGroup: reportFlagGroup,
ScanFlagGroup: scanFlags,
SecretFlagGroup: flag.NewSecretFlagGroup(),
RegistryFlagGroup: flag.NewRegistryFlagGroup(),
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
}
k8sFlags.PackageFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'

cmd := &cobra.Command{
Use: "kubernetes [flags] [CONTEXT]",
Aliases: []string{"k8s"},
Expand Down Expand Up @@ -1055,6 +1056,7 @@ func NewVMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
DBFlagGroup: flag.NewDBFlagGroup(),
MisconfFlagGroup: flag.NewMisconfFlagGroup(),
ModuleFlagGroup: flag.NewModuleFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
ReportFlagGroup: flag.NewReportFlagGroup(),
ScanFlagGroup: flag.NewScanFlagGroup(),
Expand All @@ -1069,7 +1071,7 @@ func NewVMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
},
}
vmFlags.ReportFlagGroup.ReportFormat = nil // disable '--report'
vmFlags.ScanFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
vmFlags.PackageFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
vmFlags.MisconfFlagGroup.CloudformationParamVars = nil // disable '--cf-params'
vmFlags.MisconfFlagGroup.TerraformTFVars = nil // disable '--tf-vars'

Expand Down Expand Up @@ -1128,9 +1130,8 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
types.VulnerabilityScanner,
})
scanFlagGroup := flag.NewScanFlagGroup()
scanFlagGroup.Scanners = scanners // allow only 'vuln' and 'license' options for '--scanners'
scanFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'
scanFlagGroup.Parallel = nil // disable '--parallel'
scanFlagGroup.Scanners = scanners // allow only 'vuln' and 'license' options for '--scanners'
scanFlagGroup.Parallel = nil // disable '--parallel'

licenseFlagGroup := flag.NewLicenseFlagGroup()
// License full-scan and confidence-level are for file content only
Expand All @@ -1141,6 +1142,7 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
GlobalFlagGroup: globalFlags,
CacheFlagGroup: flag.NewCacheFlagGroup(),
DBFlagGroup: flag.NewDBFlagGroup(),
PackageFlagGroup: flag.NewPackageFlagGroup(),
RemoteFlagGroup: flag.NewClientFlags(), // for client/server mode
ReportFlagGroup: reportFlagGroup,
ScanFlagGroup: scanFlagGroup,
Expand All @@ -1150,6 +1152,7 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
}

sbomFlags.CacheFlagGroup.CacheBackend.Default = string(cache.TypeMemory) // Use memory cache by default
sbomFlags.PackageFlagGroup.IncludeDevDeps = nil // disable '--include-dev-deps'

cmd := &cobra.Command{
Use: "sbom [flags] SBOM_PATH",
Expand Down
Loading