jenkins-infra / release

Contains every things needed to release jenkins core from the jenkins infra project
MIT License
13 stars 22 forks source link

Verify Artifactory download before publishing #535

Open basil opened 4 months ago

basil commented 4 months ago

While reading this code to review an unrelated PR, I noticed that the package job in the release repository downloads the WAR file produced by the release job in the release repository from Artifactory using the jv tool, which does not appear to do any certificate verification or checksum verification. This means that any problem in the download would not be detected. For example, if the server closes the connection and we get a truncated file, we would likely happily drive on to publish that truncated WAR file. Or if, for some reason, there was a bit flip or filesystem corruption on the downloaded file (a phenomenon that seems unlikely but which I have personally observed with my own two eyes multiple times in my career), we would happily publish the corrupt artifact.

After downloading the WAR file from Artifactory with jv, we should verify it somehow—either by checksum or by verifying the GPG signature.

basil commented 4 months ago

You would hope that

mvn dependency:get -Dartifact=org.jenkins-ci.main:jenkins-war:${JENKINS_VERSION}:war -DremoteRepositories=repo.jenkins-ci.org::default::https://repo.jenkins-ci.org/releases -Dtransitive=false

somehow does checksum validation, but based on https://maven.apache.org/resolver/expected-checksums.html it appears to be implemented only for Sonatype Nexus 2 ETag headers, and I confirmed the ETag returned by Artifactory does not match the expected format.

Artifactory does store checksums, and provides them via its REST API, so one option would be to fetch the SHA1 checksum with the Artifactory REST API and then verify the download with it.

Experimental observation with wget -S https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/2.452/jenkins-war-2.452.war shows that Artifactory seems to send the MD5 checksum in an ETag header, but it's unclear whether that is a stable API that can be relied on or merely a side effect of Artifactory using S3 storage, which defaults to providing an MD5 checksum in an ETag header but may be subject to change in the future.

basil commented 4 months ago

I confirmed that Artifactory provides an accurate SHA256 checksum via curl -s https://repo.jenkins-ci.org/api/storage/releases/org/jenkins-ci/main/jenkins-war/2.452/jenkins-war-2.452.war | jq -r .checksums.sha256 so this seems like the most straightforward option.

basil commented 4 months ago

I seem to have stumbled on an even simpler way to get it from Artifactory: wget https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/2.452/jenkins-war-2.452.war.sha256.