Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ protected void processResourceBundles(ClassLoader classLoader, VelocityContext c

// Don't overwrite resource that are already being provided.

File outputFile = new File(outputDirectory, projectResource);
File outputFile = resolveOutputFile(outputDirectory, projectResource);

FileUtils.mkdir(outputFile.getParentFile().getAbsolutePath());

Expand Down Expand Up @@ -992,6 +992,20 @@ protected void processResourceBundles(ClassLoader classLoader, VelocityContext c
}
}

static File resolveOutputFile(File outputDirectory, String resourceName)
throws IOException, MojoExecutionException {
if (new File(resourceName).isAbsolute()) {
throw new MojoExecutionException("Remote resource is outside the output directory: " + resourceName);
}
File canonicalOutputDirectory = outputDirectory.getCanonicalFile();
File outputFile = new File(outputDirectory, resourceName).getCanonicalFile();
if (outputFile.equals(canonicalOutputDirectory)
|| !outputFile.toPath().startsWith(canonicalOutputDirectory.toPath())) {
throw new MojoExecutionException("Remote resource is outside the output directory: " + resourceName);
}
return outputFile;
}

private void verifyRequiredProperties(RemoteResourcesBundle bundle, URL url) throws MojoExecutionException {
if (bundle.getRequiredProjectProperties() == null
|| bundle.getRequiredProjectProperties().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ public void testNoBundles() throws Exception {
mojo.execute();
}

public void testRemoteResourceCannotEscapeOutputDirectory() throws Exception {
File outputDirectory = new File("target/remote-resource-output");

try {
AbstractProcessRemoteResourcesMojo.resolveOutputFile(outputDirectory, "../outside.txt");
fail("expected a resource outside the output directory to be rejected");
} catch (MojoExecutionException e) {
assertTrue(e.getMessage().contains("outside the output directory"));
}

try {
AbstractProcessRemoteResourcesMojo.resolveOutputFile(
outputDirectory, new File(outputDirectory.getParentFile(), "absolute.txt").getAbsolutePath());
fail("expected an absolute resource path outside the output directory to be rejected");
} catch (MojoExecutionException e) {
assertTrue(e.getMessage().contains("outside the output directory"));
}

File outputFile = AbstractProcessRemoteResourcesMojo.resolveOutputFile(outputDirectory, "nested/resource.txt");
assertEquals(new File(outputDirectory, "nested/resource.txt").getCanonicalFile(), outputFile);
}

public void testConfigureLocatorRequiresProjectFile() throws Exception {
final MavenProjectResourcesStub project = createTestProject("default-null-pom");
final ProcessRemoteResourcesMojo mojo = lookupProcessMojoWithDefaultSettings(project);
Expand Down