Skip to content
Merged
1 change: 1 addition & 0 deletions swift/ql/lib/codeql/swift/frameworks/Frameworks.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

private import Alamofire.Alamofire
private import JavaScriptCore.JavaScriptCore
private import SQL.SQL
private import StandardLibrary.StandardLibrary
private import UIKit.UIKit
private import Xml.Xml
23 changes: 23 additions & 0 deletions swift/ql/lib/codeql/swift/frameworks/SQL/SQL.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Provides models for SQL libraries.
*/

import swift
private import codeql.swift.dataflow.ExternalFlow

/**
* A model for SQL library functions that permit taint flow.
*/
private class FilePathSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
// SQLite.Swift
";;false;<-(_:_:);;;Argument[0..1];ReturnValue;taint",
";Expression;true;init(_:_:);;;Argument[0];ReturnValue;taint",
";Expression;true;init(_:_:);;;Argument[1].CollectionElement;ReturnValue;taint",
";ExpressionType;true;init(_:);;;Argument[0];ReturnValue;taint",
";ExpressionType;true;replace(_:with:);;;Argument[1];ReturnValue;taint",
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,48 @@ private class CleartextStorageDatabaseSinks extends SinkModelCsv {
";FetchableRecord;true;fetchOne(_:arguments:adapter:);;;Argument[1];database-store",
";Statement;true;execute(arguments:);;;Argument[0];database-store",
";CommonTableExpression;true;init(recursive:named:columns:sql:arguments:);;;Argument[4];database-store",
";Statement;true;setArguments(_:);;;Argument[0];database-store"
";Statement;true;setArguments(_:);;;Argument[0];database-store",
// sqlite3 sinks
";;false;sqlite3_exec(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare_v2(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare_v3(_:_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare16(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare16_v2(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_prepare16_v3(_:_:_:_:_:);;;Argument[1];database-store",
";;false;sqlite3_bind_blob(_:_:_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_blob64(_:_:_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_double(_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_int(_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_int64(_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_text(_:_:_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_text16(_:_:_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_text64(_:_:_:_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_value(_:_:_:);;;Argument[2];database-store",
";;false;sqlite3_bind_pointer(_:_:_:_:);;;Argument[2];database-store",
// SQLite.swift
";Connection;true;execute(_:);;;Argument[0];database-store",
";Connection;true;prepare(_:_:);;;Argument[0];database-store",
";Connection;true;prepare(_:_:);;;Argument[1];database-store",
";Connection;true;run(_:_:);;;Argument[0];database-store",
";Connection;true;run(_:_:);;;Argument[1];database-store",
";Connection;true;scalar(_:_:);;;Argument[0];database-store",
";Connection;true;scalar(_:_:);;;Argument[1];database-store",
";Statement;true;init(_:_:);;;Argument[1];database-store",
";Statement;true;bind(_:);;;Argument[0];database-store",
";Statement;true;run(_:);;;Argument[0];database-store",
";Statement;true;scalar(_:);;;Argument[0];database-store",
";QueryType;true;insert(_:);;;Argument[0];database-store",
";QueryType;true;insert(_:_:);;;Argument[0..1];database-store",
";QueryType;true;insert(or:_:);;;Argument[1];database-store",
";QueryType;true;insertMany(_:);;;Argument[0];database-store",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be Argument[0].CollectionElement?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it can't be because at present MAD doesn't support access path syntax on sinks (or sources). I'm pushing for this feature because I think it's the natural way to express sinks like this.

The case should covered by the additional taint step at present, and that will be upgraded to an implicit read step in this query in #14357 .

I've just added tests for insertMany to this PR, as it's a special case that clearly deserves a test of its own.

";QueryType;true;insertMany(or:_:);;;Argument[1];database-store",
";QueryType;true;upsert(_:onConflictOf:);;;Argument[0];database-store",
";QueryType;true;upsert(_:onConflictOf:setValues:);;;Argument[0];database-store",
";QueryType;true;upsert(_:onConflictOf:setValues:);;;Argument[2];database-store",
";QueryType;true;update(_:);;;Argument[0];database-store",
";QueryType;true;update(_:_:);;;Argument[0..1];database-store",
";QueryType;true;update(or:_:);;;Argument[1];database-store",
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ module CleartextStorageDatabaseConfig implements DataFlow::ConfigSig {
c.getAReadContent().(DataFlow::Content::FieldContent).getField() = cx.getAMember()
)
or
// flow out from array elements of at the sink,
// flow out from dictionary tuple values at the sink (this is essential
// for some of the SQLite.swift models).
isSink(node) and
node.asExpr().getType().getUnderlyingType() instanceof DictionaryType and
c.getAReadContent().(DataFlow::Content::TupleContent).getIndex() = 1
or
// flow out from array elements (and other collection content) at the sink,
// for example in `database.allStatements(sql: "", arguments: [sensitive])`.
isSink(node) and
c.getAReadContent() instanceof DataFlow::Content::CollectionContent
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added sqlite3 and SQLite.swift sinks and flow summaries for the `swift/cleartext-storage-database` query.
Loading