Skip to content

Commit 354a7fd

Browse files
author
Sebastian Bauersfeld
committed
Make taint flow through java.lang.String.(replace|replaceFirst|replaceAll) more permissive.
1 parent 5cf320d commit 354a7fd

File tree

3 files changed

+5
-24
lines changed

3 files changed

+5
-24
lines changed

java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
251251

252252
/** Access to a method that passes taint from the qualifier. */
253253
private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
254-
(taintPreservingQualifierToMethod(sink.getMethod()) or unsafeEscape(sink)) and
254+
taintPreservingQualifierToMethod(sink.getMethod()) and
255255
tracked = sink.getQualifier()
256256
}
257257

@@ -282,28 +282,6 @@ private predicate taintPreservingQualifierToMethod(Method m) {
282282
)
283283
}
284284

285-
private class StringReplaceMethod extends TaintPreservingCallable {
286-
StringReplaceMethod() {
287-
this.getDeclaringType() instanceof TypeString and
288-
(
289-
this.hasName("replace") or
290-
this.hasName("replaceAll") or
291-
this.hasName("replaceFirst")
292-
)
293-
}
294-
295-
override predicate returnsTaintFrom(int arg) { arg = 1 }
296-
}
297-
298-
private predicate unsafeEscape(MethodAccess ma) {
299-
// Removing `<script>` tags using a string-replace method is
300-
// unsafe if such a tag is embedded inside another one (e.g. `<scr<script>ipt>`).
301-
exists(StringReplaceMethod m | ma.getMethod() = m |
302-
ma.getArgument(0).(StringLiteral).getValue() = "(<script>)" and
303-
ma.getArgument(1).(StringLiteral).getValue() = ""
304-
)
305-
}
306-
307285
/** Access to a method that passes taint from an argument. */
308286
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
309287
exists(Method m, int i |

java/ql/lib/semmle/code/java/frameworks/Strings.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ private class StringSummaryCsv extends SummaryModelCsv {
2626
"java.lang;String;false;join;;;Argument[0..1];ReturnValue;taint;manual",
2727
"java.lang;String;false;repeat;(int);;Argument[-1];ReturnValue;taint;manual",
2828
"java.lang;String;false;replace;;;Argument[-1];ReturnValue;taint;manual",
29+
"java.lang;String;false;replace;;;Argument[1];ReturnValue;taint;manual",
2930
"java.lang;String;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual",
31+
"java.lang;String;false;replaceAll;;;Argument[1];ReturnValue;taint;manual",
3032
"java.lang;String;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual",
33+
"java.lang;String;false;replaceFirst;;;Argument[1];ReturnValue;taint;manual",
3134
"java.lang;String;false;split;;;Argument[-1];ReturnValue;taint;manual",
3235
"java.lang;String;false;String;;;Argument[0];Argument[-1];taint;manual",
3336
"java.lang;String;false;strip;;;Argument[-1];ReturnValue;taint;manual",

java/ql/test/library-tests/dataflow/taint/B.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static void maintest() throws java.io.UnsupportedEncodingException, java.
4141
String valueOfSubstring = String.valueOf(complex.toCharArray(), 0, 1);
4242
sink(valueOfSubstring);
4343
// tainted - unsafe escape
44-
String badEscape = constructed.replaceAll("(<script>)", "");
44+
String badEscape = constructed.replaceAll("irrelevant", "irrelevant");
4545
sink(badEscape);
4646
// tainted - tokenized string
4747
String token = new StringTokenizer(badEscape).nextToken();

0 commit comments

Comments
 (0)