This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new d7c74c7aeba NIFI-15653 Fix DeleteSFTP security check for dot directory
path
d7c74c7aeba is described below
commit d7c74c7aeba36fa06cd2c7190054c8a003957248
Author: Rakesh Kumar Singh <[email protected]>
AuthorDate: Wed May 20 16:09:52 2026 +0530
NIFI-15653 Fix DeleteSFTP security check for dot directory path
When the Remote Path property is set to '.' (as produced by ListSFTP),
Paths.get('.').normalize() returns an empty Path (''). Resolving a
filename against that empty path yields a single-component relative
path whose getParent() returns null, causing the directory-traversal
security check to fail incorrectly and route every FlowFile to the
failure relationship.
Fix: when fileParent is null (single-component relative path), substitute
Paths.get('') for the comparison. Both the empty normalized path and a
null parent represent the implicit current directory, so the check now
correctly passes. Path-traversal attempts (e.g. '../etc/passwd') still
produce a non-empty parent that does not equal the empty directoryPath,
so the security guard remains intact.
Add TestDeleteSFTP.deletesFileWhenDirectoryPathIsDot() to cover the
regression.
This closes #11266.
Signed-off-by: Peter Turcsanyi <[email protected]>
---
.../java/org/apache/nifi/processors/standard/DeleteSFTP.java | 3 ++-
.../org/apache/nifi/processors/standard/TestDeleteSFTP.java | 12 ++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/DeleteSFTP.java
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/DeleteSFTP.java
index 5d284d3437c..29b6845b7bb 100644
---
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/DeleteSFTP.java
+++
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/DeleteSFTP.java
@@ -211,7 +211,8 @@ public class DeleteSFTP extends AbstractProcessor {
filename =
context.getProperty(FILENAME).evaluateAttributeExpressions(flowFile).getValue();
final Path filePath =
directoryPath.resolve(filename).normalize();
- if (!directoryPath.equals(filePath.getParent())) {
+ final Path fileParent = filePath.getParent();
+ if (!directoryPath.equals(fileParent == null ?
Paths.get("") : fileParent)) {
final String errorMessage = "Attempting to delete
file at path '%s' which is not a direct child of the directory '%s'"
.formatted(filePath, directoryPath);
diff --git
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestDeleteSFTP.java
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestDeleteSFTP.java
index eeb91b82475..0ce6c5b50cd 100644
---
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestDeleteSFTP.java
+++
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestDeleteSFTP.java
@@ -154,6 +154,18 @@ class TestDeleteSFTP {
runner.assertAllFlowFilesTransferred(DeleteSFTP.REL_SUCCESS);
}
+ @Test
+ void deletesFileWhenDirectoryPathIsDot() throws IOException {
+ final Path fileToDelete =
Files.writeString(sshServerRootPath.resolve("test.txt"), "some text");
+ enqueue(".", fileToDelete.getFileName().toString());
+ assertExists(fileToDelete);
+
+ runner.run();
+
+ assertNotExists(fileToDelete);
+ runner.assertAllFlowFilesTransferred(DeleteSFTP.REL_SUCCESS, 1);
+ }
+
@Test
void sendsFlowFileToFailureWhenFileIsNotADirectChildOfTheDirectory()
throws IOException {
final Path directoryPath =
Files.createDirectories(sshServerRootPath.resolve("rel/path"));