mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Move query sinks into SQLite.qll
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import java
|
||||
import Android
|
||||
|
||||
/**
|
||||
* The class `android.database.sqlite.SQLiteDatabase`.
|
||||
@@ -28,7 +29,10 @@ abstract class SQLiteRunner extends Method {
|
||||
class ExecSqlMethod extends SQLiteRunner {
|
||||
ExecSqlMethod() {
|
||||
this.getDeclaringType() instanceof TypeSQLiteDatabase and
|
||||
this.getName() = "execSql"
|
||||
// execPerConnectionSQL(String sql, Object[] bindArgs)
|
||||
// execSQL(String sql)
|
||||
// execSQL(String sql, Object[] bindArgs)
|
||||
this.hasName(["execPerConnectionSQL", "execSQL"])
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = 0 }
|
||||
@@ -37,26 +41,179 @@ class ExecSqlMethod extends SQLiteRunner {
|
||||
class QueryMethod extends SQLiteRunner {
|
||||
QueryMethod() {
|
||||
this.getDeclaringType() instanceof TypeSQLiteDatabase and
|
||||
this.getName().matches("rawQuery%")
|
||||
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 = 2 else result = 3)
|
||||
(
|
||||
if this.getParameter(0).getType() instanceof TypeString
|
||||
then result = [2, 4, 5, 6, 7]
|
||||
else result = [3, 5, 6, 7, 8]
|
||||
)
|
||||
or
|
||||
this.getName() = "queryWithFactory" and result = 4
|
||||
// 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 = [4, 6, 7, 8, 9]
|
||||
}
|
||||
}
|
||||
|
||||
class RawQueryMethod extends SQLiteRunner {
|
||||
RawQueryMethod() {
|
||||
this.getDeclaringType() instanceof TypeSQLiteDatabase and
|
||||
this.getName().matches("rawQuery%")
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
class CompileStatementMethod extends SQLiteRunner {
|
||||
CompileStatementMethod() {
|
||||
this.getDeclaringType() instanceof TypeSQLiteDatabase and
|
||||
// compileStatement(String sql)
|
||||
this.hasName("compileStatement")
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = 0 }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
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] }
|
||||
}
|
||||
|
||||
class QueryBuilderInsertMethod extends SQLiteRunner {
|
||||
QueryBuilderInsertMethod() {
|
||||
// insert(SQLiteDatabase db, ContentValues values)
|
||||
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
|
||||
this.hasName("insert")
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = -1 }
|
||||
}
|
||||
|
||||
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, 3, 5, 6, 7, 8] }
|
||||
}
|
||||
|
||||
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] }
|
||||
}
|
||||
|
||||
class ContentProviderDeleteMethod extends SQLiteRunner {
|
||||
ContentProviderDeleteMethod() {
|
||||
// delete(Uri uri, String selection, String[] selectionArgs)
|
||||
this.getDeclaringType() instanceof AndroidContentProvider and
|
||||
this.hasName("delete") and
|
||||
this.getNumberOfParameters() = 3
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = 1 }
|
||||
}
|
||||
|
||||
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 and
|
||||
this.hasName("query") and
|
||||
this.getNumberOfParameters() = [5, 6]
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = 2 }
|
||||
}
|
||||
|
||||
class ContentProviderUpdateMethod extends SQLiteRunner {
|
||||
ContentProviderUpdateMethod() {
|
||||
// update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
|
||||
this.getDeclaringType() instanceof AndroidContentProvider and
|
||||
this.hasName("update") and
|
||||
this.getNumberOfParameters() = 4
|
||||
}
|
||||
|
||||
override int sqlIndex() { result = 2 }
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ private class SqlInjectionSink extends QueryInjectionSink {
|
||||
or
|
||||
exists(MethodAccess ma, Method m, int index |
|
||||
ma.getMethod() = m and
|
||||
ma.getArgument(index) = this.asExpr()
|
||||
if index = -1
|
||||
then this.asExpr() = ma.getQualifier()
|
||||
else ma.getArgument(index) = this.asExpr()
|
||||
|
|
||||
index = m.(SQLiteRunner).sqlIndex()
|
||||
or
|
||||
@@ -90,127 +92,3 @@ private class MongoJsonStep extends AdditionalQueryInjectionTaintStep {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A sink for Android database injection vulnerabilities. */
|
||||
private class AndroidDatabaseUtils extends QueryInjectionSink {
|
||||
AndroidDatabaseUtils() {
|
||||
exists(MethodAccess call, Method method |
|
||||
method = call.getMethod() and
|
||||
method.getDeclaringType().hasQualifiedName("android.database", "DatabaseUtils") and
|
||||
(
|
||||
// (blobFileDescriptor|long|string)ForQuery(SQLiteDatabase db, String query, String[] selectionArgs)
|
||||
method.hasName(["blobFileDescriptorForQuery", "longForQuery", "stringForQuery"]) and
|
||||
method.getNumberOfParameters() = 3 and
|
||||
this.asExpr() = call.getArgument(1)
|
||||
or
|
||||
// createDbFromSqlStatements(Context context, String dbName, int dbVersion, String sqlStatements)
|
||||
method.hasName("createDbFromSqlStatements") and
|
||||
this.asExpr() = call.getArgument(3)
|
||||
or
|
||||
// queryNumEntries(SQLiteDatabase db, String table, String selection)
|
||||
// queryNumEntries(SQLiteDatabase db, String table, String selection, String[] selectionArgs)
|
||||
method.hasName("queryNumEntries") and
|
||||
this.asExpr() = call.getArgument(2)
|
||||
)
|
||||
or
|
||||
method
|
||||
.getDeclaringType()
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("android.database.sqlite", "SQLiteDatabase") and
|
||||
(
|
||||
// compileStatement(String sql)
|
||||
method.hasName("compileStatement") and
|
||||
this.asExpr() = call.getArgument(0)
|
||||
or
|
||||
// delete(String table, String whereClause, String[] whereArgs)
|
||||
method.hasName("delete") and
|
||||
this.asExpr() = call.getArgument(1)
|
||||
or
|
||||
// execPerConnectionSQL(String sql, Object[] bindArgs)
|
||||
// execSQL(String sql)
|
||||
// execSQL(String sql, Object[] bindArgs)
|
||||
method.hasName(["execPerConnectionSQL", "execSQL"]) and
|
||||
this.asExpr() = call.getArgument(0)
|
||||
or
|
||||
// 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)
|
||||
method.hasName("query") and
|
||||
(
|
||||
this.asExpr() = call.getArgument([3, 5, 6, 7, 8]) and
|
||||
method.getNumberOfParameters() = [9, 10]
|
||||
or
|
||||
this.asExpr() = call.getArgument([2, 4, 5, 6, 7]) and
|
||||
method.getNumberOfParameters() = [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)
|
||||
method.hasName("queryWithFactory") and
|
||||
this.asExpr() = call.getArgument([4, 6, 7, 8, 9])
|
||||
or
|
||||
// rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal)
|
||||
// rawQuery(String sql, String[] selectionArgs)
|
||||
method.hasName("rawQuery") and
|
||||
this.asExpr() = call.getArgument(0)
|
||||
or
|
||||
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal)
|
||||
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable)
|
||||
method.hasName("rawQueryWithFactory") and
|
||||
this.asExpr() = call.getArgument(1)
|
||||
or
|
||||
// update(String table, ContentValues values, String whereClause, String[] whereArgs)
|
||||
// updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)
|
||||
method.hasName(["update", "updateWithOnConflict"]) and
|
||||
this.asExpr() = call.getArgument(2)
|
||||
)
|
||||
or
|
||||
method
|
||||
.getDeclaringType()
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("android.content", "ContentProvider") and
|
||||
(
|
||||
// delete(Uri uri, String selection, String[] selectionArgs)
|
||||
method.hasName("delete") and
|
||||
this.asExpr() = call.getArgument(1) and
|
||||
method.getNumberOfParameters() = 3
|
||||
or
|
||||
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
|
||||
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
|
||||
method.hasName("query") and
|
||||
method.getNumberOfParameters() = [5, 6] and
|
||||
this.asExpr() = call.getArgument(2)
|
||||
or
|
||||
// update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
|
||||
method.hasName("update") and
|
||||
this.asExpr() = call.getArgument(2) and
|
||||
method.getNumberOfParameters() = 4
|
||||
)
|
||||
or
|
||||
method
|
||||
.getDeclaringType()
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("android.database.sqlite", "SQLiteQueryBuilder") and
|
||||
(
|
||||
// delete(SQLiteDatabase db, String selection, String[] selectionArgs)
|
||||
method.hasName("delete") and
|
||||
(this.asExpr() = call.getArgument(1) or this.asExpr() = call.getQualifier())
|
||||
or
|
||||
// insert(SQLiteDatabase db, ContentValues values)
|
||||
method.hasName("update") and
|
||||
this.asExpr() = call.getQualifier()
|
||||
or
|
||||
// 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)
|
||||
method.hasName("query") and
|
||||
(this.asExpr() = call.getArgument([3, 5, 6, 7, 8]) or this.asExpr() = call.getQualifier())
|
||||
or
|
||||
// update(SQLiteDatabase db, ContentValues values, String selection, String[] selectionArgs)
|
||||
method.hasName("update") and
|
||||
(this.asExpr() = call.getArgument(2) or this.asExpr() = call.getQualifier())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user