Additional check when unpacking archives. Contributed by Wilfred Spiegelenburg.
This commit is contained in:
parent
d5708bbcdc
commit
65e55097da
|
@ -109,6 +109,7 @@ public class RunJar {
|
|||
throws IOException {
|
||||
try (JarFile jar = new JarFile(jarFile)) {
|
||||
int numOfFailedLastModifiedSet = 0;
|
||||
String targetDirPath = toDir.getCanonicalPath() + File.separator;
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
final JarEntry entry = entries.nextElement();
|
||||
|
@ -117,6 +118,10 @@ public class RunJar {
|
|||
try (InputStream in = jar.getInputStream(entry)) {
|
||||
File file = new File(toDir, entry.getName());
|
||||
ensureDirectory(file.getParentFile());
|
||||
if (!file.getCanonicalPath().startsWith(targetDirPath)) {
|
||||
throw new IOException("expanding " + entry.getName()
|
||||
+ " would create file outside of " + toDir);
|
||||
}
|
||||
try (OutputStream out = new FileOutputStream(file)) {
|
||||
IOUtils.copyBytes(in, out, BUFFER_SIZE);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,15 @@ package org.apache.hadoop.util;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
@ -165,4 +168,37 @@ public class TestRunJar {
|
|||
runJar.run(args);
|
||||
// it should not throw an exception
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnJar2() throws IOException {
|
||||
// make a simple zip
|
||||
File jarFile = new File(TEST_ROOT_DIR, TEST_JAR_NAME);
|
||||
JarOutputStream jstream =
|
||||
new JarOutputStream(new FileOutputStream(jarFile));
|
||||
JarEntry je = new JarEntry("META-INF/MANIFEST.MF");
|
||||
byte[] data = "Manifest-Version: 1.0\nCreated-By: 1.8.0_1 (Manual)"
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
je.setSize(data.length);
|
||||
jstream.putNextEntry(je);
|
||||
jstream.write(data);
|
||||
jstream.closeEntry();
|
||||
je = new JarEntry("../outside.path");
|
||||
data = "any data here".getBytes(StandardCharsets.UTF_8);
|
||||
je.setSize(data.length);
|
||||
jstream.putNextEntry(je);
|
||||
jstream.write(data);
|
||||
jstream.closeEntry();
|
||||
jstream.close();
|
||||
|
||||
File unjarDir = getUnjarDir("unjar-path");
|
||||
|
||||
// Unjar everything
|
||||
try {
|
||||
RunJar.unJar(jarFile, unjarDir);
|
||||
fail("unJar should throw IOException.");
|
||||
} catch (IOException e) {
|
||||
GenericTestUtils.assertExceptionContains(
|
||||
"would create file outside of", e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue