mirror of
https://github.com/gradle/wrapper-validation-action
synced 2024-11-23 17:22:01 +00:00
Merge pull request #6 from JLLeitschuh/feat/JLL/homoglyph_detector
Add a homoglyph detector for gradle-wrapper.jar files
This commit is contained in:
commit
ffa49e0d93
11 changed files with 79 additions and 13 deletions
|
@ -34,6 +34,12 @@ verify that any and all `gradle-wrapper.jar` files in the repository match the S
|
|||
|
||||
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.
|
||||
|
||||
## Usage
|
||||
|
||||
Simply add this action to your workflow **after** having checked out your source tree and **before** running any Gradle build:
|
||||
|
|
0
__tests__/data/invalid/gradlе-wrapper.jar
Normal file
0
__tests__/data/invalid/gradlе-wrapper.jar
Normal file
|
@ -4,7 +4,8 @@ import * as find from '../src/find'
|
|||
test('finds test data wrapper jars', async () => {
|
||||
const repoRoot = path.resolve('.')
|
||||
const wrapperJars = await find.findWrapperJars(repoRoot)
|
||||
expect(wrapperJars.length).toBe(2)
|
||||
expect(wrapperJars.length).toBe(3)
|
||||
expect(wrapperJars).toContain('__tests__/data/valid/gradle-wrapper.jar')
|
||||
expect(wrapperJars).toContain('__tests__/data/invalid/gradle-wrapper.jar')
|
||||
expect(wrapperJars).toContain('__tests__/data/invalid/gradlе-wrapper.jar') // homoglyph
|
||||
})
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as validate from '../src/validate'
|
|||
const baseDir = path.resolve('.')
|
||||
|
||||
test('succeeds if all found wrapper jars are valid', async () => {
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 2, false, [
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
])
|
||||
|
||||
|
@ -12,13 +12,14 @@ test('succeeds if all found wrapper jars are valid', async () => {
|
|||
|
||||
expect(result.toDisplayString()).toBe(
|
||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||
)
|
||||
})
|
||||
|
||||
test('fails if invalid wrapper jars are found', async () => {
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 2, false, [])
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [])
|
||||
|
||||
expect(result.isValid()).toBe(false)
|
||||
|
||||
|
@ -33,31 +34,37 @@ test('fails if invalid wrapper jars are found', async () => {
|
|||
new validate.WrapperJar(
|
||||
'__tests__/data/invalid/gradle-wrapper.jar',
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
),
|
||||
new validate.WrapperJar(
|
||||
'__tests__/data/invalid/gradlе-wrapper.jar', // homoglyph
|
||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||
)
|
||||
])
|
||||
|
||||
expect(result.toDisplayString()).toBe(
|
||||
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||
)
|
||||
})
|
||||
|
||||
test('fails if not enough wrapper jars are found', async () => {
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [])
|
||||
const result = await validate.findInvalidWrapperJars(baseDir, 4, false, [])
|
||||
|
||||
expect(result.isValid()).toBe(false)
|
||||
|
||||
expect(result.errors).toEqual([
|
||||
'Expected to find at least 3 Gradle Wrapper JARs but got only 2'
|
||||
'Expected to find at least 4 Gradle Wrapper JARs but got only 3'
|
||||
])
|
||||
|
||||
expect(result.toDisplayString()).toBe(
|
||||
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||
'✗ Other validation errors:\n' +
|
||||
' Expected to find at least 3 Gradle Wrapper JARs but got only 2\n' +
|
||||
' Expected to find at least 4 Gradle Wrapper JARs but got only 3\n' +
|
||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||
)
|
||||
|
|
41
dist/index.js
vendored
41
dist/index.js
vendored
File diff suppressed because one or more lines are too long
|
@ -7,5 +7,6 @@ module.exports = {
|
|||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true
|
||||
verbose: true,
|
||||
setupFilesAfterEnv: ['./jest.setup.js']
|
||||
}
|
||||
|
|
1
jest.setup.js
Normal file
1
jest.setup.js
Normal file
|
@ -0,0 +1 @@
|
|||
jest.setTimeout(10000) // in milliseconds
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -6180,6 +6180,11 @@
|
|||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
|
||||
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
|
||||
},
|
||||
"unhomoglyph": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.3.tgz",
|
||||
"integrity": "sha512-PC/OAHE8aiTK0Gfmy0PxOlePazRn+BeCM1r4kFtkHgEnkJZgJoI7yD2yUEjsfSdLXKU1FSt/EcIZvNoKazYUTw=="
|
||||
},
|
||||
"union-value": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.0",
|
||||
"typed-rest-client": "^1.7.1"
|
||||
"typed-rest-client": "^1.7.1",
|
||||
"unhomoglyph": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^24.0.23",
|
||||
|
|
4
src/declarations.d.ts
vendored
Normal file
4
src/declarations.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
declare module 'unhomoglyph' {
|
||||
function unhomoglyph(input: string): string
|
||||
export = unhomoglyph
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
import * as util from 'util'
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
import unhomoglyph from 'unhomoglyph'
|
||||
|
||||
const readdir = util.promisify(fs.readdir)
|
||||
|
||||
export async function findWrapperJars(baseDir: string): Promise<string[]> {
|
||||
const files = await recursivelyListFiles(baseDir)
|
||||
return files
|
||||
.filter(file => file.endsWith('gradle-wrapper.jar'))
|
||||
.filter(file => unhomoglyph(file).endsWith('gradle-wrapper.jar'))
|
||||
.map(wrapperJar => path.relative(baseDir, wrapperJar))
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue