This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.18.x by this push:
new 59d30af17064 [backport camel-4.18.x] CAMEL-24893: camel-docling -
reject absolute paths in custom-argument path validation (#26744)
59d30af17064 is described below
commit 59d30af17064320073e17cfb516be60d096bb979
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Sep 22 20:31:47 2026 +0200
[backport camel-4.18.x] CAMEL-24893: camel-docling - reject absolute paths
in custom-argument path validation (#26744)
* [backport camel-4.18.x] CAMEL-24893: camel-docling - reject absolute
paths in custom-argument path validation
* fix: add missing Map import in DoclingCustomArgsValidationTest
---
.../camel/component/docling/DoclingProducer.java | 11 +++++---
.../docling/DoclingCustomArgsValidationTest.java | 31 ++++++++++++++++++++++
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
index 49e911c2c14b..f1b6c24d43f6 100644
---
a/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
+++
b/components/camel-ai/camel-docling/src/main/java/org/apache/camel/component/docling/DoclingProducer.java
@@ -1876,7 +1876,7 @@ public class DoclingProducer extends DefaultProducer {
/**
* Validates custom CLI arguments using an allowlist approach. Only
recognized docling CLI flags are permitted.
- * Producer-managed flags, shell metacharacters, and path traversal
sequences are rejected.
+ * Producer-managed flags, shell metacharacters, absolute paths, and path
traversal sequences are rejected.
*/
private void validateCustomArguments(List<String> customArgs) {
for (int i = 0; i < customArgs.size(); i++) {
@@ -1959,9 +1959,14 @@ public class DoclingProducer extends DefaultProducer {
throw new IllegalArgumentException(
"Custom argument at index " + index + " contains a
relative path traversal sequence");
}
- // Normalize path-like values to detect traversal via redundant
separators
+ // Normalize path-like values to detect absolute paths or traversal
via redundant separators
if (value.contains("/") || value.contains("\\")) {
- Path normalized = Paths.get(value).normalize();
+ Path path = Paths.get(value);
+ if (path.isAbsolute()) {
+ throw new IllegalArgumentException(
+ "Custom argument at index " + index + " must not be an
absolute path");
+ }
+ Path normalized = path.normalize();
for (Path component : normalized) {
if ("..".equals(component.toString())) {
throw new IllegalArgumentException(
diff --git
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
index 0e309ed36833..918679baa106 100644
---
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
+++
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/DoclingCustomArgsValidationTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.docling;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
+import java.util.Map;
import org.apache.camel.CamelExecutionException;
import org.apache.camel.builder.RouteBuilder;
@@ -265,6 +266,36 @@ class DoclingCustomArgsValidationTest extends
CamelTestSupport {
ex.getCause().getMessage().contains("traversal after
normalization"));
}
+ @Test
+ void customArgsWithAbsolutePathAreRejected() throws Exception {
+ Path inputFile = createInputFile();
+
+ // An absolute path contains no relative traversal sequence and no
".." component after
+ // normalization, so it must be rejected by the explicit absolute-path
check.
+ CamelExecutionException ex =
assertThrows(CamelExecutionException.class, () -> {
+ template.requestBodyAndHeaders("direct:cli-convert",
+ inputFile.toString(),
+ Map.of(DoclingHeaders.CUSTOM_ARGUMENTS,
List.of("--artifacts-path", "/etc/cron.d")));
+ });
+
+ assertInstanceOf(IllegalArgumentException.class, ex.getCause());
+ assertTrue(ex.getCause().getMessage().contains("absolute path"));
+ }
+
+ @Test
+ void customArgsWithAbsolutePathEqualsFormAreRejected() throws Exception {
+ Path inputFile = createInputFile();
+
+ CamelExecutionException ex =
assertThrows(CamelExecutionException.class, () -> {
+ template.requestBodyAndHeaders("direct:cli-convert",
+ inputFile.toString(),
+ Map.of(DoclingHeaders.CUSTOM_ARGUMENTS,
List.of("--artifacts-path=/var/www/html/uploads")));
+ });
+
+ assertInstanceOf(IllegalArgumentException.class, ex.getCause());
+ assertTrue(ex.getCause().getMessage().contains("absolute path"));
+ }
+
private Path createInputFile() throws Exception {
Path file = tempDir.resolve("test-input.txt");
Files.writeString(file, "test content");