apache / apache/maven-remote-resources-plugin

Path traversal via bundle descriptor resource names (CWE-22)

Open
#265 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
17
Forks
18
Avg merge
6h 5m
Merged PRs (30d)
5

Description

## 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:

```java
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
1. `new File(parent, child)` silently ignores `parent` when `child` is absolute, so an absolute `/etc/...` in the descriptor targets an arbitrary path.
2. `..` 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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in src/main/java/org/apache/maven/plugin/resources/remote/AbstractProcessRemoteResourcesMojo.java, especially processResourceBundles() at lines 936-963 and copyResourceIfExists() at lines 614-664. Trace how bundleResourceName and projectResource reach mkdir, copy, and velocity.mergeTemplate. Done means resource names cannot escape outputDirectory, including absolute paths, traversal segments, backslashes, or drive letters, while valid resources still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.