Skip to content

Commit 3416911

Browse files
Java: Refector out StringBuilder and Number taint preserving callables
1 parent eafde05 commit 3416911

File tree

2 files changed

+56
-62
lines changed

2 files changed

+56
-62
lines changed

java/ql/src/semmle/code/java/dataflow/FlowSteps.qll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,59 @@ private class StringTaintPreservingCallable extends TaintPreservingCallable {
6969
this.hasName(["format", "formatted", "join"]) and arg = [0 .. getNumberOfParameters()]
7070
}
7171
}
72+
73+
private class NumberTaintPreservingCallable extends TaintPreservingCallable {
74+
int argument;
75+
76+
NumberTaintPreservingCallable() {
77+
this.getDeclaringType().getASupertype*().hasQualifiedName("java.lang", "Number") and
78+
(
79+
this instanceof Constructor and
80+
argument = 0
81+
or
82+
this.getName().matches(["to%String", "toByteArray", "%Value"]) and
83+
argument = -1
84+
or
85+
this.getName().matches(["parse%", "valueOf%", "to%String", "decode"]) and
86+
argument = 0
87+
)
88+
}
89+
90+
override predicate returnsTaintFrom(int arg) { arg = argument }
91+
}
92+
93+
private class StringBuilderTaintPreservingCallable extends TaintPreservingCallable {
94+
StringBuilderTaintPreservingCallable() {
95+
exists(Class c | c = this.getDeclaringType().getASourceSupertype*() |
96+
(
97+
c.hasQualifiedName("java.lang", "StringBuilder") or
98+
c.hasQualifiedName("java.lang", "StringBuffer") or
99+
c.hasQualifiedName("java.io", "StringWriter")
100+
) and
101+
(
102+
this.hasName(["append", "insert", "replace", "toString"])
103+
or
104+
this.(Constructor).getParameterType(0) instanceof TypeString and
105+
c = this.getDeclaringType()
106+
)
107+
)
108+
}
109+
110+
override predicate returnsTaintFrom(int arg) {
111+
arg = -1
112+
or
113+
this instanceof Constructor and arg = 0
114+
or
115+
this.hasName("append") and arg = 0
116+
or
117+
this.hasName("insert") and arg = 1
118+
or
119+
this.hasName("replace") and arg = 2
120+
}
121+
122+
override predicate transfersTaint(int src, int sink) {
123+
returnsTaintFrom(src) and
124+
sink = -1 and
125+
src != -1
126+
}
127+
}

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

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,6 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
192192
or
193193
s = "java.util.zip.GZIPInputStream" and argi = 0
194194
or
195-
// string builders and buffers
196-
s = "java.lang.StringBuilder" and argi = 0
197-
or
198-
s = "java.lang.StringBuffer" and argi = 0
199-
or
200195
// a cookie with tainted ingredients is tainted
201196
s = "javax.servlet.http.Cookie" and argi = 0
202197
or
@@ -220,11 +215,6 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
220215
s = "java.io.File" and argi = 1
221216
)
222217
or
223-
exists(RefType t | t.getQualifiedName() = "java.lang.Number" |
224-
hasSubtype*(t, sink.getConstructedType())
225-
) and
226-
argi = 0
227-
or
228218
// wrappers constructed by extension
229219
exists(Constructor c, Parameter p, SuperConstructorInvocationStmt sup |
230220
c = sink.getConstructor() and
@@ -310,13 +300,6 @@ private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
310300
private predicate taintPreservingQualifierToMethod(Method m) {
311301
m instanceof CloneMethod
312302
or
313-
exists(Class c | c.getQualifiedName() = "java.lang.Number" | hasSubtype*(c, m.getDeclaringType())) and
314-
(
315-
m.getName().matches("to%String") or
316-
m.getName() = "toByteArray" or
317-
m.getName().matches("%Value")
318-
)
319-
or
320303
m.getDeclaringType().getASupertype*().hasQualifiedName("java.io", "Reader") and
321304
(
322305
m.getName() = "read" and m.getNumberOfParameters() = 0
@@ -340,13 +323,6 @@ private predicate taintPreservingQualifierToMethod(Method m) {
340323
m.getDeclaringType().hasQualifiedName("java.io", "ObjectInputStream") and
341324
m.getName().matches("read%")
342325
or
343-
(
344-
m.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
345-
m.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer") or
346-
m.getDeclaringType().hasQualifiedName("java.io", "StringWriter")
347-
) and
348-
(m.getName() = "toString" or m.getName() = "append")
349-
or
350326
m.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXSource") and
351327
m.hasName("getInputSource")
352328
or
@@ -432,29 +408,6 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
432408
* `arg`th argument is tainted.
433409
*/
434410
private predicate taintPreservingArgumentToMethod(Method method, int arg) {
435-
exists(Class c | c.getQualifiedName() = "java.lang.Number" |
436-
hasSubtype*(c, method.getDeclaringType())
437-
) and
438-
(
439-
method.getName().matches("parse%") and arg = 0
440-
or
441-
method.getName().matches("valueOf%") and arg = 0
442-
or
443-
method.getName().matches("to%String") and arg = 0
444-
)
445-
or
446-
(
447-
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
448-
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer")
449-
) and
450-
(
451-
method.getName() = "append" and arg = 0
452-
or
453-
method.getName() = "insert" and arg = 1
454-
or
455-
method.getName() = "replace" and arg = 2
456-
)
457-
or
458411
(
459412
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Encoder") or
460413
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Decoder") or
@@ -518,10 +471,6 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
518471
method.hasName("sourceToInputSource") and
519472
arg = 0
520473
or
521-
method.getDeclaringType().hasQualifiedName("java.io", "StringWriter") and
522-
method.hasName("append") and
523-
arg = 0
524-
or
525474
method.(TaintPreservingCallable).returnsTaintFrom(arg)
526475
}
527476

@@ -602,17 +551,6 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
602551
)
603552
)
604553
or
605-
exists(Method append |
606-
method.overrides*(append) and
607-
append.hasName("append") and
608-
arg = 0 and
609-
(
610-
append.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
611-
append.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer") or
612-
append.getDeclaringType().hasQualifiedName("java.io", "StringWriter")
613-
)
614-
)
615-
or
616554
method.(TaintPreservingCallable).transfersTaint(arg, -1)
617555
}
618556

0 commit comments

Comments
 (0)