Skip to content

Commit d302dc7

Browse files
author
Sauyon Lee
committed
Add tests for org.springframework.util;StringUtils taint models
1 parent d04e302 commit d302dc7

4 files changed

Lines changed: 184 additions & 0 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import org.springframework.util.StringUtils;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Enumeration;
6+
import java.util.Locale;
7+
import java.lang.String;
8+
9+
class Test {
10+
String taint() { return "tainted"; }
11+
12+
String[] taintArray() { return null; }
13+
14+
Locale taintLocale() { return null; }
15+
16+
Collection<String> taintedCollection() { return null; }
17+
18+
Enumeration<String> taintedEnumeration() { return null; }
19+
20+
void sink(Object o) {}
21+
22+
void test() throws Exception {
23+
String[] arr = {};
24+
25+
sink(StringUtils.addStringToArray(arr, taint())); // $hasTaintFlow
26+
27+
sink(StringUtils.addStringToArray(taintArray(), "")); // $hasTaintFlow
28+
29+
String[] strs = arr;
30+
StringUtils.addStringToArray(strs, taint());
31+
sink(strs); // $hasTaintFlow
32+
33+
sink(StringUtils.applyRelativePath("/", taint())); // $hasTaintFlow
34+
sink(StringUtils.applyRelativePath(taint(), "../../test")); // $hasTaintFlow
35+
36+
sink(StringUtils.arrayToCommaDelimitedString(taintArray())); // $hasTaintFlow
37+
38+
sink(StringUtils.arrayToDelimitedString(taintArray(), ":")); // $hasTaintFlow
39+
40+
sink(StringUtils.capitalize(taint())); // $hasTaintFlow
41+
42+
sink(StringUtils.cleanPath(taint())); // $hasTaintFlow
43+
44+
ArrayList<String> coll = new ArrayList<>();
45+
46+
sink(StringUtils.collectionToCommaDelimitedString(taintedCollection())); // $hasTaintFlow
47+
48+
sink(StringUtils.collectionToDelimitedString(taintedCollection(), ":")); // $hasTaintFlow
49+
50+
sink(StringUtils.collectionToDelimitedString(taintedCollection(), ":", "", "")); // $hasTaintFlow
51+
sink(StringUtils.collectionToDelimitedString(coll, ":", taint(), "")); // $hasTaintFlow
52+
sink(StringUtils.collectionToDelimitedString(coll, ":", "", taint())); // $hasTaintFlow
53+
54+
sink(StringUtils.commaDelimitedListToSet(taint())); // $hasTaintFlow
55+
56+
sink(StringUtils.commaDelimitedListToStringArray(taint())); // $hasTaintFlow
57+
58+
sink(StringUtils.concatenateStringArrays(taintArray(), arr)); // $hasTaintFlow
59+
sink(StringUtils.concatenateStringArrays(arr, taintArray())); // $hasTaintFlow
60+
61+
sink(StringUtils.delete(taint(), "")); // $hasTaintFlow
62+
63+
sink(StringUtils.deleteAny(taint(), "")); // $hasTaintFlow
64+
65+
sink(StringUtils.delimitedListToStringArray(taint(), ":")); // $hasTaintFlow
66+
sink(StringUtils.delimitedListToStringArray(taint(), ":", ".")); // $hasTaintFlow
67+
68+
sink(StringUtils.getFilename(taint())); // $hasTaintFlow
69+
70+
sink(StringUtils.getFilenameExtension(taint())); // $hasTaintFlow
71+
72+
sink(StringUtils.mergeStringArrays(taintArray(), arr)); // $hasTaintFlow
73+
sink(StringUtils.mergeStringArrays(arr, taintArray())); // $hasTaintFlow
74+
75+
sink(StringUtils.parseLocale(taint())); // $hasTaintFlow
76+
77+
sink(StringUtils.parseLocaleString(taint())); // $hasTaintFlow
78+
79+
// sink(StringUtils.parseTimezoneString(taint())); // does not exist in spring 5.2.3
80+
81+
sink(StringUtils.quote(taint())); // $hasTaintFlow
82+
83+
sink(StringUtils.quoteIfString(taint())); // $hasTaintFlow
84+
85+
sink(StringUtils.removeDuplicateStrings(taintArray())); // $hasTaintFlow
86+
87+
sink(StringUtils.replace(taint(), "", "")); // $hasTaintFlow
88+
sink(StringUtils.replace("", "", taint())); // $hasTaintFlow
89+
90+
sink(StringUtils.sortStringArray(taintArray())); // $hasTaintFlow
91+
92+
sink(StringUtils.split(taint(), "")); // $hasTaintFlow
93+
94+
sink(StringUtils.splitArrayElementsIntoProperties(taintArray(), "")); // $hasTaintFlow
95+
sink(StringUtils.splitArrayElementsIntoProperties(taintArray(), "", "")); // $hasTaintFlow
96+
97+
sink(StringUtils.stripFilenameExtension(taint())); // $hasTaintFlow
98+
99+
sink(StringUtils.tokenizeToStringArray(taint(), "")); // $hasTaintFlow
100+
sink(StringUtils.tokenizeToStringArray(taint(), "", true, true)); // $hasTaintFlow
101+
102+
sink(StringUtils.toLanguageTag(taintLocale())); // $hasTaintFlow
103+
104+
sink(StringUtils.toStringArray(taintedCollection())); // $hasTaintFlow
105+
106+
sink(StringUtils.toStringArray(taintedEnumeration())); // $hasTaintFlow
107+
108+
sink(StringUtils.trimAllWhitespace(taint())); // $hasTaintFlow
109+
110+
sink(StringUtils.trimArrayElements(taintArray())); // $hasTaintFlow
111+
112+
sink(StringUtils.trimLeadingCharacter(taint(), 'a')); // $hasTaintFlow
113+
114+
sink(StringUtils.trimLeadingWhitespace(taint())); // $hasTaintFlow
115+
116+
sink(StringUtils.trimTrailingCharacter(taint(), 'a')); // $hasTaintFlow
117+
118+
sink(StringUtils.trimTrailingWhitespace(taint())); // $hasTaintFlow
119+
120+
sink(StringUtils.trimWhitespace(taint())); // $hasTaintFlow
121+
122+
sink(StringUtils.uncapitalize(taint())); // $hasTaintFlow
123+
124+
sink(StringUtils.unqualify(taint())); // $hasTaintFlow
125+
126+
sink(StringUtils.unqualify(taint(), '.')); // $hasTaintFlow
127+
128+
sink(StringUtils.uriDecode(taint(), java.nio.charset.StandardCharsets.UTF_8)); // $hasTaintFlow
129+
}
130+
}

