Skip to content

Commit 20705ca

Browse files
Jami CogswellJami Cogswell
authored andcommitted
Java: add library tests, remove query tests
1 parent 9f244aa commit 20705ca

File tree

2 files changed

+152
-34
lines changed

2 files changed

+152
-34
lines changed

java/ql/test/library-tests/pathsanitizer/Test.java

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.nio.file.Path;
44
import java.nio.file.Paths;
55
import android.net.Uri;
6+
import java.io.BufferedReader;
7+
import java.io.InputStreamReader;
8+
import java.net.Socket;
69

710
public class Test {
811

@@ -61,6 +64,7 @@ public void exactPathMatchGuard() throws Exception {
6164
}
6265

6366
private void allowListGuardValidation(String path) throws Exception {
67+
//if (path.indexOf("..") != -1 || !path.startsWith("/safe"))
6468
if (path.contains("..") || !path.startsWith("/safe"))
6569
throw new Exception();
6670
}
@@ -463,4 +467,152 @@ public void blockListGuard() throws Exception {
463467
}
464468
}
465469
}
470+
471+
private void fileConstructorValidation(String path) throws Exception {
472+
// Use `indexOf` instead of `contains` for this test since a `contains`
473+
// call in this scenario will already be sanitized due to the inclusion
474+
// of `ValidatedVariableAccess` nodes in `defaultTaintSanitizer`.
475+
if (path.indexOf("..") != -1)
476+
throw new Exception();
477+
}
478+
479+
public void fileConstructor() throws Exception {
480+
// PathTraversalGuard
481+
{
482+
String source = (String) source();
483+
File f1 = new File("safe/file.txt");
484+
if (!source.contains("..")) {
485+
File f2 = new File(f1, source);
486+
sink(f2); // Safe
487+
sink(source); // $ hasTaintFlow
488+
} else {
489+
File f3 = new File(f1, source);
490+
sink(f3); // $ hasTaintFlow
491+
sink(source); // $ hasTaintFlow
492+
}
493+
}
494+
{
495+
String source = (String) source();
496+
497+
// `f1` tainted by an `ActiveThreatModelSource`
498+
Socket sock = new Socket();
499+
BufferedReader filenameReader =
500+
new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
501+
String filename = filenameReader.readLine();
502+
File f1Tainted = new File(filename); // tainted
503+
504+
if (!source.contains("..")) {
505+
// `f2` is unsafe if `f1` is tainted
506+
File f2 = new File(f1Tainted, source);
507+
sink(f2); // $ hasTaintFlow
508+
sink(source); // $ hasTaintFlow
509+
} else {
510+
File f3 = new File(f1Tainted, source);
511+
sink(f3); // $ hasTaintFlow
512+
sink(source); // $ hasTaintFlow
513+
}
514+
}
515+
{
516+
String source = (String) source();
517+
File f1Null = null;
518+
if (!source.contains("..")) {
519+
// `f2` is unsafe if `f1` is null
520+
File f2 = new File(f1Null, source);
521+
sink(f2); // $ hasTaintFlow
522+
sink(source); // $ hasTaintFlow
523+
} else {
524+
File f3 = new File(f1Null, source);
525+
sink(f3); // $ hasTaintFlow
526+
sink(source); // $ hasTaintFlow
527+
}
528+
}
529+
{
530+
String source = (String) source();
531+
File f1 = new File("safe/file.txt");
532+
if (source.indexOf("..") == -1) {
533+
File f2 = new File(f1, source);
534+
sink(f2); // Safe
535+
sink(source); // $ hasTaintFlow
536+
} else {
537+
File f3 = new File(f1, source);
538+
sink(f3); // $ hasTaintFlow
539+
sink(source); // $ hasTaintFlow
540+
}
541+
}
542+
{
543+
String source = (String) source();
544+
File f1 = new File("safe/file.txt");
545+
if (source.indexOf("..") != -1) {
546+
File f2 = new File(f1, source);
547+
sink(f2); // $ hasTaintFlow
548+
sink(source); // $ hasTaintFlow
549+
} else {
550+
File f3 = new File(f1, source);
551+
sink(f3); // Safe
552+
sink(source); // $ hasTaintFlow
553+
}
554+
}
555+
{
556+
String source = (String) source();
557+
File f1 = new File("safe/file.txt");
558+
if (source.lastIndexOf("..") == -1) {
559+
File f2 = new File(f1, source);
560+
sink(f2); // Safe
561+
sink(source); // $ hasTaintFlow
562+
} else {
563+
File f3 = new File(f1, source);
564+
sink(f3); // $ hasTaintFlow
565+
sink(source); // $ hasTaintFlow
566+
}
567+
}
568+
// validation method
569+
{
570+
String source = (String) source();
571+
File f1 = new File("safe/file.txt");
572+
fileConstructorValidation(source);
573+
File f2 = new File(f1, source);
574+
sink(f2); // Safe
575+
sink(source); // $ hasTaintFlow
576+
}
577+
{
578+
String source = (String) source();
579+
File f1 = new File("safe/file.txt");
580+
581+
if (source.contains("..")) {
582+
throw new Exception();
583+
} else {
584+
File f2 = new File(f1, source);
585+
sink(f2); // Safe
586+
sink(source); // $ hasTaintFlow
587+
}
588+
}
589+
// PathNormalizeSanitizer
590+
{
591+
File source = (File) source();
592+
String normalized = source.getCanonicalPath();
593+
File f1 = new File("safe/file.txt");
594+
File f2 = new File(f1, normalized);
595+
sink(f2); // Safe
596+
sink(source); // $ hasTaintFlow
597+
sink(normalized); // $ hasTaintFlow
598+
}
599+
{
600+
File source = (File) source();
601+
String normalized = source.getCanonicalFile().toString();
602+
File f1 = new File("safe/file.txt");
603+
File f2 = new File(f1, normalized);
604+
sink(f2); // Safe
605+
sink(source); // $ hasTaintFlow
606+
sink(normalized); // $ hasTaintFlow
607+
}
608+
{
609+
String source = (String) source();
610+
String normalized = Paths.get(source).normalize().toString();
611+
File f1 = new File("safe/file.txt");
612+
File f2 = new File(f1, normalized);
613+
sink(f2); // Safe
614+
sink(source); // $ hasTaintFlow
615+
sink(normalized); // $ hasTaintFlow
616+
}
617+
}
466618
}

