...
Code Block | ||
---|---|---|
| ||
static final int BUFFER = 512; // ... // external data source: filename private void validateFilename(String filename) { ... } public final void unzip(String filename){ FileInputStream fis = new FileInputStream(filename); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { System.out.println("Extracting: " + entry); int count; byte data[] = new byte[BUFFER]; // write the files to the disk String name = validateFilename(entry.getName()); FileOutputStream fos = new FileOutputStream(name); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); while ((count = zis.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, count); } dest.flush(); dest.close(); zis.closeEntry(); } zis.close(); } |
Compliant Solution
In this compliant solution, the code inside the while loop tracks the uncompressed file size of each entry in a zip archive while extracting the entry. It throws an exception if the entry being extracted is too large — about 100MB in this case. We do not use the ZipEntry.getSize()
method because the value it reports is not reliable.
Code Block | ||
---|---|---|
| ||
static final int BUFFER = 512; static final int TOOBIG = 0x6400000; // 100MB // ... private void validateFilename(String filename) { ... } //public externalfinal data source:void unzip(String filename){ FileInputStream fis = new FileInputStream(filename); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); ZipEntry entry; 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 file is not insanely big int total = 0; String name = validateFilename(entry.getName()); FileOutputStream fos = new FileOutputStream(name); Â BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); Â while (total <= TOOBIG && (count = zis.read(data, 0, BUFFER)) != -1) { Â Â Â dest.write(data, 0, count); Â Â Â total += count; Â } Â dest.flush(); Â dest.close(); zis.closeEntry(); if (total > TOOBIG){ throw new IllegalStateException("File being unzipped is huge."); } } } finally { zis.close(); } } |
Risk Assessment
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
IDS04-J | low | probable | high | P2 | L3 |
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="47d1bd3300b340d5-c1700bd4-45354f8b-8322abd0-d2ceb3862ff530fa0e76d500"><ac:plain-text-body><![CDATA[ | [[Mahmoud 2002 | AA. References#Mahmoud 02]] | [Compressing and Decompressing Data Using Java APIs | http://java.sun.com/developer/technicalArticles/Programming/compression/] | ]]></ac:plain-text-body></ac:structured-macro> |
...