-
Notifications
You must be signed in to change notification settings - Fork 513
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(signature): Checksum signature verification #1670
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Shubham Hibare <shubham@hibare.in>
Signed-off-by: Shubham Hibare <shubham@hibare.in>
@@ -616,7 +679,7 @@ main() ( | |||
install_dir=${install_dir:-./bin} | |||
|
|||
# note: never change the program flags or arguments (this must always be backwards compatible) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: never change the program flags or arguments (this must always be backwards compatible)
A note for reviewers/testers: we need to verify that this would function when installing a previous release. Ideally we'd know the specific release that implemented this and be able to short circuit this and error when validation would silently never occur.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Note: currently unknown options print usage but are ignored, so old releases would download without checking anything. If you want older releases to fail, we'll need to compare the version given here with the first release that supports this as you suggest)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an awesome add! I need to think through and run some testing to ensure installing previous releases is ok https://github.com/anchore/grype/pull/1670/files#r1467020629
Signed-off-by: Shubham Hibare <shubham@hibare.in>
@wagoodman Any update? As you mentioned, definitely need a check to test which version this feature was rolled out and show error when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this work!
return 1 | ||
fi | ||
|
||
checksum_sig_file_path=$(download_github_release_checksums_sig "${download_url}" "${name}" "${version}" "${destination}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a problem per se, but cosign can be passed an url directly, is there any benefit to downloading the cert/signatures?
e.g. this worked (for syft but it's similar)
cosign verify-blob syft_1.4.1_checksums.txt \
--certificate https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_checksums.txt.pem \
--signature https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_checksums.txt.sig \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--certificate-identity 'https://github.com/anchore/syft/.github/workflows/release.yaml@refs/heads/main'
${COSIGN_BINARY} verify-blob "$1" \ | ||
--certificate "$2" \ | ||
--signature "$3" \ | ||
--certificate-identity-regexp "https://github\.com/${OWNER}/${REPO}/\.github/workflows/.+" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably should be more strict than the regex for this, otherwise I assume I could open a PR that adds a new workflow that'll sign something bad™ -- that'll leave traces but it'll still be usable for old releases.
Since the path currently doesn't change, we can just use it as is:
--certificate-identity "https://github.com/${OWNER}/${REPO}/.github/workflows/release.yaml@refs/heads/main"
Ideally the build script should be updated to build releases by tag (refs/tags/v1.2.3) instead of branch, at which point we'll be able to say @refs/tags/$version
checksum_sig_file_path=$(download_github_release_checksums_sig "${download_url}" "${name}" "${version}" "${destination}") | ||
log_info "downloaded checksums signature file: ${checksum_sig_file_path}" | ||
|
||
checksums_cert_file_path=$(download_github_release_checksums_cert "${download_url}" "${name}" "${version}" "${destination}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's more of a cosign question than a question about this script, but if we download the signing certificate what prevents an attacker to provide another checksums file/certificate/signature set?
I'd assume it's the github oidc feature, because the authority cosign has built in wouldn't issue that tokens.actions.githubusercontent.com issuer intermediate certificate to anyone else, and github wouldn't give this certificate identity to another workflow, but given the tool didn't make any network request I don't like the fact that there doesn't seem to be a CRL, so if a bug allows malicious users to abuse the github token they'll be able to provide their own set of files? Meaning I'd be much more comfortable pinning a fingerprint we could just update if it leaks...
But now I'm looking it looks like each release generates a different certificate every time, so that wouldn't work. I guess I'll have to learn to trust these tools...
@@ -616,7 +679,7 @@ main() ( | |||
install_dir=${install_dir:-./bin} | |||
|
|||
# note: never change the program flags or arguments (this must always be backwards compatible) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Note: currently unknown options print usage but are ignored, so old releases would download without checking anything. If you want older releases to fail, we'll need to compare the version given here with the first release that supports this as you suggest)
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin -v | ||
``` | ||
> ![NOTE] | ||
> This requires `cosign` to be installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to link to https://github.com/sigstore/cosign as many distros don't have a package for it (yet?)
Addresses issue #1627
This PR adds checksum.txt file signature verification before downloading and installing actual binary. This is an optional opt-in feature using command line flag
-v
to installation script.Signature verification process depends on 3rd party cosign binary. If the binary is not found, the user is prompted to install the binary. Cosign binary installation is not part of this script.
The overall process with signature verification looks like this:
-v
command line flag to installation script.Successful signature verification:
Signature verification failure:
Cosign binary not found: