Skip to content

Commit 84a4b6a

Browse files
committed
Make reporting locations consistent with PathCreation; add test
1 parent 83498f5 commit 84a4b6a

File tree

5 files changed

+42
-10
lines changed

5 files changed

+42
-10
lines changed

java/ql/src/Security/CWE/CWE-022/TaintedPath.ql

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,21 @@ class TaintedPathConfig extends TaintTracking::Configuration {
5050
}
5151
}
5252

53+
/**
54+
* Gets the data-flow node at which to report a path ending at `sink`.
55+
*
56+
* Previously this query flagged alerts exclusively at `PathCreation` sites,
57+
* so to avoid perturbing existing alerts, where a `PathCreation` exists we
58+
* continue to report there; otherwise we report directly at `sink`.
59+
*/
60+
DataFlow::Node getReportingNode(DataFlow::Node sink) {
61+
any(TaintedPathConfig c).hasFlowTo(sink) and
62+
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
63+
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
64+
else result = sink
65+
}
66+
5367
from DataFlow::PathNode source, DataFlow::PathNode sink, TaintedPathConfig conf
5468
where conf.hasFlowPath(source, sink)
55-
select sink, source, sink, "$@ flows to here and is used in a path.", source.getNode(),
56-
"User-provided value"
69+
select getReportingNode(sink.getNode()), source, sink, "$@ flows to here and is used in a path.",
70+
source.getNode(), "User-provided value"

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edges
88
| Test.java:79:74:79:97 | getInputStream(...) : ServletInputStream | Test.java:79:52:79:98 | new InputStreamReader(...) : InputStreamReader |
99
| Test.java:80:31:80:32 | br : BufferedReader | Test.java:80:31:80:43 | readLine(...) : String |
1010
| Test.java:80:31:80:43 | readLine(...) : String | Test.java:82:67:82:81 | ... + ... |
11+
| Test.java:88:17:88:37 | getHostName(...) : String | Test.java:90:26:90:29 | temp |
1112
nodes
1213
| Test.java:19:18:19:38 | getHostName(...) : String | semmle.label | getHostName(...) : String |
1314
| Test.java:24:20:24:23 | temp | semmle.label | temp |
@@ -20,10 +21,13 @@ nodes
2021
| Test.java:80:31:80:32 | br : BufferedReader | semmle.label | br : BufferedReader |
2122
| Test.java:80:31:80:43 | readLine(...) : String | semmle.label | readLine(...) : String |
2223
| Test.java:82:67:82:81 | ... + ... | semmle.label | ... + ... |
24+
| Test.java:88:17:88:37 | getHostName(...) : String | semmle.label | getHostName(...) : String |
25+
| Test.java:90:26:90:29 | temp | semmle.label | temp |
2326
subpaths
2427
#select
2528
| Test.java:24:11:24:24 | new File(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:24:20:24:23 | temp | $@ flows to here and is used in a path. | Test.java:19:18:19:38 | getHostName(...) | User-provided value |
2629
| Test.java:27:11:27:25 | get(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:27:21:27:24 | temp | $@ flows to here and is used in a path. | Test.java:19:18:19:38 | getHostName(...) | User-provided value |
2730
| Test.java:30:11:30:48 | getPath(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:30:44:30:47 | temp | $@ flows to here and is used in a path. | Test.java:19:18:19:38 | getHostName(...) | User-provided value |
2831
| Test.java:34:12:34:25 | new File(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:34:21:34:24 | temp | $@ flows to here and is used in a path. | Test.java:19:18:19:38 | getHostName(...) | User-provided value |
2932
| Test.java:82:52:82:88 | new FileWriter(...) | Test.java:79:74:79:97 | getInputStream(...) : ServletInputStream | Test.java:82:67:82:81 | ... + ... | $@ flows to here and is used in a path. | Test.java:79:74:79:97 | getInputStream(...) | User-provided value |
33+
| Test.java:90:26:90:29 | temp | Test.java:88:17:88:37 | getHostName(...) : String | Test.java:90:26:90:29 | temp | $@ flows to here and is used in a path. | Test.java:88:17:88:37 | getHostName(...) | User-provided value |

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// http://cwe.mitre.org/data/definitions/22.html
33
package test.cwe22.semmle.tests;
44

5-
65
import javax.servlet.http.*;
76
import javax.servlet.ServletException;
87

@@ -12,20 +11,21 @@
1211
import java.nio.file.Paths;
1312
import java.nio.file.FileSystems;
1413

14+
import org.apache.commons.io.output.LockableFileWriter;
1515

1616
class Test {
1717
void doGet1(InetAddress address)
1818
throws IOException {
1919
String temp = address.getHostName();
2020
File file;
2121
Path path;
22-
22+
2323
// BAD: construct a file path with user input
2424
file = new File(temp);
25-
25+
2626
// BAD: construct a path with user input
2727
path = Paths.get(temp);
28-
28+
2929
// BAD: construct a path with user input
3030
path = FileSystems.getDefault().getPath(temp);
3131

@@ -34,7 +34,7 @@ void doGet1(InetAddress address)
3434
file = new File(temp);
3535
}
3636
}
37-
37+
3838
void doGet2(InetAddress address)
3939
throws IOException {
4040
String temp = address.getHostName();
@@ -44,7 +44,7 @@ void doGet2(InetAddress address)
4444
if(isSafe(temp))
4545
file = new File(temp);
4646
}
47-
47+
4848
void doGet3(InetAddress address)
4949
throws IOException {
5050
String temp = address.getHostName();
@@ -66,7 +66,7 @@ boolean isSafe(String pathSpec) {
6666
return false;
6767
return true;
6868
}
69-
69+
7070
boolean isSortOfSafe(String pathSpec) {
7171
// no file separators
7272
if (pathSpec.contains(File.separator))
@@ -82,4 +82,11 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr
8282
BufferedWriter bw = new BufferedWriter(new FileWriter("dir/"+filename, true));
8383
}
8484
}
85+
86+
void doGet4(InetAddress address)
87+
throws IOException {
88+
String temp = address.getHostName();
89+
// BAD: open a file based on user input, using a MaD-documented API
90+
new LockableFileWriter(temp);
91+
}
8592
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4
1+
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/apache-commons-io-2.6

java/ql/test/stubs/apache-commons-io-2.6/org/apache/commons/io/output/LockableFileWriter.java

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)