mirror of
				https://hub.gitmirror.com/https://github.com/gradle/actions.git
				synced 2025-11-04 03:50:02 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			132 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Gradle Wrapper Validation Action
 | 
						||
 | 
						||
This action validates the checksums of _all_ [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html) JAR files present in the repository and fails if any unknown Gradle Wrapper JAR files are found.
 | 
						||
 | 
						||
The action should be run in the root of the repository, as it will recursively search for any files named `gradle-wrapper.jar`.
 | 
						||
 | 
						||
> [!NOTE]
 | 
						||
> Starting with v4 the `setup-gradle` action will automatically [perform wrapper validation](../docs/setup-gradle.md#gradle-wrapper-validation)
 | 
						||
> on each execution.
 | 
						||
> 
 | 
						||
> If you are using `setup-gradle` in your workflows, it is unlikely that you will need to use the `wrapper-validation` action.
 | 
						||
 | 
						||
## The Gradle Wrapper Problem in Open Source
 | 
						||
 | 
						||
The `gradle-wrapper.jar` is a binary blob of executable code that is checked into nearly
 | 
						||
[2.8 Million GitHub Repositories](https://github.com/search?l=&q=filename%3Agradle-wrapper.jar&type=Code).
 | 
						||
 | 
						||
Searching across GitHub you can find many pull requests (PRs) with helpful titles like 'Update to Gradle xxx'.
 | 
						||
Many of these PRs are contributed by individuals outside of the organization maintaining the project.
 | 
						||
 | 
						||
Many maintainers are incredibly grateful for these kinds of contributions as it takes an item off of their backlog.
 | 
						||
We assume that most maintainers do not consider the security implications of accepting the Gradle Wrapper binary from external contributors.
 | 
						||
There is a certain amount of blind trust open source maintainers have.
 | 
						||
Further compounding the issue is that maintainers are most often greeted in these PRs with a diff to the `gradle-wrapper.jar` that looks like this.
 | 
						||
 | 
						||

 | 
						||
 | 
						||
A fairly simple social engineering supply chain attack against open source would be contribute a helpful “Updated to Gradle xxx” PR that contains malicious code hidden inside this binary JAR.
 | 
						||
A malicious `gradle-wrapper.jar` could execute, download, or install arbitrary code while otherwise behaving like a completely normal `gradle-wrapper.jar`.
 | 
						||
 | 
						||
## Solution
 | 
						||
 | 
						||
We have created a simple GitHub Action that can be applied to any GitHub repository.
 | 
						||
This GitHub Action will do one simple task:
 | 
						||
verify that any and all `gradle-wrapper.jar` files in the repository match the SHA-256 checksums of any of our official releases.
 | 
						||
 | 
						||
If any are found that do not match the SHA-256 checksums of our official releases, the action will fail.
 | 
						||
 | 
						||
Additionally, the action will find and SHA-256 hash all
 | 
						||
[homoglyph](https://en.wikipedia.org/wiki/Homoglyph)
 | 
						||
variants of files named `gradle-wrapper.jar`,
 | 
						||
for example a file named `gradlе-wrapper.jar` (which uses a Cyrillic `е` instead of `e`).
 | 
						||
The goal is to prevent homoglyph attacks which may be very difficult to spot in a GitHub diff.
 | 
						||
We created an example [Homoglyph attack PR here](https://github.com/JLLeitschuh/playframework/pull/1/files).
 | 
						||
 | 
						||
## Usage
 | 
						||
 | 
						||
### Add to an existing Workflow
 | 
						||
 | 
						||
Simply add this action to your workflow **after** having checked out your source tree and **before** running any Gradle build:
 | 
						||
 | 
						||
```yaml
 | 
						||
uses: gradle/actions/wrapper-validation@v5
 | 
						||
```
 | 
						||
 | 
						||
This action step should precede any step using `gradle/gradle-build-action` or `gradle/actions/setup-gradle`.
 | 
						||
 | 
						||
### Add a new dedicated Workflow
 | 
						||
 | 
						||
Here's a sample complete workflow you can add to your repositories:
 | 
						||
 | 
						||
**`.github/workflows/gradle-wrapper-validation.yml`**
 | 
						||
```yaml
 | 
						||
name: "Validate Gradle Wrapper"
 | 
						||
 | 
						||
on:
 | 
						||
  push:
 | 
						||
  pull_request:
 | 
						||
 | 
						||
jobs:
 | 
						||
  validation:
 | 
						||
    name: "Validation"
 | 
						||
    runs-on: ubuntu-latest
 | 
						||
    steps:
 | 
						||
      - uses: actions/checkout@v4
 | 
						||
      - uses: gradle/actions/wrapper-validation@v5
 | 
						||
```
 | 
						||
 | 
						||
## Contributing to an external GitHub Repository
 | 
						||
 | 
						||
Since [GitHub Actions](https://github.com/features/actions)
 | 
						||
are completely free for open source projects and are automatically enabled on almost all projects,
 | 
						||
adding this check to a project's build is as simple as contributing a PR.
 | 
						||
Enabling the check requires no overhead on behalf of the project maintainer beyond merging the action.
 | 
						||
 | 
						||
You can add this action to your favorite Gradle based project without checking out their source locally via the
 | 
						||
GitHub Web UI thanks to the 'Create new file' button.
 | 
						||
 | 
						||

 | 
						||
 | 
						||
Simply add a new file named `.github/workflows/gradle-wrapper-validation.yml` with the contents mentioned above.
 | 
						||
 | 
						||
We recommend the message commit contents of:
 | 
						||
 - Title: `Official Gradle Wrapper Validation Action`
 | 
						||
 - Body (at minimum): `See: https://github.com/gradle/actions/wrapper-validation`
 | 
						||
 | 
						||
From there, you can easily follow the rest of the prompts to create a Pull Request against the project.
 | 
						||
 | 
						||
## Validation Failures
 | 
						||
 | 
						||
A wrapper jar can fail validation for a few reasons:
 | 
						||
1. The wrapper is from a snapshot build of Gradle (nightly or release nightly) and you have not set `allow-snapshots`
 | 
						||
   or `allow-snapshot-wrappers` to `true`.
 | 
						||
2. The wrapper jar is from a version of Gradle with an unverifiable wrapper jar (see below).
 | 
						||
3. The wrapper jar is saved in Git LFS, and has not been correctly restored on checkout (see below).
 | 
						||
4. The wrapper jar was not published by Gradle, and could be compromised.
 | 
						||
 | 
						||
If this GitHub action fails because a `gradle-wrapper.jar` was not published by Gradle,
 | 
						||
we highly recommend that you reach out to us at [security@gradle.com](mailto:security@gradle.com).
 | 
						||
 | 
						||
#### Unverifiable Wrapper Jars
 | 
						||
Wrapper Jars generated by Gradle versions `3.3` to `4.0` are not verifiable because those files were dynamically generated by Gradle in a non-reproducible way. It's not possible to verify the `gradle-wrapper.jar` for those versions are legitimate using a hash comparison. If you have a validation failure, you should try to determine if the `gradle-wrapper.jar` was generated by one of these versions before running the build.
 | 
						||
 | 
						||
- If the Gradle version in `gradle-wrapper.properties` is outside of this range, you can regenerate the `gradle-wrapper.jar` by running `./gradlew wrapper`. This will generate a new, verifiable wrapper jar.
 | 
						||
- If you need to run your build with a version of Gradle between 3.3 and 4.0, you can use a newer version of Gradle to generate the `gradle-wrapper.jar`.
 | 
						||
 | 
						||
#### Wrapper Jar stored with Git LFS
 | 
						||
If your repository is configured to store Wrapper Jars in Git Large File Storage (LFS), then you must include the configuration to correctly
 | 
						||
restore these Jars on checkout. Without this, only a pointer to the Wrapper Jar is restored, and the checksum verification will fail.
 | 
						||
 | 
						||
```
 | 
						||
    steps:
 | 
						||
      - uses: actions/checkout@v4
 | 
						||
        with:
 | 
						||
          lfs: true  # gradle-wrapper.jar verification will fail without this
 | 
						||
```
 | 
						||
 | 
						||
## Resources
 | 
						||
 | 
						||
To learn more about verifying the Gradle Wrapper JAR locally, see our
 | 
						||
[guide on the topic](https://docs.gradle.org/current/userguide/gradle_wrapper.html#wrapper_checksum_verification).
 |