Java: tests for android database flow steps

This commit is contained in:
Arthur Baars
2020-09-30 12:11:29 +02:00
parent a13e845127
commit 061c2a754f
3 changed files with 259 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
import java.util.Map;
import java.util.Set;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.CancellationSignal;
public class FlowSteps {
public static <T> T taint() {
return null;
}
private static abstract class MyContentProvider extends ContentProvider {
// Dummy class to test for sub classes
}
private static abstract class MyContentResolver extends ContentResolver {
// Dummy class to test for sub classes
}
private static abstract class MySQLiteQueryBuilder extends SQLiteQueryBuilder {
// Dummy class to test for sub classes
}
public static String[] appendSelectionArgs() {
String[] originalValues = taint();
String[] newValues = taint();
return DatabaseUtils.appendSelectionArgs(originalValues, newValues);
}
public static String concatenateWhere() {
String a = taint();
String b = taint();
return DatabaseUtils.concatenateWhere(a, b);
}
public static String buildQueryString(MySQLiteQueryBuilder target) {
target = taint();
boolean distinct = taint();
String tables = taint();
String[] columns = taint();
String where = taint();
String groupBy = taint();
String having = taint();
String orderBy = taint();
String limit = taint();
return SQLiteQueryBuilder.buildQueryString(distinct, tables, columns, where, groupBy, having, orderBy, limit);
}
public static String buildQuery(MySQLiteQueryBuilder target) {
target = taint();
String[] projectionIn = taint();
String selection = taint();
String groupBy = taint();
String having = taint();
String sortOrder = taint();
String limit = taint();
return target.buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit);
}
public static String buildQuery2(MySQLiteQueryBuilder target) {
target = taint();
String[] projectionIn = taint();
String selection = taint();
String[] selectionArgs = taint();
String groupBy = taint();
String having = taint();
String sortOrder = taint();
String limit = taint();
return target.buildQuery(projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit);
}
public static String buildUnionQuery(MySQLiteQueryBuilder target) {
target = taint();
String[] subQueries = taint();
String sortOrder = taint();
String limit = taint();
return target.buildUnionQuery(subQueries, sortOrder, limit);
}
public static String buildUnionSubQuery2(MySQLiteQueryBuilder target) {
target = taint();
String typeDiscriminatorColumn = taint();
String[] unionColumns = taint();
Set<String> columnsPresentInTable = taint();
int computedColumnsOffset = taint();
String typeDiscriminatorValue = taint();
String selection = taint();
String[] selectionArgs = taint();
String groupBy = taint();
String having = taint();
return target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable,
computedColumnsOffset, typeDiscriminatorValue, selection, selectionArgs, groupBy, having);
}
public static void buildUnionSubQuery3(MySQLiteQueryBuilder target) {
target = taint();
String typeDiscriminatorColumn = taint();
String[] unionColumns = taint();
Set<String> columnsPresentInTable = taint();
int computedColumnsOffset = taint();
String typeDiscriminatorValue = taint();
String selection = taint();
String groupBy = taint();
String having = taint();
target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable, computedColumnsOffset,
typeDiscriminatorValue, selection, groupBy, having);
}
public static Cursor query(MyContentResolver target) {
Uri uri = taint();
String[] projection = taint();
String selection = taint();
String[] selectionArgs = taint();
String sortOrder = taint();
CancellationSignal cancellationSignal = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
}
public static Cursor query(MyContentProvider target) {
Uri uri = taint();
String[] projection = taint();
String selection = taint();
String[] selectionArgs = taint();
String sortOrder = taint();
CancellationSignal cancellationSignal = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
}
public static Cursor query2(MyContentResolver target) {
Uri uri = taint();
String[] projection = taint();
String selection = taint();
String[] selectionArgs = taint();
String sortOrder = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder);
}
public static Cursor query2(MyContentProvider target) {
Uri uri = taint();
String[] projection = taint();
String selection = taint();
String[] selectionArgs = taint();
String sortOrder = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder);
}
public static void appendColumns() {
StringBuilder s = taint();
String[] columns = taint();
SQLiteQueryBuilder.appendColumns(s, columns);
}
public static void setProjectionMap(MySQLiteQueryBuilder target) {
target = taint();
Map<String, String> columnMap = taint();
target.setProjectionMap(columnMap);
}
public static void setTables(MySQLiteQueryBuilder target) {
target = taint();
String inTables = taint();
target.setTables(inTables);
}
public static void appendWhere(MySQLiteQueryBuilder target) {
target = taint();
CharSequence inWhere = taint();
target.appendWhere(inWhere);
}
public static void appendWhereStandalone(MySQLiteQueryBuilder target) {
target = taint();
CharSequence inWhere = taint();
target.appendWhereStandalone(inWhere);
}
}

View File

@@ -0,0 +1,56 @@
| FlowSteps.java:32:44:32:57 | originalValues | FlowSteps.java:32:10:32:69 | appendSelectionArgs(...) |
| FlowSteps.java:32:60:32:68 | newValues | FlowSteps.java:32:10:32:69 | appendSelectionArgs(...) |
| FlowSteps.java:38:41:38:41 | a | FlowSteps.java:38:10:38:45 | concatenateWhere(...) |
| FlowSteps.java:38:44:38:44 | b | FlowSteps.java:38:10:38:45 | concatenateWhere(...) |
| FlowSteps.java:51:56:51:61 | tables | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:64:51:70 | columns | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:73:51:77 | where | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:80:51:86 | groupBy | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:89:51:94 | having | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:97:51:103 | orderBy | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:51:106:51:110 | limit | FlowSteps.java:51:10:51:111 | buildQueryString(...) |
| FlowSteps.java:62:10:62:15 | target | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:28:62:39 | projectionIn | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:42:62:50 | selection | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:53:62:59 | groupBy | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:62:62:67 | having | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:70:62:78 | sortOrder | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:62:81:62:85 | limit | FlowSteps.java:62:10:62:86 | buildQuery(...) |
| FlowSteps.java:74:10:74:15 | target | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:28:74:39 | projectionIn | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:42:74:50 | selection | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:53:74:65 | selectionArgs | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:68:74:74 | groupBy | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:77:74:82 | having | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:85:74:93 | sortOrder | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:74:96:74:100 | limit | FlowSteps.java:74:10:74:101 | buildQuery(...) |
| FlowSteps.java:82:10:82:15 | target | FlowSteps.java:82:10:82:61 | buildUnionQuery(...) |
| FlowSteps.java:82:33:82:42 | subQueries | FlowSteps.java:82:10:82:61 | buildUnionQuery(...) |
| FlowSteps.java:82:45:82:53 | sortOrder | FlowSteps.java:82:10:82:61 | buildUnionQuery(...) |
| FlowSteps.java:82:56:82:60 | limit | FlowSteps.java:82:10:82:61 | buildUnionQuery(...) |
| FlowSteps.java:96:10:96:15 | target | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:96:36:96:58 | typeDiscriminatorColumn | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:96:61:96:72 | unionColumns | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:96:75:96:95 | columnsPresentInTable | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:97:28:97:49 | typeDiscriminatorValue | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:97:52:97:60 | selection | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:97:63:97:75 | selectionArgs | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:97:78:97:84 | groupBy | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:97:87:97:92 | having | FlowSteps.java:96:10:97:93 | buildUnionSubQuery(...) |
| FlowSteps.java:110:3:110:8 | target | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:110:29:110:51 | typeDiscriminatorColumn | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:110:54:110:65 | unionColumns | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:110:68:110:88 | columnsPresentInTable | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:111:5:111:26 | typeDiscriminatorValue | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:111:29:111:37 | selection | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:111:40:111:46 | groupBy | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:111:49:111:54 | having | FlowSteps.java:110:3:111:55 | buildUnionSubQuery(...) |
| FlowSteps.java:121:23:121:25 | uri | FlowSteps.java:121:10:121:95 | query(...) |
| FlowSteps.java:131:23:131:25 | uri | FlowSteps.java:131:10:131:95 | query(...) |
| FlowSteps.java:140:23:140:25 | uri | FlowSteps.java:140:10:140:75 | query(...) |
| FlowSteps.java:149:23:149:25 | uri | FlowSteps.java:149:10:149:75 | query(...) |
| FlowSteps.java:155:39:155:45 | columns | FlowSteps.java:155:36:155:36 | s [post update] |
| FlowSteps.java:161:27:161:35 | columnMap | FlowSteps.java:161:3:161:8 | target [post update] |
| FlowSteps.java:167:20:167:27 | inTables | FlowSteps.java:167:3:167:8 | target [post update] |
| FlowSteps.java:173:22:173:28 | inWhere | FlowSteps.java:173:3:173:8 | target [post update] |
| FlowSteps.java:179:32:179:38 | inWhere | FlowSteps.java:179:3:179:8 | target [post update] |

View File

@@ -0,0 +1,22 @@
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.QueryInjection
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:dataflow:android::flow" }
override predicate isSource(DataFlow::Node source) {
exists(VarAccess va, MethodAccess ma |
source.asExpr() = va and
va.getVariable().getAnAssignedValue() = ma and
ma.getMethod().hasName("taint")
)
}
override predicate isSink(DataFlow::Node sink) { not isSource(sink) }
}
from DataFlow::Node source, DataFlow::Node sink, Conf config
where config.hasFlow(source, sink) and sink.getLocation().getFile().getBaseName() = "FlowSteps.java"
select source, sink