Closed oguzkocer closed 2 years ago
I didn't know were to find such a tampered gradle-wrapper.jar that doesn't match the official sha256. Let me know if you know how to test that. 🙏
@ParaskP7 I'm guessing you can use any random .jar
(or actually, probably any random file even) and rename it gradle-wrapper.jar
, to get a file with that name but invalid checksum? e.g. echo "Fake Corrupted Wrapper" >gradle-wrapper.jar
@ParaskP7 I'm guessing you can use any random .jar (or actually, probably any random file even) and rename it gradle-wrapper.jar, to get a file with that name but invalid checksum? e.g. echo "Fake Corrupted Wrapper" >gradle-wrapper.jar
Thanks @AliSoftware for the tip, but I actually tried that and what I got was that it didn't even go through the validate_checksum
function, it just got straight to No gradle-wrapper.jar files found.
, any ideas what am I missing here, I am sure it is something basic, as I said, I am not a scripting except... 😅 😝 😑
Thank you both for the PR review! 🙇
@ParaskP7 Here is how to generate the Failed to validate '$wrapper_file'
error:
P.S: It looks like I forgot to cd into the test-gradle-wrapper
folder after creating it, but I didn't have anything else related to this test in temp
folder, so it shouldn't matter.
Note that you can no longer call this script directly because of the hash_file
change. However, you can do it if you add the bin
folder from this repository to your path. It looks something like this in fish
shell:
$ fish_add_path ~/Developer/Projects/bash-cache-buildkite-plugin/bin/
$ ~/Developer/Projects/bash-cache-buildkite-plugin/bin/validate_gradle_wrapper
👋 @oguzkocer @AliSoftware !
Thank you so much for the above, but actually, and shame on me (😊), as I was using the previously downloaded homoglyph gradle-wrapper.jar
name by copy-pasting it to this tampered gradle-wrapper.jar
of mine, this was what made it to not work on my side... What a noob right! 😅
I copy-pasted the gradle-wrapper.jar
from WPAndroid's such JAR file and onto this tampered gradle-wrapper.jar
of mine and test it again, everything worked as expected. After waiting a bit (as expected), I am indeed getting the Failed to validate './gradle-wrapper.jar'
failure.
Again, apologies for the false alarm, and now, I'll go hide in the dark and cry... 😊 🙏 😭
@ParaskP7 No worries at all. Thanks again for reviewing and testing the PR! 🙇♂️
This PR adds
bin/validate_gradle_wrapper
helper script which we can use to validate the Gradle Wrapper in our projects using Buildkite.During the implementation of this script, I've consulted with the official Gradle Wrapper Documentation as well as the official Gradle Wrapper Validation Github Action. Here is a summary of what the script does:
gradle-wrapper.jar
. If no such file is found, it'll fail with the following error:No gradle-wrapper.jar files found.
This is because if we don't have any Gradle Wrapper files in the project, we shouldn't be calling this script. If we do and it still fails, it's possibly due to Homoglyph attack. (more on that below)gradle-wrapper.jar
file, the script will download the json fromhttps://services.gradle.org/versions/all
and make a list of urls of all the knownsha256
hashes using thewrapperChecksumUrl
property.sha256
values are not directly listed in thejson
file, but instead have to be downloaded from a url, we have to check each url until we find a match. We can possibly avoid this by using the Gradle wrapper version information, but that adds extra complexity and it's more error prone, so in my opinion, checking each known value is better. The good news is, since we use relatively latest Gradle versions in each project, we only end up checking a few versions.gradle-wrapper.jar
file, we'll log that information as such:'./gradle/wrapper/gradle-wrapper.jar' is validated with sha256 checksum from 'https://services.gradle.org/distributions/gradle-7.4.2-wrapper.jar.sha256'
. This information allows us to always come back to a build and check how it was validated.gradle-wrapper.jar
file, which in most cases will only be one, and if each of them is validated, the script will return success return code. If any of the files fail to validate, it'll exit with an error as such:Failed to validate './gradle/wrapper/gradle-wrapper.jar'
.Combining with Official Github Action
We initially wanted to use the Official Github Action, but it becomes a bit messy to use that as a prerequisite for our Buildkite actions. So, @jkmassel and I had a discussion about using our own script as a prerequisite, but also adding the Github Action as an extra piece of security. That means, if there is a validation error that our script misses, we'll at least know about it and address the issue in our script. This makes our script more future-proof and gives extra coverage for Homoglyph attacks.
Homoglyph Attacks
The main difference with this script and the official Github Action is that, this script doesn't cover all cases of Homoglyph attacks. The official Github Action will unhomoglyph each file and then if a file's name corresponds to
gradle-wrapper.jar
, it'll validate it.On the contrary, since this script only looks for
gradle-wrapper.jar
file, if the file is a homoglyphed version, it'll not find it. That means - in most cases, it'll exit with a failure because it didn't find anygradle-wrapper.jar
files. However, there is still a case this script doesn't cover and that is, if the project contains both a validgradle-wrapper.jar
file as well as a homoglyphed one, it'll return a false positive validation.I looked into adding the same Homoglyph file name validation to the bash script, but I think it's a bit tricky and messy to do it in bash. I also thought that
gradle-wrapper.jar
file is probably not the only file that can be used to attack. So, in my opinion, if this is something we are worried about, we should add a more generic check to our repositories where we block any Homoglyphed file names using a list of names we keep in a central location. If we go down that route, we can use the unhomoglyph library to avoid another re-write of something that already exists.Specifically for Gradle Wrapper validation; since we are also adding the Github Action, I don't think we should worry about it. We are already handling the Gradle upgrades ourselves. Once we start using this script as well as the Github Action, I think we will have more than enough coverage.
To Test
gradle-wrapper.jar
file within it.gradle-wrapper.jar
file from this PR, put it in a temporary directory and run this script which should fail withNo gradle-wrapper.jar files found.
.