Repository navigation
ci: run trivy on last release binary - #275
Conversation
| id: release | ||
| run: | | ||
| url=$(gh release view --json assets --jq \ | ||
| '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \ |
There was a problem hiding this comment.
Should this run on a matrix? I.e. to catch architecture-specific vulnerabilities
There was a problem hiding this comment.
I think we should, tbh if it is easier we can download all the files, extract them and look for binaries.
There was a problem hiding this comment.
Would gh release download work as well? From documentation it says it downloads the latest release and it is simpler.
There was a problem hiding this comment.
Should this run on a matrix? I.e. to catch architecture-specific vulnerabilities
In Go, dependencies in go.mod are not architecture-dependent. Vulnerabilities are not architecture-dependent either, so AFAIK when vulnerabilities are found, they are associated to a specific version (or a range) of a libraries, but not to a specific architecture. I agree that in reality, a vulnerability could only affect an arch-specific path, but this vulnerability will be associated to the library anyway. In go files, specific directive could be used to tune the imports based on the target arch, but these dependencies must be listed anyway in go.mod. So that could lead to false positives but not false negatives.
Given that, the architecture we select to scan is actually irrelevant. Do you agree?
I picked amd64 because this is the most common and the one we are most likely to keep building over time.
There was a problem hiding this comment.
I agree that in reality, a vulnerability could only affect an arch-specific path, but this vulnerability will be associated to the library anyway.
If this is true then we can only test amd64. I am not saying it is not, but if we were to use govulncheck or similar, then the scanners not only look at go.mod but instead they look at the actual call graph in which case architecture IS relevant, right?
IMHO either we add a comment saying why we are only testing amd64 or we test all architectures even if it is redundant for now. We may add more scanners in the future and I am almost certain we will forget to expand the list of architectures now that the assumption no longer holds. In this case, evident > clever IMO.
There was a problem hiding this comment.
If this is true then we can only test amd64. I am not saying it is not, but if we were to use govulncheck or similar, then the scanners not only look at go.mod but instead they look at the actual call graph in which case architecture IS relevant, right?
I see your point. I agree that if we were to replace trivy with govulncheck, then the more precise analysis of govulncheck on a single arch could exclude false positives for this arch that are true positives for another arch.
I am adding the matrix. See cfd7a2a
letFunny
left a comment
There was a problem hiding this comment.
Thanks for looking more into this Paul, great diligence! Just a couple of comments.
| id: release | ||
| run: | | ||
| url=$(gh release view --json assets --jq \ | ||
| '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \ |
There was a problem hiding this comment.
I think we should, tbh if it is easier we can download all the files, extract them and look for binaries.
| uses: aquasecurity/trivy-action@master | ||
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 | ||
| with: | ||
| scan-type: 'fs' |
There was a problem hiding this comment.
Are we not going to do the 'fs' check then? If we could have it "for free" it would be even better as it would cause problems in the go.mod itself. Let's say that go.mod says go 1.23 is used but our CI uses go.24 to build the binary. Then the binary might not have vulnerabilities but users building the binary themselves might not be safe. In this case I think we should probably bump the minimal go version in go.mod as well even if it is more troublesome for us.
There was a problem hiding this comment.
If our go.mod says Go 1.23, it only means our code needs at least this version to work properly. This is not a promise on the level of security, but a minimum functional requirement. In an ideal world (and forgetting about new language features) I suppose we would like this value to be as low as possible so the project could be built with a wide variety of go versions.
I don't think we can do any promise on binaries we do not distribute ourselves, nor should we try to.
Also, as explained in the PR description, in fs mode trivy is not looking at the go ... directive given in go.mod because it does not say what version of Go will actually be used. So in the case of a Go project, the fs mode executed on the code could only find less vulnerabilities than the rootfs mode on the binary, because the rootfs mode will identify the Go version used.
There was a problem hiding this comment.
I don't think we can do any promise on binaries we do not distribute ourselves, nor should we try to.
Depends on how you look at it, but yes I get your point. If the minimal version is for the package to build then the expectation is as you say, if as a user I expect the package to build without known vulnerabilities then the minimum version should reflect that.
in fs mode trivy is not looking at the go ... directive given in go.mod
I didn't know this, I was under the impression trivy look at the minimum version and used that. Then it is okay if we don't keep it. Thanks for the context!
There was a problem hiding this comment.
I am sticking to https://go.dev/ref/mod#go-mod-file-go for the meaning of the go directive. If we were to do what you suggest, the toolchain directive might be a better fit, but it still feels like a stretch.
| id: release | ||
| run: | | ||
| url=$(gh release view --json assets --jq \ | ||
| '.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \ |
There was a problem hiding this comment.
Would gh release download work as well? From documentation it says it downloads the latest release and it is simpler.
letFunny
left a comment
There was a problem hiding this comment.
Looks good to me, thank you for working on this
niemeyer
left a comment
There was a problem hiding this comment.
Looks okay, but I'm trusting you both on this one as there are multiple action imports here. No relevant secrets being offers, so hopefully okay anyway. It is slightly ironic, considering the "security" name, though. Maybe "scanning" is a better term here.
Trivy was previously executed on the main branch, so the report was not
reflecting the level of vulnerability in the binary actually distributed to
users. Moreover,
fstype scan only uses the go version fromgo.modas ahint and so cannot conclude on the stdb lib actually used to build the binary.
As a consequence, the report produced was imprecise and incomplete.
This PR does two main changes:
rootfstype scan on the binary, ensuring the the std lib includedis analysed.
Actions are also pinned to protect against supply chain attacks on them.
Note: I manually tested both type of trivy scan on the binary and confirmed
only the
rootfsone identifies the vulnerabilities in the std lib.