Merge pull request #5487 from joefarebrother/sql-sinks

Java: Convert SQL sinks to CSV format
This commit is contained in:
Anders Schack-Mulligen
2021-07-02 10:51:09 +02:00
committed by GitHub
14 changed files with 428 additions and 726 deletions

View File

@@ -95,6 +95,12 @@ private module Frameworks {
private import semmle.code.java.security.LdapInjection private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.XPath private import semmle.code.java.security.XPath
private import semmle.code.java.security.JexlInjection private import semmle.code.java.security.JexlInjection
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Jdbc
private import semmle.code.java.frameworks.SpringJdbc
private import semmle.code.java.frameworks.MyBatis
private import semmle.code.java.frameworks.Hibernate
private import semmle.code.java.frameworks.jOOQ
} }
private predicate sourceModelCsv(string row) { private predicate sourceModelCsv(string row) {

View File

@@ -3,6 +3,7 @@
*/ */
import java import java
import semmle.code.java.dataflow.ExternalFlow
/** The interface `org.hibernate.query.QueryProducer`. */ /** The interface `org.hibernate.query.QueryProducer`. */
class HibernateQueryProducer extends RefType { class HibernateQueryProducer extends RefType {
@@ -21,19 +22,18 @@ class HibernateSession extends RefType {
HibernateSession() { this.hasQualifiedName("org.hibernate", "Session") } HibernateSession() { this.hasQualifiedName("org.hibernate", "Session") }
} }
/** private class SqlSinkCsv extends SinkModelCsv {
* Holds if `m` is a method on `HibernateQueryProducer`, or `HibernateSharedSessionContract` override predicate row(string row) {
* or `HibernateSession`, or a subclass, taking an SQL string as its first argument. row =
*/ [
predicate hibernateSqlMethod(Method m) { //"package;type;overrides;name;signature;ext;spec;kind"
exists(RefType t | "org.hibernate;QueryProducer;true;createQuery;;;Argument[0];sql",
t = m.getDeclaringType().getASourceSupertype*() and "org.hibernate;QueryProducer;true;createNativeQuery;;;Argument[0];sql",
( "org.hibernate;QueryProducer;true;createSQLQuery;;;Argument[0];sql",
t instanceof HibernateQueryProducer or "org.hibernate;SharedSessionContract;true;createQuery;;;Argument[0];sql",
t instanceof HibernateSharedSessionContract or "org.hibernate;SharedSessionContract;true;createSQLQuery;;;Argument[0];sql",
t instanceof HibernateSession "org.hibernate;Session;true;createQuery;;;Argument[0];sql",
) "org.hibernate;Session;true;createSQLQuery;;;Argument[0];sql"
) and ]
m.getParameterType(0) instanceof TypeString and }
m.hasName(["createQuery", "createNativeQuery", "createSQLQuery"])
} }

View File

@@ -3,6 +3,7 @@
*/ */
import semmle.code.java.Type import semmle.code.java.Type
import semmle.code.java.dataflow.ExternalFlow
/*--- Types ---*/ /*--- Types ---*/
/** The interface `java.sql.Connection`. */ /** The interface `java.sql.Connection`. */
@@ -26,62 +27,6 @@ class TypeStatement extends Interface {
} }
/*--- Methods ---*/ /*--- Methods ---*/
/** A method with the name `prepareStatement` declared in `java.sql.Connection`. */
class ConnectionPrepareStatement extends Method {
ConnectionPrepareStatement() {
getDeclaringType() instanceof TypeConnection and
hasName("prepareStatement")
}
}
/** A method with the name `prepareCall` declared in `java.sql.Connection`. */
class ConnectionPrepareCall extends Method {
ConnectionPrepareCall() {
getDeclaringType() instanceof TypeConnection and
hasName("prepareCall")
}
}
/** A method with the name `executeQuery` declared in `java.sql.Statement`. */
class StatementExecuteQuery extends Method {
StatementExecuteQuery() {
getDeclaringType() instanceof TypeStatement and
hasName("executeQuery")
}
}
/** A method with the name `execute` declared in `java.sql.Statement`. */
class MethodStatementExecute extends Method {
MethodStatementExecute() {
getDeclaringType() instanceof TypeStatement and
hasName("execute")
}
}
/** A method with the name `executeUpdate` declared in `java.sql.Statement`. */
class MethodStatementExecuteUpdate extends Method {
MethodStatementExecuteUpdate() {
getDeclaringType() instanceof TypeStatement and
hasName("executeUpdate")
}
}
/** A method with the name `executeLargeUpdate` declared in `java.sql.Statement`. */
class MethodStatementExecuteLargeUpdate extends Method {
MethodStatementExecuteLargeUpdate() {
getDeclaringType() instanceof TypeStatement and
hasName("executeLargeUpdate")
}
}
/** A method with the name `addBatch` declared in `java.sql.Statement`. */
class MethodStatementAddBatch extends Method {
MethodStatementAddBatch() {
getDeclaringType() instanceof TypeStatement and
hasName("addBatch")
}
}
/** A method with the name `getString` declared in `java.sql.ResultSet`. */ /** A method with the name `getString` declared in `java.sql.ResultSet`. */
class ResultSetGetStringMethod extends Method { class ResultSetGetStringMethod extends Method {
ResultSetGetStringMethod() { ResultSetGetStringMethod() {
@@ -92,24 +37,18 @@ class ResultSetGetStringMethod extends Method {
} }
/*--- Other definitions ---*/ /*--- Other definitions ---*/
/** private class SqlSinkCsv extends SinkModelCsv {
* An expression representing SQL code that occurs as an argument of override predicate row(string row) {
* a method in `java.sql.Connection` or `java.sql.Statement`. row =
*/ [
class SqlExpr extends Expr { //"package;type;overrides;name;signature;ext;spec;kind"
SqlExpr() { "java.sql;Connection;true;prepareStatement;;;Argument[0];sql",
exists(MethodAccess call, Method method | "java.sql;Connection;true;prepareCall;;;Argument[0];sql",
call.getArgument(0) = this and "java.sql;Statement;true;execute;;;Argument[0];sql",
method = call.getMethod() and "java.sql;Statement;true;executeQuery;;;Argument[0];sql",
( "java.sql;Statement;true;executeUpdate;;;Argument[0];sql",
method instanceof ConnectionPrepareStatement or "java.sql;Statement;true;executeLargeUpdate;;;Argument[0];sql",
method instanceof ConnectionPrepareCall or "java.sql;Statement;true;addBatch;;;Argument[0];sql"
method instanceof StatementExecuteQuery or ]
method instanceof MethodStatementExecute or
method instanceof MethodStatementExecuteUpdate or
method instanceof MethodStatementExecuteLargeUpdate or
method instanceof MethodStatementAddBatch
)
)
} }
} }

View File

@@ -3,25 +3,24 @@
*/ */
import java import java
import semmle.code.java.dataflow.ExternalFlow
/** The class `org.apache.ibatis.jdbc.SqlRunner`. */ /** The class `org.apache.ibatis.jdbc.SqlRunner`. */
class MyBatisSqlRunner extends RefType { class MyBatisSqlRunner extends RefType {
MyBatisSqlRunner() { this.hasQualifiedName("org.apache.ibatis.jdbc", "SqlRunner") } MyBatisSqlRunner() { this.hasQualifiedName("org.apache.ibatis.jdbc", "SqlRunner") }
} }
/** private class SqlSinkCsv extends SinkModelCsv {
* Holds if `m` is a method on `MyBatisSqlRunner` taking an SQL string as its override predicate row(string row) {
* first argument. row =
*/ [
predicate mybatisSqlMethod(Method m) { //"package;type;overrides;name;signature;ext;spec;kind"
m.getDeclaringType() instanceof MyBatisSqlRunner and "org.apache.ibatis.jdbc;SqlRunner;false;delete;(String,Object[]);;Argument[0];sql",
m.getParameterType(0) instanceof TypeString and "org.apache.ibatis.jdbc;SqlRunner;false;insert;(String,Object[]);;Argument[0];sql",
( "org.apache.ibatis.jdbc;SqlRunner;false;run;(String);;Argument[0];sql",
m.hasName("delete") or "org.apache.ibatis.jdbc;SqlRunner;false;selectAll;(String,Object[]);;Argument[0];sql",
m.hasName("insert") or "org.apache.ibatis.jdbc;SqlRunner;false;selectOne;(String,Object[]);;Argument[0];sql",
m.hasName("run") or "org.apache.ibatis.jdbc;SqlRunner;false;update;(String,Object[]);;Argument[0];sql"
m.hasName("selectAll") or ]
m.hasName("selectOne") or }
m.hasName("update")
)
} }

