Safeguard
Developer Tools•

How do you stop a tampered gradle-wrapper.jar reaching CI?

The Gradle Wrapper JAR is a binary in your repo that runs on every machine. Validate it in CI and pin the distribution checksum. Here is how, step by step.

Safeguard Security Team
3 min read

Validate gradle-wrapper.jar in CI against Gradle's published checksums, and pin the Gradle distribution with distributionSha256Sum. The wrapper JAR is a checked in binary that executes on developer laptops and build servers, so a pull request that swaps it deserves the same suspicion as any unreviewed executable.

Why the wrapper is an attack surface

Gradle's own documentation states the risk. The Wrapper JAR is a binary file executed on developer computers and build servers. Because it is usually committed to version control, a malicious actor could replace it with a modified one in a pull request that appears to only upgrade the Gradle version.

Code reviewers rarely open a binary diff. That is exactly why automation has to do it.

Step 1: validate the JAR automatically

If you build on GitHub, the Setup Gradle action validates the Wrapper JAR on every build. The documentation says that as of version 4 the validation is built in, with no separate action needed.

On other CI systems, run the manual check described next as a pipeline step.

Step 2: check the checksum yourself

Gradle publishes checksums for all releases except versions 3.3 to 4.0.2, which did not generate reproducible JARs. The documented Linux flow downloads the sha256 file for your Gradle version and runs a check against gradle/wrapper/gradle-wrapper.jar.

cd gradle/wrapper
curl --location --output gradle-wrapper.jar.sha256 \
  https://services.gradle.org/distributions/gradle-9.8.1-wrapper.jar.sha256
echo "  gradle-wrapper.jar" >> gradle-wrapper.jar.sha256
sha256sum --check gradle-wrapper.jar.sha256

Replace the version in the URL with the one your project uses. A result of OK means it matches. Anything else, stop the pipeline.

Step 3: pin the distribution checksum

The wrapper also downloads the Gradle distribution. Gradle lets you verify that download by adding the SHA-256 hash to gradle-wrapper.properties:

distributionSha256Sum=<hash from the published sha256 file>

Gradle fails the build if the checksum does not match the file on the hosting server. One caveat from the documentation: the check only runs if that distribution has not already been downloaded, so it matters most on clean CI agents and fresh clones.

Step 4: make the check a required gate

A check nobody enforces is a suggestion. Make wrapper validation a required status on pull requests that touch the gradle/wrapper directory, and require a code owner review for those paths.

ControlCatchesWhere it runs
Wrapper JAR validationModified wrapper binaryCI, on pull request
distributionSha256SumTampered Gradle downloadEvery fresh build
Code owner on gradle/wrapperUnreviewed wrapper changesReview time

Try it yourself

Click through it at your own pace, or open it full screen. See how a failing check blocks a merge until someone deals with it, which is the behavior you want for a changed wrapper file.

Safeguard policies and gates can block a pull request on dependency findings, and its dependency scanning covers the Gradle and Maven libraries your build resolves. Try a free scan at gold.safeguard.sh/scan.

Quick check

Is the wrapper JAR checked on every build by default?

No. Gradle does not validate it for you unless you add a check, such as the Setup Gradle action on GitHub or a manual checksum step.

Do I need both the JAR check and distributionSha256Sum?

They protect different files. One covers the small bootstrap binary in your repo, the other covers the Gradle distribution it downloads.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.