Skip to content

Commit 551d86c

Browse files
Java: Define classes for taint propagation methods
1 parent fc4a342 commit 551d86c

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Provides taint tracking information for frameworks.
3+
* When a new framework is added that provides taint tracking steps, it should be imported here.
4+
*/
5+
6+
import semmle.code.java.frameworks.jackson.JacksonSerializability
7+
import semmle.code.java.frameworks.android.Intent
8+
import semmle.code.java.frameworks.android.SQLite
9+
import semmle.code.java.frameworks.Guice
10+
import semmle.code.java.frameworks.Protobuf
11+
import semmle.code.java.frameworks.spring.SpringController
12+
import semmle.code.java.frameworks.spring.SpringHttp

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

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,9 @@ private import semmle.code.java.dataflow.SSA
55
private import semmle.code.java.dataflow.DefUse
66
private import semmle.code.java.security.SecurityTests
77
private import semmle.code.java.security.Validation
8-
private import semmle.code.java.frameworks.android.Intent
9-
private import semmle.code.java.frameworks.android.SQLite
10-
private import semmle.code.java.frameworks.Guice
11-
private import semmle.code.java.frameworks.Protobuf
12-
private import semmle.code.java.frameworks.spring.SpringController
13-
private import semmle.code.java.frameworks.spring.SpringHttp
148
private import semmle.code.java.Maps
159
private import semmle.code.java.dataflow.internal.ContainerFlow
16-
private import semmle.code.java.frameworks.jackson.JacksonSerializability
10+
private import semmle.code.java.dataflow.TaintTrackingFrameworks
1711

1812
/**
1913
* Holds if taint can flow from `src` to `sink` in zero or more
@@ -78,6 +72,34 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
7872
any(AdditionalTaintStep a).step(src, sink)
7973
}
8074

75+
/**
76+
* A method that returns tainted data when one of its inputs (an argument or the qualifier) are tainted.
77+
*
78+
* Extend this class to add additional taint steps through a method that should
79+
* apply to all taint configurations.
80+
*/
81+
abstract class TaintPreservingMethod extends Method {
82+
/**
83+
* Holds if this method returns tainted data when `arg` tainted.
84+
* `arg` is a parameter index, or is -1 to indicate the qualifier.
85+
*/
86+
abstract predicate returnsTaint(int arg);
87+
}
88+
89+
/**
90+
* A method that transfers taint from one of its inputs (an argument or the qualifier) to another.
91+
*
92+
* Extend this class to add additional taint steps through a method that should
93+
* apply to all taint configurations.
94+
*/
95+
abstract class TaintTransferringMethod extends Method {
96+
/**
97+
* Holds if this method writes tainted data to `sink` when `src` is tainted.
98+
* `src` and `sink` are parameter indices, or -1 to indicate the qualifier.
99+
*/
100+
predicate transfersTaint(int src, int sink) { none() }
101+
}
102+
81103
/**
82104
* Holds if `node` should be a sanitizer in all global taint flow configurations
83105
* but not in local taint.
@@ -300,6 +322,8 @@ private predicate taintPreservingQualifierToArgument(Method m, int arg) {
300322
m.getDeclaringType().getASupertype*().hasQualifiedName("java.io", "Reader") and
301323
m.hasName("read") and
302324
arg = 0
325+
or
326+
m.(TaintTransferringMethod).transfersTaint(-1, arg)
303327
}
304328

305329
/** Access to a method that passes taint from the qualifier. */
@@ -412,6 +436,8 @@ private predicate taintPreservingQualifierToMethod(Method m) {
412436
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String[] selectionArgs, String groupBy, String having)
413437
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String groupBy, String having)
414438
m.hasName(["buildQuery", "buildUnionQuery", "buildUnionSubQuery"])
439+
or
440+
m.(TaintPreservingMethod).returnsTaint(-1)
415441
}
416442

417443
private class StringReplaceMethod extends Method {
@@ -429,7 +455,7 @@ private predicate unsafeEscape(MethodAccess ma) {
429455
// Removing `<script>` tags using a string-replace method is
430456
// unsafe if such a tag is embedded inside another one (e.g. `<scr<script>ipt>`).
431457
exists(StringReplaceMethod m | ma.getMethod() = m |
432-
ma.getArgument(0).(StringLiteral).getRepresentedString() = "(<script>)" and
458+
ma.getArgument(0).(StringLiteral).getRepresentedString() = "<script>" and
433459
ma.getArgument(1).(StringLiteral).getRepresentedString() = ""
434460
)
435461
}
@@ -620,6 +646,8 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
620646
// Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
621647
method.hasName("query") and
622648
arg = 0
649+
or
650+
method.(TaintPreservingMethod).returnsTaint(arg)
623651
}
624652

625653
/**
@@ -678,6 +706,8 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
678706
method.hasName("appendColumns") and
679707
input = 1 and
680708
output = 0
709+
or
710+
method.(TaintTransferringMethod).transfersTaint(input, output)
681711
}
682712

683713
/**
@@ -737,6 +767,8 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
737767
// appendWhereStandalone(CharSequence inWhere)
738768
method.hasName(["setProjectionMap", "setTables", "appendWhere", "appendWhereStandalone"]) and
739769
arg = 0
770+
or
771+
method.(TaintTransferringMethod).transfersTaint(arg, -1)
740772
}
741773

742774
/** A comparison or equality test with a constant. */

0 commit comments

Comments
 (0)