Summary
ShadowCopyAction in the Shadow plugin does not validate or sanitize
ZIP entry names before writing them to the output fat JAR. A malicious
upstream dependency containing path traversal sequences (e.g.
../../../../tmp/pwned.txt) in entry names will have those entries
reproduced verbatim in the output shadow JAR.
Details
The vulnerability exists because Shadow relies entirely on Gradle's
ZipFileTree for entry sanitization rather than implementing its own
path validation. This means:
- Users on Gradle < 7.6.2 / 8.x < 8.2.0 are directly exploitable
- The produced shadow JAR becomes a Zip Slip weapon against any
downstream consumer using unprotected extraction (raw ZipInputStream,
older CI tooling, custom Java unpackers)
- If Shadow ever uses a non-ZipFileTree code path, protection
disappears silently
Affected file: src/main/kotlin/com/github/jengelman/gradle/plugins/ shadow/internal/ShadowCopyAction.kt
PoC
- Create a malicious JAR with path traversal entry:
import zipfile
with zipfile.ZipFile('evil.jar', 'w') as zf:
zf.writestr('../../../../tmp/zipslip_proof.txt', 'pwned')
- Add as dependency in a shadow project
- Run
gradle shadowJar
- Run
unzip -l build/libs/*.jar | grep "\.\."
- Traversal entry survives in output JAR
Impact
Any tool extracting the shadow JAR with unprotected extraction is
subject to arbitrary file overwrite. Users on older Gradle versions
are directly vulnerable at build time.
Summary
ShadowCopyAction in the Shadow plugin does not validate or sanitize
ZIP entry names before writing them to the output fat JAR. A malicious
upstream dependency containing path traversal sequences (e.g.
../../../../tmp/pwned.txt) in entry names will have those entriesreproduced verbatim in the output shadow JAR.
Details
The vulnerability exists because Shadow relies entirely on Gradle's
ZipFileTree for entry sanitization rather than implementing its own
path validation. This means:
downstream consumer using unprotected extraction (raw ZipInputStream,
older CI tooling, custom Java unpackers)
disappears silently
Affected file:
src/main/kotlin/com/github/jengelman/gradle/plugins/ shadow/internal/ShadowCopyAction.ktPoC
gradle shadowJarunzip -l build/libs/*.jar | grep "\.\."Impact
Any tool extracting the shadow JAR with unprotected extraction is
subject to arbitrary file overwrite. Users on older Gradle versions
are directly vulnerable at build time.