From 774e4cfcb33164672956c6fc4a5cf3f4fe290458 Mon Sep 17 00:00:00 2001 From: tathagta15 Date: Thu, 18 Jun 2026 15:25:41 +0530 Subject: [PATCH] [ACS-11995] fix codeql path and command injection (#1292) --- .../AbstractMetadataExtractsIT.java | 4 ++ .../transform/base/executors/RuntimeExec.java | 55 +++++++++++++++++-- .../metadata/AbstractMetadataExtractsIT.java | 4 ++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractMetadataExtractsIT.java b/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractMetadataExtractsIT.java index 25e0f833..822d80fb 100644 --- a/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractMetadataExtractsIT.java +++ b/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractMetadataExtractsIT.java @@ -120,6 +120,10 @@ public abstract class AbstractMetadataExtractsIT private Map readExpectedMetadata(String filename, File actualMetadataFile) throws IOException { + if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) + { + throw new IllegalArgumentException("Invalid expected metadata filename: " + filename); + } try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filename)) { if (inputStream == null) diff --git a/engines/base/src/main/java/org/alfresco/transform/base/executors/RuntimeExec.java b/engines/base/src/main/java/org/alfresco/transform/base/executors/RuntimeExec.java index 1ee77ba6..3bb4e404 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/executors/RuntimeExec.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/executors/RuntimeExec.java @@ -667,11 +667,7 @@ public class RuntimeExec { String key = entry.getKey(); String value = entry.getValue() == null ? "" : entry.getValue(); - if (value.contains("\n") || value.contains("\r") || value.contains("\0")) - { - throw new IllegalArgumentException( - "Command property '" + key + "' contains an illegal character"); - } + validateCommandPropertyValue(key, value); // progressively replace the property in the command key = (VAR_OPEN + key + VAR_CLOSE); int index = sb.indexOf(key); @@ -704,6 +700,55 @@ public class RuntimeExec return adjustedCommandElements.toArray(new String[0]); } + private void validateCommandPropertyValue(String key, String value) + { + if (value.contains("\n") || value.contains("\r") || value.contains("\0")) + { + throw new IllegalArgumentException( + "Command property '" + key + "' contains an illegal character"); + } + + if ("source".equals(key) || "target".equals(key)) + { + validatePathProperty(key, value); + } + else if ("sourceMimetype".equals(key) || "targetMimetype".equals(key)) + { + validateMimetypeProperty(key, value); + } + } + + private void validatePathProperty(String key, String value) + { + if (value.isBlank()) + { + throw new IllegalArgumentException("Command property '" + key + "' must not be blank"); + } + + // Allow quotes/backticks in paths; this class executes via Runtime.exec(String[]) (no shell parsing) + + File file = new File(value); + if (!file.isAbsolute()) + { + throw new IllegalArgumentException( + "Command property '" + key + "' must be an absolute path"); + } + } + + private void validateMimetypeProperty(String key, String value) + { + if (value.isBlank()) + { + throw new IllegalArgumentException("Command property '" + key + "' must not be blank"); + } + + if (!value.matches("^[a-zA-Z0-9!#$&^_.+-]+/[a-zA-Z0-9!#$&^_.+-]+$")) + { + throw new IllegalArgumentException( + "Command property '" + key + "' is not a valid mimetype"); + } + } + /** * Object to carry the results of an execution to the caller. * diff --git a/engines/base/src/test/java/org/alfresco/transform/base/metadata/AbstractMetadataExtractsIT.java b/engines/base/src/test/java/org/alfresco/transform/base/metadata/AbstractMetadataExtractsIT.java index e1e93ae5..a5b2641d 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/metadata/AbstractMetadataExtractsIT.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/metadata/AbstractMetadataExtractsIT.java @@ -119,6 +119,10 @@ public abstract class AbstractMetadataExtractsIT private Map readExpectedMetadata(String filename, File actualMetadataFile) throws IOException { + if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) + { + throw new IllegalArgumentException("Invalid expected metadata filename: " + filename); + } try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filename)) { if (inputStream == null)