Skip to content

Commit 3291c67

Browse files
committed
TEZ-4699:Add Validation/Canonical checks to avoid path exploitation in CSVResult.java
1 parent a0d8eb9 commit 3291c67

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

tez-tools/analyzers/job-analyzer/src/test/java/org/apache/tez/analyzer/TestCSVResult.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.io.IOException;
2323
import java.nio.charset.StandardCharsets;
24+
import java.nio.file.AccessDeniedException;
2425
import java.nio.file.FileAlreadyExistsException;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
@@ -29,25 +30,19 @@
2930
import org.junit.Rule;
3031
import org.junit.Test;
3132
import org.junit.rules.TemporaryFolder;
32-
import org.slf4j.Logger;
33-
import org.slf4j.LoggerFactory;
3433

35-
/**
36-
* Unit tests for {@link CSVResult#dumpToFile(String)} (validation and atomic create).
37-
*/
34+
3835
public class TestCSVResult {
3936

4037
@Rule
4138
public TemporaryFolder tmpDir = new TemporaryFolder();
42-
private static final Logger LOG = LoggerFactory.getLogger(TestCSVResult.class);
4339

4440
@Test
4541
public void testDumpToFileWritesContent() throws Exception {
4642
Path out = tmpDir.newFolder().toPath().resolve("out.csv");
4743
CSVResult result = new CSVResult(new String[] { "h1", "h2" });
4844
result.addRecord(new String[] { "a", "b" });
4945
result.dumpToFile(out.toString());
50-
LOG.info("output file path is : {}", out.getFileName() );
5146
String content = new String(Files.readAllBytes(out), StandardCharsets.UTF_8);
5247
Assert.assertEquals("h1,h2\na,b\n", content);
5348
}
@@ -60,7 +55,7 @@ public void testDumpToFileRejectsExistingFile() throws Exception {
6055
result.dumpToFile(out.toString());
6156
Assert.fail("Expected FileAlreadyExistsException when output file already exists");
6257
} catch (FileAlreadyExistsException e) {
63-
// CREATE_NEW must fail if path already exists (atomic exclusive create)
58+
Assert.assertTrue("expected File Already Exist Exception",e.getMessage().contains(out.toString()));
6459
}
6560
}
6661

@@ -103,4 +98,25 @@ public void testDumpToFileNestedDirectory() throws Exception {
10398
result.dumpToFile(out.toString());
10499
Assert.assertEquals("h\nr\n", new String(Files.readAllBytes(out), StandardCharsets.UTF_8));
105100
}
101+
102+
@Test
103+
public void testDumpToFileNoWritePermissionRelativePath() throws Exception {
104+
Path dir = tmpDir.newFolder("noWriteDir").toPath();
105+
dir.toFile().setWritable(false);
106+
Path out = dir.resolve("out.csv");
107+
String relativePath = dir + "/../noWriteDir/out.csv";
108+
CSVResult result = new CSVResult(new String[] { "h" });
109+
110+
try {
111+
result.dumpToFile(relativePath);
112+
Assert.fail("Expected AccessDeniedException due to no write permission");
113+
} catch (AccessDeniedException e) {
114+
Assert.assertTrue(
115+
"Expected permission related error",
116+
e.getMessage().contains(out.toString())
117+
);
118+
} finally {
119+
dir.toFile().setWritable(true);
120+
}
121+
}
106122
}

0 commit comments

Comments
 (0)