You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tu...@apache.org on 2026/05/22 16:25:13 UTC
(nifi) branch main updated: NIFI-15653 Fix DeleteSFTP security check for dot directory path
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 <rs...@gmail.com>
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 <tu...@apache.org>
---
.../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"));