java/ql/test/library-tests/frameworks/spring/flow.expected

Whitespace-only changes.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import java
2+
import semmle.code.java.frameworks.spring.Spring
3+
import semmle.code.java.dataflow.TaintTracking
4+
import TestUtilities.InlineExpectationsTest
5+
6+
class TaintFlowConf extends TaintTracking::Configuration {
7+
TaintFlowConf() { this = "qltest:frameworks:spring-taint-flow" }
8+
9+
override predicate isSource(DataFlow::Node n) {
10+
exists(string name | name.matches("taint%") |
11+
n.asExpr().(MethodAccess).getMethod().hasName(name)
12+
)
13+
}
14+
15+
override predicate isSink(DataFlow::Node n) {
16+
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
17+
}
18+
}
19+
20+
class ValueFlowConf extends DataFlow::Configuration {
21+
ValueFlowConf() { this = "qltest:frameworks:spring-value-flow" }
22+
23+
override predicate isSource(DataFlow::Node n) {
24+
n.asExpr().(MethodAccess).getMethod().hasName("taint")
25+
}
26+
27+
override predicate isSink(DataFlow::Node n) {
28+
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
29+
}
30+
}
31+
32+
class HasFlowTest extends InlineExpectationsTest {
33+
HasFlowTest() { this = "HasFlowTest" }
34+
35+
override string getARelevantTag() { result = ["hasTaintFlow", "hasValueFlow"] }
36+
37+
override predicate hasActualResult(Location location, string element, string tag, string value) {
38+
tag = "hasTaintFlow" and
39+
exists(DataFlow::Node src, DataFlow::Node sink, TaintFlowConf conf | conf.hasFlow(src, sink) |
40+
not any(ValueFlowConf vconf).hasFlow(src, sink) and
41+
sink.getLocation() = location and
42+
element = sink.toString() and
43+
value = ""
44+
)
45+
or
46+
tag = "hasValueFlow" and
47+
exists(DataFlow::Node src, DataFlow::Node sink, ValueFlowConf conf | conf.hasFlow(src, sink) |
48+
sink.getLocation() = location and
49+
element = sink.toString() and
50+
value = ""
51+
)
52+
}
53+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.2.3

0 commit comments

Comments
 (0)