java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -86,38 +86,4 @@ public void sendUserFileGood4(Socket sock, String user) throws IOException {
8686
fileLine = fileReader.readLine();
8787
}
8888
}
89-
90-
public void sendUserFileGood5(Socket sock, String user) throws IOException {
91-
BufferedReader filenameReader =
92-
new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
93-
String filename = filenameReader.readLine();
94-
File f1 = new File("safe/file.txt");
95-
// GOOD: ensure that the path does not contain ".." and is used as the
96-
// second argument to a `File` constructor
97-
if (!filename.contains("..")) {
98-
File f2 = new File(f1, filename);
99-
f2.exists();
100-
101-
// Only sanitize `f2`; `filename` is still tainted
102-
BufferedReader fileReader = new BufferedReader(new FileReader(filename)); // $ hasTaintFlow
103-
}
104-
}
105-
106-
public void sendUserFileGood6(Socket sock, String user) throws IOException {
107-
BufferedReader filenameReader =
108-
new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
109-
String filename = filenameReader.readLine();
110-
File f1 = new File("safe/file.txt");
111-
112-
// GOOD: ensure that the path is normalized and is then used as the
113-
// second argument to a `File` constructor
114-
Path normalizedFilename = Paths.get(filename).normalize().toAbsolutePath();
115-
String normalizedFilenameStr = normalizedFilename.toString();
116-
File f2 = new File(f1, normalizedFilenameStr);
117-
f2.exists();
118-
119-
// Only sanitize `f2`; `filename` and `normalizedFilenameStr` are still tainted
120-
BufferedReader fileReader = new BufferedReader(new FileReader(filename)); // $ hasTaintFlow
121-
BufferedReader fileReader2 = new BufferedReader(new FileReader(normalizedFilenameStr)); // $ hasTaintFlow
122-
}
12389
}

0 commit comments

Comments
 (0)