Skip to content

Commit b2519ff

Browse files
committed
Cod sample for partial path traversal
1 parent b694601 commit b2519ff

File tree

5 files changed

+54
-0
lines changed

5 files changed

+54
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package test.org.fugerit.java.code.samples.vulnerability;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.fugerit.java.core.function.SafeFunction;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.io.File;
9+
import java.io.IOException;
10+
import java.util.function.BiFunction;
11+
12+
/**
13+
*
14+
* This sample is based on the CodeQUL code scanning alert :
15+
* https://github.com/fugerit-org/fj-doc/security/code-scanning/103
16+
*
17+
*/
18+
@Slf4j
19+
class TestPartialPathTraversal {
20+
21+
private static final BiFunction<File, File, Boolean> CANONICAL_PATH_FUN =
22+
( dir, parent ) -> SafeFunction.get( () -> dir.getCanonicalPath().startsWith( parent.getCanonicalPath() ) );
23+
24+
private static final BiFunction<File, File, Boolean> NORMALIZED_PATH_FUN =
25+
( dir, parent ) -> SafeFunction.get( () -> dir.toPath().normalize().startsWith( parent.toPath().normalize() ) );
26+
27+
private boolean checkWorker( File dir, File parent, BiFunction<File, File, Boolean> fun, String desc ) throws IOException {
28+
boolean allowCheck = fun.apply( dir, parent );
29+
log.info( "checkWorker result : {}, dir : {}, parent : {}, desc : {}", allowCheck, dir.getCanonicalPath(), parent.getCanonicalPath(), desc );
30+
return allowCheck;
31+
}
32+
33+
@Test
34+
void testAllowCheck() throws IOException {
35+
File dir = new File( "./src/test/resources/partial-path-traversal/dir1" );
36+
File dir1v = new File( "./src/test/resources/partial-path-traversal/dir1vulnerable" );
37+
File dir1s = new File( "./src/test/resources/partial-path-traversal/dir1/subdir" );
38+
File dir1u = new File( "./src/test/resources/partial-path-traversal/dir2" );
39+
// CANONICAL_PATH_FUN will wrongly allow to use directory on the same level of allowed directory if substring
40+
Assertions.assertTrue( this.checkWorker( dir1v, dir, CANONICAL_PATH_FUN, "canonical path vulnerable" ) );
41+
// CANONICAL_PATH_FUN will correctly allow a subdir
42+
Assertions.assertTrue( this.checkWorker( dir1s, dir, CANONICAL_PATH_FUN, "canonical path real subdir" ) );
43+
// CANONICAL_PATH_FUN will correctly stop an unrelated dir
44+
Assertions.assertFalse( this.checkWorker( dir1u, dir, CANONICAL_PATH_FUN, "canonical path real subdir" ) );
45+
// NORMALIZED_PATH_FUN will correctly stop this
46+
Assertions.assertFalse( this.checkWorker( dir1v, dir, NORMALIZED_PATH_FUN, "normalized path vulnerable" ) );
47+
// NORMALIZED_PATH_FUN will correctly allow subdir
48+
Assertions.assertTrue( this.checkWorker( dir1s, dir, NORMALIZED_PATH_FUN, "normalized path real subdir" ) );
49+
// NORMALIZED_PATH_FUN will correctly stop unrelated dir
50+
Assertions.assertFalse( this.checkWorker( dir1u, dir, NORMALIZED_PATH_FUN, "normalized path real subdir" ) );
51+
52+
}
53+
54+
}

code-samples-base/src/test/resources/partial-path-traversal/dir1/donotdelete.txt

Whitespace-only changes.

code-samples-base/src/test/resources/partial-path-traversal/dir1/subdir/donotdelete.txt

Whitespace-only changes.

code-samples-base/src/test/resources/partial-path-traversal/dir1vulnerable/donotdelete.txt

Whitespace-only changes.

code-samples-base/src/test/resources/partial-path-traversal/dir2/donotdelete.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)