View File

@@ -3,33 +3,28 @@
*/ */
import java import java
import semmle.code.java.dataflow.ExternalFlow
/** The class `org.springframework.jdbc.core.JdbcTemplate`. */ /** The class `org.springframework.jdbc.core.JdbcTemplate`. */
class JdbcTemplate extends RefType { class JdbcTemplate extends RefType {
JdbcTemplate() { this.hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") } JdbcTemplate() { this.hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") }
} }
/** private class SqlSinkCsv extends SinkModelCsv {
* Holds if `m` is a method on `JdbcTemplate` taking an SQL string as its first override predicate row(string row) {
* argument. row =
*/ [
predicate jdbcSqlMethod(Method m) { //"package;type;overrides;name;signature;ext;spec;kind"
m.getDeclaringType() instanceof JdbcTemplate and "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;(String[]);;Argument[0];sql",
m.getParameterType(0) instanceof TypeString and "org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;;;Argument[0];sql",
( "org.springframework.jdbc.core;JdbcTemplate;false;execute;;;Argument[0];sql",
m.hasName("batchUpdate") or "org.springframework.jdbc.core;JdbcTemplate;false;update;;;Argument[0];sql",
m.hasName("execute") or "org.springframework.jdbc.core;JdbcTemplate;false;query;;;Argument[0];sql",
m.getName().matches("query%") or "org.springframework.jdbc.core;JdbcTemplate;false;queryForList;;;Argument[0];sql",
m.hasName("update") "org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql",
) "org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql",
} "org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql"
/** The method `JdbcTemplate.batchUpdate(String... sql)` */ ]
class BatchUpdateVarargsMethod extends Method {
BatchUpdateVarargsMethod() {
this.getDeclaringType() instanceof JdbcTemplate and
this.hasName("batchUpdate") and
this.getParameterType(0).(Array).getComponentType() instanceof TypeString and
this.getParameter(0).isVarargs()
} }
} }

View File

