Commit 0f27b1a6 authored by Andy Wilkinson's avatar Andy Wilkinson

Verify entry output location when extracting zip

Closes gh-16028
parent 30bba53a
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -122,8 +122,17 @@ class ProjectGenerator { ...@@ -122,8 +122,17 @@ class ProjectGenerator {
private void extractFromStream(ZipInputStream zipStream, boolean overwrite, private void extractFromStream(ZipInputStream zipStream, boolean overwrite,
File outputFolder) throws IOException { File outputFolder) throws IOException {
ZipEntry entry = zipStream.getNextEntry(); ZipEntry entry = zipStream.getNextEntry();
String canonicalOutputPath = outputFolder.getCanonicalPath() + File.separator;
while (entry != null) { while (entry != null) {
File file = new File(outputFolder, entry.getName()); File file = new File(outputFolder, entry.getName());
String canonicalEntryPath = file.getCanonicalPath();
if (!canonicalEntryPath.startsWith(canonicalOutputPath)) {
throw new ReportableException("Entry '" + entry.getName()
+ "' would be written to '" + canonicalEntryPath
+ "'. This is outside the output location of '"
+ canonicalOutputPath
+ "'. Verify your target server configuration.");
}
if (file.exists() && !overwrite) { if (file.exists() && !overwrite) {
throw new ReportableException((file.isDirectory() ? "Directory" : "File") throw new ReportableException((file.isDirectory() ? "Directory" : "File")
+ " '" + file.getName() + " '" + file.getName()
......
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -125,6 +125,20 @@ public class InitCommandTests extends AbstractHttpClientMockTests { ...@@ -125,6 +125,20 @@ public class InitCommandTests extends AbstractHttpClientMockTests {
assertThat(archiveFile).exists(); assertThat(archiveFile).exists();
} }
@Test
public void generateProjectAndExtractWillNotWriteEntriesOutsideOutputLocation()
throws Exception {
File folder = this.temporaryFolder.newFolder();
byte[] archive = createFakeZipArchive("../outside.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.ERROR);
File archiveFile = new File(folder.getParentFile(), "outside.txt");
assertThat(archiveFile).doesNotExist();
}
@Test @Test
public void generateProjectAndExtractWithConvention() throws Exception { public void generateProjectAndExtractWithConvention() throws Exception {
File folder = this.temporaryFolder.newFolder(); File folder = this.temporaryFolder.newFolder();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment