Skip to content

Commit 365fd78

Browse files
committed
feat(appsec): instrument Files.copy(Path,Path) and Files.copy(Path,OutputStream) for RASP
Files.copy(Path source, Path target, CopyOption[]) was missing from FilesCallSite: - fires beforeFileLoaded(source) for LFI detection on the source path - fires beforeFileWritten(target) for write detection on the target path Files.copy(Path source, OutputStream out) was also missing: - fires beforeFileLoaded(source) for LFI detection on the source path
1 parent 995f760 commit 365fd78

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

dd-java-agent/instrumentation/java/java-io-1.8/src/main/java/datadog/trace/instrumentation/java/lang/FilesCallSite.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ public static void beforeCopyFromStream(@CallSite.Argument(1) @Nullable final Pa
4343
}
4444
}
4545

46+
@CallSite.Before(
47+
"java.nio.file.Path java.nio.file.Files.copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption[])")
48+
public static void beforeCopyPathToPath(
49+
@CallSite.Argument(0) @Nullable final Path source,
50+
@CallSite.Argument(1) @Nullable final Path target) {
51+
if (source != null) {
52+
FileIORaspHelper.INSTANCE.beforeFileLoaded(source.toString());
53+
}
54+
if (target != null) {
55+
FileIORaspHelper.INSTANCE.beforeFileWritten(target.toString());
56+
}
57+
}
58+
4659
@CallSite.Before(
4760
"java.nio.file.Path java.nio.file.Files.move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption[])")
4861
public static void beforeMove(@CallSite.Argument(1) @Nullable final Path target) {
@@ -51,6 +64,13 @@ public static void beforeMove(@CallSite.Argument(1) @Nullable final Path target)
5164
}
5265
}
5366

67+
@CallSite.Before("long java.nio.file.Files.copy(java.nio.file.Path, java.io.OutputStream)")
68+
public static void beforeCopyToStream(@CallSite.Argument(0) @Nullable final Path source) {
69+
if (source != null) {
70+
FileIORaspHelper.INSTANCE.beforeFileLoaded(source.toString());
71+
}
72+
}
73+
5474
// ===================== READ =====================
5575

5676
@CallSite.Before(

dd-java-agent/instrumentation/java/java-io-1.8/src/test/groovy/datadog/trace/instrumentation/java/io/FilesCallSiteTest.groovy

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,35 @@ class FilesCallSiteTest extends BaseIoRaspCallSiteTest {
102102
1 * helper.beforeFileWritten(path.toString())
103103
}
104104

105+
void 'test RASP Files.copy path to path fires beforeFileLoaded on source and beforeFileWritten on target'() {
106+
setup:
107+
final helper = Mock(FileIORaspHelper)
108+
FileIORaspHelper.INSTANCE = helper
109+
final source = newFile('test_rasp_copy_src.txt').toPath()
110+
final target = temporaryFolder.resolve('test_rasp_copy_path_dst.txt')
111+
112+
when:
113+
TestFilesSuite.copyPathToPath(source, target)
114+
115+
then:
116+
1 * helper.beforeFileLoaded(source.toString())
117+
1 * helper.beforeFileWritten(target.toString())
118+
}
119+
120+
void 'test RASP Files.copy path to OutputStream fires beforeFileLoaded on source'() {
121+
setup:
122+
final helper = Mock(FileIORaspHelper)
123+
FileIORaspHelper.INSTANCE = helper
124+
final source = newFile('test_rasp_copy_stream_src.txt').toPath()
125+
126+
when:
127+
TestFilesSuite.copyToStream(source, new ByteArrayOutputStream())
128+
129+
then:
130+
1 * helper.beforeFileLoaded(source.toString())
131+
0 * helper.beforeFileWritten(_)
132+
}
133+
105134
void 'test RASP Files.move'() {
106135
setup:
107136
final helper = Mock(FileIORaspHelper)

dd-java-agent/instrumentation/java/java-io-1.8/src/test/java/foo/bar/TestFilesSuite.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ public static BufferedWriter newBufferedWriterDefaultCharset(
5757
return Files.newBufferedWriter(path, options);
5858
}
5959

60+
public static Path copyPathToPath(
61+
final Path source, final Path target, final CopyOption... options) throws IOException {
62+
return Files.copy(source, target, options);
63+
}
64+
65+
public static long copyToStream(final Path source, final OutputStream out) throws IOException {
66+
return Files.copy(source, out);
67+
}
68+
6069
public static Path move(final Path source, final Path target, final CopyOption... options)
6170
throws IOException {
6271
return Files.move(source, target);

0 commit comments

Comments
 (0)