@@ -1,6 +1,7 @@
import java import java
import Android import Android
import semmle.code.java.dataflow.FlowSteps import semmle.code.java.dataflow.FlowSteps
import semmle.code.java.dataflow.ExternalFlow
/** /**
* The class `android.database.sqlite.SQLiteDatabase`. * The class `android.database.sqlite.SQLiteDatabase`.
@@ -23,209 +24,90 @@ class TypeDatabaseUtils extends Class {
TypeDatabaseUtils() { hasQualifiedName("android.database", "DatabaseUtils") } TypeDatabaseUtils() { hasQualifiedName("android.database", "DatabaseUtils") }
} }
abstract class SQLiteRunner extends Method { private class SQLiteSinkCsv extends SinkModelCsv {
abstract int sqlIndex(); override predicate row(string row) {
} row =
[
private class ExecSqlMethod extends SQLiteRunner { //"package;type;overrides;name;signature;ext;spec;kind"
ExecSqlMethod() { "android.database.sqlite;SQLiteDatabase;false;compileStatement;(String);;Argument[0];sql",
this.getDeclaringType() instanceof TypeSQLiteDatabase and "android.database.sqlite;SQLiteDatabase;false;execSQL;(String);;Argument[0];sql",
// execPerConnectionSQL(String sql, Object[] bindArgs) "android.database.sqlite;SQLiteDatabase;false;execSQL;(String,Object[]);;Argument[0];sql",
// execSQL(String sql) "android.database.sqlite;SQLiteDatabase;false;execPerConnectionSQL;(String,Object[]);;Argument[0];sql",
// execSQL(String sql, Object[] bindArgs) // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
this.hasName(["execPerConnectionSQL", "execSQL"]) // query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// Each String / String[] arg except for selectionArgs is a sink
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[4..7];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[0..2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[4..6];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[5..8];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[5..8];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[4];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[6..9];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[6..9];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[]);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[],CancellationSignal);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;delete;(String,String,String[]);;Argument[0..1];sql",
"android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[2];sql",
"android.database;DatabaseUtils;false;longForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;stringForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;blobFileDescriptorForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;createDbFromSqlStatements;(Context,String,int,String);;Argument[3];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String);;Argument[1];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String);;Argument[1..2];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String,String[]);;Argument[1..2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;insert;(SQLiteDatabase,ContentValues);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[2];sql",
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal)
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[4..6];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[4..7];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4..7];sql",
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Argument[1];sql",
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[2];sql",
"android.content;ContentResolver;true;delete;(Uri,String,String[]);;Argument[1];sql",
"android.content;ContentResolver;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[2];sql"
]
} }
override int sqlIndex() { result = 0 }
}
private class QueryMethod extends SQLiteRunner {
QueryMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
this.hasName(["query", "queryWithFactory"])
}
override int sqlIndex() {
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
this.getName() = "query" and
(
if this.getParameter(0).getType() instanceof TypeString
then result = [0, 1, 2, 4, 5, 6, 7]
else result = [1, 2, 3, 5, 6, 7, 8]
)
or
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
this.getName() = "queryWithFactory" and result = [2, 3, 4, 6, 7, 8, 9]
}
}
private class RawQueryMethod extends SQLiteRunner {
RawQueryMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
this.hasName(["rawQuery", "rawQueryWithFactory"])
}
override int sqlIndex() {
// rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal)
// rawQuery(String sql, String[] selectionArgs)
this.getName() = "rawQuery" and result = 0
or
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal)
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable)
this.getName() = "rawQueryWithFactory" and result = 1
}
}
private class CompileStatementMethod extends SQLiteRunner {
CompileStatementMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// compileStatement(String sql)
this.hasName("compileStatement")
}
override int sqlIndex() { result = 0 }
}
private class DeleteMethod extends SQLiteRunner {
DeleteMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// delete(String table, String whereClause, String[] whereArgs)
this.hasName("delete")
}
override int sqlIndex() { result = 1 }
}
private class UpdateMethod extends SQLiteRunner {
UpdateMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// update(String table, ContentValues values, String whereClause, String[] whereArgs)
// updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)
this.hasName(["update", "updateWithOnConflict"])
}
override int sqlIndex() { result = 2 }
}
private class ForQueryMethod extends SQLiteRunner {
ForQueryMethod() {
// (blobFileDescriptor|long|string)ForQuery(SQLiteDatabase db, String query, String[] selectionArgs)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName(["blobFileDescriptorForQuery", "longForQuery", "stringForQuery"]) and
this.getNumberOfParameters() = 3
}
override int sqlIndex() { result = 1 }
}
private class CreateDbFromSqlStatementsMethod extends SQLiteRunner {
CreateDbFromSqlStatementsMethod() {
// createDbFromSqlStatements(Context context, String dbName, int dbVersion, String sqlStatements)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName("createDbFromSqlStatements")
}
override int sqlIndex() { result = 3 }
}
private class QueryNumEntriesMethod extends SQLiteRunner {
QueryNumEntriesMethod() {
// queryNumEntries(SQLiteDatabase db, String table, String selection)
// queryNumEntries(SQLiteDatabase db, String table, String selection, String[] selectionArgs)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName("queryNumEntries")
}
override int sqlIndex() { result = 2 }
}
private class QueryBuilderDeleteMethod extends SQLiteRunner {
QueryBuilderDeleteMethod() {
// delete(SQLiteDatabase db, String selection, String[] selectionArgs)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("delete")
}
override int sqlIndex() { result = [-1, 1] }
}
private class QueryBuilderInsertMethod extends SQLiteRunner {
QueryBuilderInsertMethod() {
// insert(SQLiteDatabase db, ContentValues values)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("insert")
}
override int sqlIndex() { result = -1 }
}
private class QueryBuilderQueryMethod extends SQLiteRunner {
QueryBuilderQueryMethod() {
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("query")
}
override int sqlIndex() { result = [-1, 2, 4, 5, 6, 7] }
}
private class QueryBuilderUpdateMethod extends SQLiteRunner {
QueryBuilderUpdateMethod() {
// update(SQLiteDatabase db, ContentValues values, String selection, String[] selectionArgs)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("update")
}
override int sqlIndex() { result = [-1, 2] }
}
private class ContentProviderDeleteMethod extends SQLiteRunner {
ContentProviderDeleteMethod() {
// delete(Uri uri, String selection, String[] selectionArgs)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("delete") and
this.getNumberOfParameters() = 3
}
override int sqlIndex() { result = 1 }
}
private class ContentProviderQueryMethod extends SQLiteRunner {
ContentProviderQueryMethod() {
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("query") and
this.getNumberOfParameters() = [5, 6]
}
override int sqlIndex() { result = 2 }
}
private class ContentProviderUpdateMethod extends SQLiteRunner {
ContentProviderUpdateMethod() {
// update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("update") and
this.getNumberOfParameters() = 4
}
override int sqlIndex() { result = 2 }
} }
private class QueryBuilderBuildMethod extends TaintPreservingCallable { private class QueryBuilderBuildMethod extends TaintPreservingCallable {

View File

@@ -3,6 +3,7 @@
*/ */
import java import java
import semmle.code.java.dataflow.ExternalFlow
/** /**
* Methods annotated with this allow for generation of "plain SQL" * Methods annotated with this allow for generation of "plain SQL"
@@ -21,3 +22,13 @@ predicate jOOQSqlMethod(Method m) {
m.getAnAnnotation() instanceof PlainSQLType and m.getAnAnnotation() instanceof PlainSQLType and
m.getParameterType(0) instanceof TypeString m.getParameterType(0) instanceof TypeString
} }
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"org.jooq;PlainSQL;false;;;Annotated;Argument[0];sql"
]
}
}

View File

@@ -2,13 +2,8 @@
import java import java
import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.DataFlow
import semmle.code.java.frameworks.Jdbc
import semmle.code.java.frameworks.jOOQ
import semmle.code.java.frameworks.android.SQLite
import semmle.code.java.frameworks.javaee.Persistence import semmle.code.java.frameworks.javaee.Persistence
import semmle.code.java.frameworks.SpringJdbc import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.frameworks.MyBatis
import semmle.code.java.frameworks.Hibernate
/** A sink for database query language injection vulnerabilities. */ /** A sink for database query language injection vulnerabilities. */
abstract class QueryInjectionSink extends DataFlow::Node { } abstract class QueryInjectionSink extends DataFlow::Node { }
@@ -29,28 +24,7 @@ class AdditionalQueryInjectionTaintStep extends Unit {
/** A sink for SQL injection vulnerabilities. */ /** A sink for SQL injection vulnerabilities. */
private class SqlInjectionSink extends QueryInjectionSink { private class SqlInjectionSink extends QueryInjectionSink {
SqlInjectionSink() { SqlInjectionSink() { sinkNode(this, "sql") }
this.asExpr() instanceof SqlExpr
or
exists(MethodAccess ma, Method m, int index |
ma.getMethod() = m and
if index = -1
then this.asExpr() = ma.getQualifier()
else ma.getArgument(index) = this.asExpr()
|
index = m.(SQLiteRunner).sqlIndex()
or
m instanceof BatchUpdateVarargsMethod
or
index = 0 and jdbcSqlMethod(m)
or
index = 0 and mybatisSqlMethod(m)
or
index = 0 and hibernateSqlMethod(m)
or
index = 0 and jOOQSqlMethod(m)
)
}
} }
/** A sink for Java Persistence Query Language injection vulnerabilities. */ /** A sink for Java Persistence Query Language injection vulnerabilities. */

View File

@@ -27,155 +27,160 @@ public class FlowSteps {
} }
public static String[] appendSelectionArgs() { public static String[] appendSelectionArgs() {
String[] originalValues = taint(); String[] originalValues = {taint()}; // $ MISSING: taintReachesReturn
String[] newValues = taint(); String[] newValues = {taint()}; // $ MISSING: taintReachesReturn
return DatabaseUtils.appendSelectionArgs(originalValues, newValues); return DatabaseUtils.appendSelectionArgs(originalValues, newValues);
} }
public static String concatenateWhere() { public static String concatenateWhere() {
String a = taint(); String a = taint(); // $taintReachesReturn
String b = taint(); String b = taint(); // $taintReachesReturn
return DatabaseUtils.concatenateWhere(a, b); return DatabaseUtils.concatenateWhere(a, b);
} }
public static String buildQueryString(MySQLiteQueryBuilder target) { public static String buildQueryString(MySQLiteQueryBuilder target) {
target = taint(); target = taint();
boolean distinct = taint(); boolean distinct = taint();
String tables = taint(); String tables = taint(); // $taintReachesReturn
String[] columns = taint(); String[] columns = {taint()}; // $ MISSING: taintReachesReturn
String where = taint(); String where = taint(); // $taintReachesReturn
String groupBy = taint(); String groupBy = taint(); // $taintReachesReturn
String having = taint(); String having = taint(); // $taintReachesReturn
String orderBy = taint(); String orderBy = taint(); // $taintReachesReturn
String limit = taint(); String limit = taint(); // $taintReachesReturn
return SQLiteQueryBuilder.buildQueryString(distinct, tables, columns, where, groupBy, having, orderBy, limit); return SQLiteQueryBuilder.buildQueryString(distinct, tables, columns, where, groupBy, having, orderBy, limit);
} }
public static String buildQuery(MySQLiteQueryBuilder target) { public static String buildQuery(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String[] projectionIn = taint(); String[] projectionIn = {taint()};// $ MISSING: taintReachesReturn
String selection = taint(); String selection = taint(); // $taintReachesReturn
String groupBy = taint(); String groupBy = taint(); // $taintReachesReturn
String having = taint(); String having = taint(); // $taintReachesReturn
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesReturn
String limit = taint(); String limit = taint(); // $taintReachesReturn
return target.buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit); return target.buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit);
} }
public static String buildQuery2(MySQLiteQueryBuilder target) { public static String buildQuery2(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String[] projectionIn = taint(); String[] projectionIn = {taint()}; // $ MISSING: taintReachesReturn
String selection = taint(); String selection = taint(); // $taintReachesReturn
String[] selectionArgs = taint(); String[] selectionArgs = {taint()}; // $ MISSING: taintReachesReturn
String groupBy = taint(); String groupBy = taint(); // $taintReachesReturn
String having = taint(); String having = taint(); // $taintReachesReturn
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesReturn
String limit = taint(); String limit = taint(); // $taintReachesReturn
return target.buildQuery(projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit); return target.buildQuery(projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit);
} }
public static String buildUnionQuery(MySQLiteQueryBuilder target) { public static String buildUnionQuery(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String[] subQueries = taint(); String[] subQueries = {taint()}; // $ MISSING: taintReachesReturn
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesReturn
String limit = taint(); String limit = taint(); // $taintReachesReturn
return target.buildUnionQuery(subQueries, sortOrder, limit); return target.buildUnionQuery(subQueries, sortOrder, limit);
} }
public static String buildUnionSubQuery2(MySQLiteQueryBuilder target) { public static String buildUnionSubQuery2(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String typeDiscriminatorColumn = taint(); String typeDiscriminatorColumn = taint(); // $taintReachesReturn
String[] unionColumns = taint(); String[] unionColumns = {taint()}; // $ MISSING: taintReachesReturn
Set<String> columnsPresentInTable = taint(); Set<String> columnsPresentInTable = taint(); // $taintReachesReturn
int computedColumnsOffset = taint(); int computedColumnsOffset = taint();
String typeDiscriminatorValue = taint(); String typeDiscriminatorValue = taint(); // $taintReachesReturn
String selection = taint(); String selection = taint(); // $taintReachesReturn
String[] selectionArgs = taint(); String[] selectionArgs = {taint()}; // $ MISSING: taintReachesReturn
String groupBy = taint(); String groupBy = taint(); // $taintReachesReturn
String having = taint(); String having = taint(); // $taintReachesReturn
return target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable, return target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable,
computedColumnsOffset, typeDiscriminatorValue, selection, selectionArgs, groupBy, having); computedColumnsOffset, typeDiscriminatorValue, selection, selectionArgs, groupBy, having);
} }
public static void buildUnionSubQuery3(MySQLiteQueryBuilder target) { public static String buildUnionSubQuery3(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String typeDiscriminatorColumn = taint(); String typeDiscriminatorColumn = taint(); // $taintReachesReturn
String[] unionColumns = taint(); String[] unionColumns = {taint()}; // $ MISSING: taintReachesReturn
Set<String> columnsPresentInTable = taint(); Set<String> columnsPresentInTable = taint(); // $taintReachesReturn
int computedColumnsOffset = taint(); int computedColumnsOffset = taint();
String typeDiscriminatorValue = taint(); String typeDiscriminatorValue = taint(); // $taintReachesReturn
String selection = taint(); String selection = taint(); // $taintReachesReturn
String groupBy = taint(); String groupBy = taint(); // $taintReachesReturn
String having = taint(); String having = taint(); // $taintReachesReturn
target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable, computedColumnsOffset, return target.buildUnionSubQuery(typeDiscriminatorColumn, unionColumns, columnsPresentInTable, computedColumnsOffset,
typeDiscriminatorValue, selection, groupBy, having); typeDiscriminatorValue, selection, groupBy, having);
} }
public static Cursor query(MyContentResolver target) { public static Cursor query(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint(); // $taintReachesReturn
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
} }
public static Cursor query(MyContentProvider target) { public static Cursor query(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint(); // $taintReachesReturn
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); return target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
} }
public static Cursor query2(MyContentResolver target) { public static Cursor query2(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint(); // $taintReachesReturn
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder); return target.query(uri, projection, selection, selectionArgs, sortOrder);
} }
public static Cursor query2(MyContentProvider target) { public static Cursor query2(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint(); // $taintReachesReturn
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
return target.query(uri, projection, selection, selectionArgs, sortOrder); return target.query(uri, projection, selection, selectionArgs, sortOrder);
} }
public static void appendColumns() { public static StringBuilder appendColumns() {
StringBuilder s = taint(); StringBuilder s = taint(); // $taintReachesReturn
String[] columns = taint(); String[] columns = {taint()}; // $ MISSING: taintReachesReturn
SQLiteQueryBuilder.appendColumns(s, columns); SQLiteQueryBuilder.appendColumns(s, columns);
return s;
} }
public static void setProjectionMap(MySQLiteQueryBuilder target) { public static SQLiteQueryBuilder setProjectionMap(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
Map<String, String> columnMap = taint(); Map<String, String> columnMap = taint(); // $taintReachesReturn
target.setProjectionMap(columnMap); target.setProjectionMap(columnMap);
return target;
} }
public static void setTables(MySQLiteQueryBuilder target) { public static SQLiteQueryBuilder setTables(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
String inTables = taint(); String inTables = taint(); // $taintReachesReturn
target.setTables(inTables); target.setTables(inTables);
return target;
} }
public static void appendWhere(MySQLiteQueryBuilder target) { public static SQLiteQueryBuilder appendWhere(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
CharSequence inWhere = taint(); CharSequence inWhere = taint(); // $taintReachesReturn
target.appendWhere(inWhere); target.appendWhere(inWhere);
return target;
} }
public static void appendWhereStandalone(MySQLiteQueryBuilder target) { public static SQLiteQueryBuilder appendWhereStandalone(MySQLiteQueryBuilder target) {
target = taint(); target = taint(); // $taintReachesReturn
CharSequence inWhere = taint(); CharSequence inWhere = taint(); // $taintReachesReturn
target.appendWhereStandalone(inWhere); target.appendWhereStandalone(inWhere);
return target;
} }
} }

View File

@@ -25,58 +25,58 @@ public class Sinks {
} }
public static void compileStatement(SQLiteDatabase target) { public static void compileStatement(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
target.compileStatement(sql); target.compileStatement(sql);
} }
public static void delete1(MySQLiteQueryBuilder target) { public static void delete1(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.delete(db, selection, selectionArgs); target.delete(db, selection, selectionArgs);
} }
public static void delete(SQLiteDatabase target) { public static void delete(SQLiteDatabase target) {
String table = taint(); String table = taint(); // $taintReachesSink
String whereClause = taint(); String whereClause = taint(); // $taintReachesSink
String[] whereArgs = taint(); String[] whereArgs = {taint()};
target.delete(table, whereClause, whereArgs); target.delete(table, whereClause, whereArgs);
} }
public static void delete(MyContentResolver target) { public static void delete(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.delete(uri, selection, selectionArgs); target.delete(uri, selection, selectionArgs);
} }
public static void delete(MyContentProvider target) { public static void delete(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.delete(uri, selection, selectionArgs); target.delete(uri, selection, selectionArgs);
} }
public static void execPerConnectionSQL(SQLiteDatabase target) { public static void execPerConnectionSQL(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
Object[] bindArgs = taint(); Object[] bindArgs = {taint()};
target.execPerConnectionSQL(sql, bindArgs); target.execPerConnectionSQL(sql, bindArgs);
} }
public static void execSQL(SQLiteDatabase target) { public static void execSQL(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
target.execSQL(sql); target.execSQL(sql);
} }
public static void execSQL2(SQLiteDatabase target) { public static void execSQL2(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
Object[] bindArgs = taint(); Object[] bindArgs = {taint()};
target.execSQL(sql, bindArgs); target.execSQL(sql, bindArgs);
} }
public static void insert(MySQLiteQueryBuilder target) { public static void insert(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
ContentValues values = taint(); ContentValues values = taint();
target.insert(db, values); target.insert(db, values);
@@ -84,108 +84,108 @@ public class Sinks {
public static void query(SQLiteDatabase target) { public static void query(SQLiteDatabase target) {
boolean distinct = taint(); boolean distinct = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
target.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit); target.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
} }
public static void query2(SQLiteDatabase target) { public static void query2(SQLiteDatabase target) {
boolean distinct = taint(); boolean distinct = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, target.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit,
cancellationSignal); cancellationSignal);
} }
public static void query3(SQLiteDatabase target) { public static void query3(SQLiteDatabase target) {
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
target.query(table, columns, selection, selectionArgs, groupBy, having, orderBy); target.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
} }
public static void query4(SQLiteDatabase target) { public static void query4(SQLiteDatabase target) {
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
target.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit); target.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
} }
public static void query(MySQLiteQueryBuilder target) { public static void query(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String[] projectionIn = taint(); String[] projectionIn = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesSink
target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder); target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder);
} }
public static void query2(MySQLiteQueryBuilder target) { public static void query2(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String[] projectionIn = taint(); String[] projectionIn = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit); target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit);
} }
public static void query3(MySQLiteQueryBuilder target) { public static void query3(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String[] projectionIn = taint(); String[] projectionIn = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String sortOrder = taint(); String sortOrder = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit, cancellationSignal); target.query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder, limit, cancellationSignal);
} }
public static void query3(MyContentProvider target) { public static void query3(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint();
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
target.query(uri, projection, selection, selectionArgs, sortOrder); target.query(uri, projection, selection, selectionArgs, sortOrder);
} }
public static void query(MyContentProvider target) { public static void query(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint();
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
@@ -193,18 +193,18 @@ public class Sinks {
public static void query3(MyContentResolver target) { public static void query3(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint();
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
target.query(uri, projection, selection, selectionArgs, sortOrder); target.query(uri, projection, selection, selectionArgs, sortOrder);
} }
public static void query(MyContentResolver target) { public static void query(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint();
String[] projection = taint(); String[] projection = {taint()};
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String sortOrder = taint(); String sortOrder = taint();
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal); target.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
@@ -213,14 +213,14 @@ public class Sinks {
public static void queryWithFactory(SQLiteDatabase target) { public static void queryWithFactory(SQLiteDatabase target) {
SQLiteDatabase.CursorFactory cursorFactory = taint(); SQLiteDatabase.CursorFactory cursorFactory = taint();
boolean distinct = taint(); boolean distinct = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
target.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having, target.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having,
orderBy, limit); orderBy, limit);
} }
@@ -228,103 +228,103 @@ public class Sinks {
public static void queryWithFactory2(SQLiteDatabase target) { public static void queryWithFactory2(SQLiteDatabase target) {
SQLiteDatabase.CursorFactory cursorFactory = taint(); SQLiteDatabase.CursorFactory cursorFactory = taint();
boolean distinct = taint(); boolean distinct = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String[] columns = taint(); String[] columns = {taint()}; // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String groupBy = taint(); String groupBy = taint(); // $taintReachesSink
String having = taint(); String having = taint(); // $taintReachesSink
String orderBy = taint(); String orderBy = taint(); // $taintReachesSink
String limit = taint(); String limit = taint(); // $taintReachesSink
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having, target.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having,
orderBy, limit, cancellationSignal); orderBy, limit, cancellationSignal);
} }
public static void rawQuery(SQLiteDatabase target) { public static void rawQuery(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.rawQuery(sql, selectionArgs); target.rawQuery(sql, selectionArgs);
} }
public static void rawQuery2(SQLiteDatabase target) { public static void rawQuery2(SQLiteDatabase target) {
String sql = taint(); String sql = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.rawQuery(sql, selectionArgs, cancellationSignal); target.rawQuery(sql, selectionArgs, cancellationSignal);
} }
public static void rawQueryWithFactory(SQLiteDatabase target) { public static void rawQueryWithFactory(SQLiteDatabase target) {
SQLiteDatabase.CursorFactory cursorFactory = taint(); SQLiteDatabase.CursorFactory cursorFactory = taint();
String sql = taint(); String sql = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String editTable = taint(); String editTable = taint();
target.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable); target.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable);
} }
public static void rawQueryWithFactory2(SQLiteDatabase target) { public static void rawQueryWithFactory2(SQLiteDatabase target) {
SQLiteDatabase.CursorFactory cursorFactory = taint(); SQLiteDatabase.CursorFactory cursorFactory = taint();
String sql = taint(); String sql = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
String editTable = taint(); String editTable = taint();
CancellationSignal cancellationSignal = taint(); CancellationSignal cancellationSignal = taint();
target.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, cancellationSignal); target.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, cancellationSignal);
} }
public static void update(MySQLiteQueryBuilder target) { public static void update(MySQLiteQueryBuilder target) {
target = taint();; target = taint(); // $taintReachesSink
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
ContentValues values = taint(); ContentValues values = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.update(db, values, selection, selectionArgs); target.update(db, values, selection, selectionArgs);
} }
public static void update(SQLiteDatabase target) { public static void update(SQLiteDatabase target) {
String table = taint(); String table = taint(); // $taintReachesSink
ContentValues values = taint(); ContentValues values = taint();
String whereClause = taint(); String whereClause = taint(); // $taintReachesSink
String[] whereArgs = taint(); String[] whereArgs = {taint()};
target.update(table, values, whereClause, whereArgs); target.update(table, values, whereClause, whereArgs);
} }
public static void update(MyContentResolver target) { public static void update(MyContentResolver target) {
Uri uri = taint(); Uri uri = taint();
ContentValues values = taint(); ContentValues values = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.update(uri, values, selection, selectionArgs); target.update(uri, values, selection, selectionArgs);
} }
public static void update(MyContentProvider target) { public static void update(MyContentProvider target) {
Uri uri = taint(); Uri uri = taint();
ContentValues values = taint(); ContentValues values = taint();
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
target.update(uri, values, selection, selectionArgs); target.update(uri, values, selection, selectionArgs);
} }
public static void updateWithOnConflict(SQLiteDatabase target) { public static void updateWithOnConflict(SQLiteDatabase target) {
String table = taint(); String table = taint(); // $taintReachesSink
ContentValues values = taint(); ContentValues values = taint();
String whereClause = taint(); String whereClause = taint(); // $taintReachesSink
String[] whereArgs = taint(); String[] whereArgs = {taint()};
int conflictAlgorithm = taint(); int conflictAlgorithm = taint();
target.updateWithOnConflict(table, values, whereClause, whereArgs, conflictAlgorithm); target.updateWithOnConflict(table, values, whereClause, whereArgs, conflictAlgorithm);
} }
public static void queryNumEntries() { public static void queryNumEntries() {
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
DatabaseUtils.queryNumEntries(db, table, selection); DatabaseUtils.queryNumEntries(db, table, selection);
} }
public static void queryNumEntries2() { public static void queryNumEntries2() {
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String table = taint(); String table = taint(); // $taintReachesSink
String selection = taint(); String selection = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
DatabaseUtils.queryNumEntries(db, table, selection, selectionArgs); DatabaseUtils.queryNumEntries(db, table, selection, selectionArgs);
} }
@@ -332,28 +332,28 @@ public class Sinks {
Context context = taint(); Context context = taint();
String dbName = taint(); String dbName = taint();
int dbVersion = taint(); int dbVersion = taint();
String sqlStatements = taint(); String sqlStatements = taint(); // $taintReachesSink
DatabaseUtils.createDbFromSqlStatements(context, dbName, dbVersion, sqlStatements); DatabaseUtils.createDbFromSqlStatements(context, dbName, dbVersion, sqlStatements);
} }
public static void blobFileDescriptorForQuery() { public static void blobFileDescriptorForQuery() {
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String query = taint(); String query = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
DatabaseUtils.blobFileDescriptorForQuery(db, query, selectionArgs); DatabaseUtils.blobFileDescriptorForQuery(db, query, selectionArgs);
} }
public static void longForQuery() { public static void longForQuery() {
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String query = taint(); String query = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
DatabaseUtils.longForQuery(db, query, selectionArgs); DatabaseUtils.longForQuery(db, query, selectionArgs);
} }
public static void stringForQuery() { public static void stringForQuery() {
SQLiteDatabase db = taint(); SQLiteDatabase db = taint();
String query = taint(); String query = taint(); // $taintReachesSink
String[] selectionArgs = taint(); String[] selectionArgs = {taint()};
DatabaseUtils.stringForQuery(db, query, selectionArgs); DatabaseUtils.stringForQuery(db, query, selectionArgs);
} }
} }

View File

@@ -1,56 +0,0 @@
| 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

@@ -2,21 +2,30 @@ import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.QueryInjection import semmle.code.java.security.QueryInjection
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration { class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:dataflow:android::flow" } Conf() { this = "qltest:dataflow:android::flow" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
exists(VarAccess va, MethodAccess ma | source.asExpr().(MethodAccess).getMethod().hasName("taint")
source.asExpr() = va and
va.getVariable().getAnAssignedValue() = ma and
ma.getMethod().hasName("taint")
)
} }
override predicate isSink(DataFlow::Node sink) { not isSource(sink) } override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ReturnStmt r).getResult() }
} }
from DataFlow::Node source, DataFlow::Node sink, Conf config class FlowStepTest extends InlineExpectationsTest {
where config.hasFlow(source, sink) and sink.getLocation().getFile().getBaseName() = "FlowSteps.java" FlowStepTest() { this = "FlowStepTest" }
select source, sink
override string getARelevantTag() { result = "taintReachesReturn" }
override predicate hasActualResult(Location l, string element, string tag, string value) {
tag = "taintReachesReturn" and
value = "" and
exists(Conf conf, DataFlow::Node source, DataFlow::Node sink |
conf.hasFlow(source, sink) and
l = source.getLocation() and
element = source.toString()
)
}
}

View File

@@ -1,88 +0,0 @@
| Sinks.java:29:27:29:29 | sql |
| Sinks.java:37:3:37:8 | target |
| Sinks.java:37:21:37:29 | selection |
| Sinks.java:44:24:44:34 | whereClause |
| Sinks.java:51:22:51:30 | selection |
| Sinks.java:58:22:58:30 | selection |
| Sinks.java:64:31:64:33 | sql |
| Sinks.java:69:18:69:20 | sql |
| Sinks.java:75:18:75:20 | sql |
| Sinks.java:82:3:82:8 | target |
| Sinks.java:95:26:95:30 | table |
| Sinks.java:95:33:95:39 | columns |
| Sinks.java:95:42:95:50 | selection |
| Sinks.java:95:68:95:74 | groupBy |
| Sinks.java:95:77:95:82 | having |
| Sinks.java:95:85:95:91 | orderBy |
| Sinks.java:95:94:95:98 | limit |
| Sinks.java:109:26:109:30 | table |
| Sinks.java:109:33:109:39 | columns |
| Sinks.java:109:42:109:50 | selection |
| Sinks.java:109:68:109:74 | groupBy |
| Sinks.java:109:77:109:82 | having |
| Sinks.java:109:85:109:91 | orderBy |
| Sinks.java:109:94:109:98 | limit |
| Sinks.java:121:16:121:20 | table |
| Sinks.java:121:23:121:29 | columns |
| Sinks.java:121:32:121:40 | selection |
| Sinks.java:121:58:121:64 | groupBy |
| Sinks.java:121:67:121:72 | having |
| Sinks.java:121:75:121:81 | orderBy |
| Sinks.java:133:16:133:20 | table |
| Sinks.java:133:23:133:29 | columns |
| Sinks.java:133:32:133:40 | selection |
| Sinks.java:133:58:133:64 | groupBy |
| Sinks.java:133:67:133:72 | having |
| Sinks.java:133:75:133:81 | orderBy |
| Sinks.java:133:84:133:88 | limit |
| Sinks.java:145:3:145:8 | target |
| Sinks.java:145:34:145:42 | selection |
| Sinks.java:145:60:145:66 | groupBy |
| Sinks.java:145:69:145:74 | having |
| Sinks.java:145:77:145:85 | sortOrder |
| Sinks.java:158:3:158:8 | target |
| Sinks.java:158:34:158:42 | selection |
| Sinks.java:158:60:158:66 | groupBy |
| Sinks.java:158:69:158:74 | having |
| Sinks.java:158:77:158:85 | sortOrder |
| Sinks.java:158:88:158:92 | limit |
| Sinks.java:172:3:172:8 | target |
| Sinks.java:172:34:172:42 | selection |
| Sinks.java:172:60:172:66 | groupBy |
| Sinks.java:172:69:172:74 | having |
| Sinks.java:172:77:172:85 | sortOrder |
| Sinks.java:172:88:172:92 | limit |
| Sinks.java:181:33:181:41 | selection |
| Sinks.java:191:33:191:41 | selection |
| Sinks.java:200:33:200:41 | selection |
| Sinks.java:210:33:210:41 | selection |
| Sinks.java:224:52:224:56 | table |
| Sinks.java:224:59:224:65 | columns |
| Sinks.java:224:68:224:76 | selection |
| Sinks.java:224:94:224:100 | groupBy |
| Sinks.java:224:103:224:108 | having |
| Sinks.java:225:5:225:11 | orderBy |
| Sinks.java:225:14:225:18 | limit |
| Sinks.java:240:52:240:56 | table |
| Sinks.java:240:59:240:65 | columns |
| Sinks.java:240:68:240:76 | selection |
| Sinks.java:240:94:240:100 | groupBy |
| Sinks.java:240:103:240:108 | having |
| Sinks.java:241:5:241:11 | orderBy |
| Sinks.java:241:14:241:18 | limit |
| Sinks.java:247:19:247:21 | sql |
| Sinks.java:254:19:254:21 | sql |
| Sinks.java:262:45:262:47 | sql |
| Sinks.java:271:45:271:47 | sql |
| Sinks.java:280:3:280:8 | target |
| Sinks.java:280:29:280:37 | selection |
| Sinks.java:288:32:288:42 | whereClause |
| Sinks.java:296:30:296:38 | selection |
| Sinks.java:304:30:304:38 | selection |
| Sinks.java:313:46:313:56 | whereClause |
| Sinks.java:320:44:320:52 | selection |
| Sinks.java:328:44:328:52 | selection |
| Sinks.java:336:71:336:83 | sqlStatements |
| Sinks.java:343:48:343:52 | query |
| Sinks.java:350:34:350:38 | query |
| Sinks.java:357:36:357:40 | query |

View File

@@ -1,5 +1,31 @@
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.QueryInjection import semmle.code.java.security.QueryInjection
import TestUtilities.InlineExpectationsTest
from QueryInjectionSink sink class Conf extends TaintTracking::Configuration {
where sink.getLocation().getFile().getBaseName() = "Sinks.java" Conf() { this = "qltest:dataflow:android::flow" }
select sink
override predicate isSource(DataFlow::Node source) {
source.asExpr().(MethodAccess).getMethod().hasName("taint")
}
override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
}
class SinkTest extends InlineExpectationsTest {
SinkTest() { this = "SinkTest" }
override string getARelevantTag() { result = "taintReachesSink" }
override predicate hasActualResult(Location l, string element, string tag, string value) {
tag = "taintReachesSink" and
value = "" and
exists(Conf conf, DataFlow::Node source, DataFlow::Node sink |
conf.hasFlow(source, sink) and
l = source.getLocation() and
element = source.toString()
)
}
}