...
Code Block | ||
---|---|---|
| ||
static final int BUFFER = 512; static final intlong TOOBIG = 0x6400000; // maxMax size of unzipped data, 100MB static final int TOOMANY = 1024; // maxMax number of files // ... private String validateFilename(String filename, String intendedDir) throws java.io.IOException { File f = new File(filename); String canonicalPath = f.getCanonicalPath(); File iD = new File(intendedDir); String canonicalID = iD.getCanonicalPath(); if (canonicalPath.startsWith(canonicalID)) { return canonicalPath; } else { throw new IllegalStateException("File is outside extraction target directory."); } } public final void unzip(String filename) throws java.io.IOException { FileInputStream fis = new FileInputStream(filename); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; int entries = 0; long total = 0; try { while ((entry = zis.getNextEntry()) != null) { System.out.println("Extracting: " + entry); int count; byte data[] = new byte[BUFFER]; // Write the files to the disk, but ensure that the filename is valid, // and that the file is not insanely big String name = validateFilename(entry.getName(), "."); if (entry.isDirectory()) { System.out.println("Creating directory " + name); new File(name).mkdir(); continue; } FileOutputStream fos = new FileOutputStream(name); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); while (total + BUFFER <= TOOBIG && (count = zis.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, count); total += count; } dest.flush(); dest.close(); zis.closeEntry(); entries++; if (entries > TOOMANY) { throw new IllegalStateException("Too many files to unzip."); } if (total + BUFFER > TOOBIG) { throw new IllegalStateException("File being unzipped is too big."); } } } finally { zis.close(); } } |
Risk Assessment
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
IDS04-J | Low | Probable | High | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
The Checker Framework |
| Tainting Checker | Trust and security errors (see Chapter 8) | ||||||
SonarQube |
|
Related Guidelines
CWE-409, Improper |
Handling of Highly Compressed Data (Data Amplification) |
Guideline |
1-1 / DOS-1: Beware of activities that may use disproportionate resources |
Related Vulnerabilities
Vulnerability | Description |
---|---|
Zip Slip | Zip Slip is a form of directory traversal that can be exploited by extracting files from an archive. It is caused by a failure to validate path names of the files within an archive which can lead to files being extracted outside of the intended directory and overwriting existing system files. An attacker can exploit this vulnerability to overwrite executable files to achieve remote command execution on a victim’s machine. Snyk responsibly disclosed the vulnerability before public disclosure on June 5th 2018. Their blog post and technical paper detailing the vulnerability can be found at https://snyk.io/blog/zip-slip-vulnerability/. |
Android Implementation Details
Although not directly a violation of this rule, the Android Master Key vulnerability (insecure use of ZipEntry
) is related to this rule. Another attack vector, found by a researcher in China, is also related to this rule.
Bibliography
...
...