grype icon indicating copy to clipboard operation
grype copied to clipboard

Share which file is vulnerable when reporting an intra-file vulnerability in the default table output

Open luhring opened this issue 1 year ago • 2 comments

What would you like to be added:

In the default output format, for image scans (or really, any scan of a target that contains multiple files), when reporting a vulnerability for a dependency inside a file (e.g. a module compiled into a Go binary), show which file has the vulnerability.

Why is this needed:

Without this feature, the output row for these kinds of vulnerabilities is not very helpful.

If I'm trying to ensure my image has as few vulnerabilities as possible, and I'm using Grype to help me, I want to get to the point where I can do something about every given vulnerability as quickly as possible. Any factor that gets in my way of doing this is noticeable friction added to my process of getting the job done.

For a distro package, (e.g. apk type), remediation is obvious. From anywhere in the image (or Dockerfile, etc.) I can run apk add -u pkgName and I'm done.

But for cases like Go binaries, JARs, etc. — there is a missing layer of hierarchy in Grype's table output. I see the vulnerable package, and I know what image I scanned, but I'm missing a crucial piece of information: the file itself. So I need to re-run the scan with a more helpful output.

Here's an example:

$ grype -q quay.io/cilium/hubble-ui-backend:v0.10.0
NAME                      INSTALLED                           FIXED-IN                           TYPE       VULNERABILITY        SEVERITY
github.com/cilium/cilium  v1.12.4                                                                go-module  CVE-2023-27593       Medium
github.com/cilium/cilium  v1.12.4                                                                go-module  CVE-2023-27594       High
github.com/cilium/cilium  v1.12.4                             1.12.8                             go-module  GHSA-4hc4-pgfx-3mrx  Medium
github.com/cilium/cilium  v1.12.4                             1.12.8                             go-module  GHSA-8fg8-jh2h-f2hc  Medium
golang.org/x/net          v0.4.0                              0.7.0                              go-module  GHSA-vvpx-j8f3-3w6h  High
golang.org/x/sys          v0.0.0-20210902050250-f475640dd07b  0.0.0-20220412211240-33da011f77ad  go-module  GHSA-p782-xgp4-8hr8  Medium

Which Go binary (or binaries, plural?) has the vulnerability? I have no idea. In the very best case, the image only has a single Go binary, and I have this knowledge in advance. But in all other cases, this Grype scan brought me no closer to a solution for those vulnerabilities.

Additional context:

The "default" piece of this ask might be more important than one would think. In practice, for better or for worse, I've seen lots of people sharing screenshots (or console copy/paste like the above example) of the table view. Of course, in some cases, folks are persisting a more machine-readable format, like the native JSON output or SARIF. But still, lots of times this isn't the case. And it would be great for folks on the receiving end of these snippets to more readily understand what Grype found.

cc: @kzantow

luhring avatar Mar 28 '23 00:03 luhring

DEVELOPER NOTES: After some internal discussion with the team, we think implementing this feature would be good but an implementation should consider a few things:

  • we do not want the location to be output by default in the table view, as locations can be (and often are!) very long, this would make the table unwieldy, which is contradictory to the purpose of the table: having a simple summary view. however, we could make the columns that get displayed configurable (e.g. columns=name,vulnerability,location) but since table is a format type, a flag like --table-columns is mutually exclusive to the other output formats and we'd like to avoid this, instead favoring just structured configuration (like env var GRYPE_FORMAT_TABLE_COLUMNS=... or analogous YAML)
  • syft format configuration is done using a pattern consistent throughout the application in a number of ways: get a list of preconfigured format providers to pick from rather than configuration resulting in a single formatter object. we should probably use this feature to rework the grype presenters to be configured and used similar to the syft formats in this regard.
  • we probably want to continue to output 1-line-per-result. some possibilities for solving the "very wide table" problem could involve putting locations on a second line or similar, but this would break any tools using the table output as a simple way to get a list of CVEs using something like cut
  • as noted in the PR #1275, it also could be nice to have a configuration for omitting certain types from the location by default, such as rpm or dpkg packages, which tend to reference the same file(s) and provide limited value

kzantow avatar Mar 11 '24 19:03 kzantow

One note I'll add is that I actually think Trivy has solved this problem really elegantly in their table output.

They don't cram all vuln matches of all kinds into a single table, they create "context-relevant" tables for distro packages and individual files.

Here's a simple example:

image

In this case, they found vulnerabilities in just one file. Instead of putting that file path (which to your point, could have been very long) inside a column somewhere, they factor it out and give the path its own table.

This is hugely beneficial to someone trying to use the tool to get real remediation work done.

For the example above, Grype just shows github.com/docker/docker. And the image could have had hundreds of binary paths to look in. Asking users to "use the JSON output" would solve their problem, but at an enormous cost of verbosity. Taking an approach like Trivy's would make the table more valuable without incurring much cost.

Food for thought!

luhring avatar Apr 01 '24 13:04 luhring