Summary
AbstractProcessRemoteResourcesMojo.processResourceBundles() builds the output file path directly from a remote bundle descriptor entry and writes into it without validating or normalizing the name:
File outputFile = new File(outputDirectory, projectResource);
FileUtils.mkdir(outputFile.getParentFile().getAbsolutePath());
...
URL bundleResourceUrl = classLoader.getResource(bundleResource);
if (bundleResourceUrl != null) {
FileUtils.copyURLToFile(bundleResourceUrl, outputFile);
}
src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java:936-963
Problems
new File(parent, child) silently ignores parent when child is absolute, so an absolute <remoteResource>/etc/...</remoteResource> in the descriptor targets an arbitrary path.
.. segments in the descriptor entry escape the output directory.
Impact
Content writes are partially constrained: non-.vm resources are only copied when classLoader.getResource(name) resolves the same (traversal) name, which usually fails. However:
FileUtils.mkdir(outputFile.getParentFile()...) runs unconditionally before that check (:938), so an untrusted bundle can create directories anywhere the build user can write.
- The local-override copy path
copyResourceIfExists() (:614-664) writes local project files to the traversal-resolved target, so a file outside the output directory can be overwritten when the layout lines up.
- The
.vm path uses the same unsanitized name for velocity.mergeTemplate(...).
A malicious/third-party bundle can create arbitrary directories (and, in the override case, overwrite files) outside the configured output directory.
Suggested fix
Validate/denormalize resource names before use: reject names containing .., leading /, backslashes, or drive letters; or resolve new File(outputDirectory, name) and verify it stays inside outputDirectory before mkdir/copy.
Note
See also copyProjectRootIfExists() (:666-679) and copyResourceIfExists() (:614-664) which use the same unsanitized bundleResourceName/projectResource to derive source files.
Summary
AbstractProcessRemoteResourcesMojo.processResourceBundles()builds the output file path directly from a remote bundle descriptor entry and writes into it without validating or normalizing the name:src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java:936-963Problems
new File(parent, child)silently ignoresparentwhenchildis absolute, so an absolute<remoteResource>/etc/...</remoteResource>in the descriptor targets an arbitrary path...segments in the descriptor entry escape the output directory.Impact
Content writes are partially constrained: non-
.vmresources are only copied whenclassLoader.getResource(name)resolves the same (traversal) name, which usually fails. However:FileUtils.mkdir(outputFile.getParentFile()...)runs unconditionally before that check (:938), so an untrusted bundle can create directories anywhere the build user can write.copyResourceIfExists()(:614-664) writes local project files to the traversal-resolved target, so a file outside the output directory can be overwritten when the layout lines up..vmpath uses the same unsanitized name forvelocity.mergeTemplate(...).A malicious/third-party bundle can create arbitrary directories (and, in the override case, overwrite files) outside the configured output directory.
Suggested fix
Validate/denormalize resource names before use: reject names containing
.., leading/, backslashes, or drive letters; or resolvenew File(outputDirectory, name)and verify it stays insideoutputDirectorybeforemkdir/copy.Note
See also
copyProjectRootIfExists()(:666-679) andcopyResourceIfExists()(:614-664) which use the same unsanitizedbundleResourceName/projectResourceto derive source files.