mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Python: Model executemany on PEP-249 DB APIs
Note: I kept the modeling using the old approach with type-trackers instead of `DataFlow::MethodCallNode`. I would like a meta query for DCA to show sinks before doing this, so I can be absolutely sure we don't loose out on any important sinks on this... so will postpone this work to a small one-off task (added to my todo list).
This commit is contained in:
@@ -178,4 +178,27 @@ module PEP249 {
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] }
|
||||
}
|
||||
|
||||
private DataFlow::TypeTrackingNode executemany(DataFlow::TypeTracker t) {
|
||||
t.startInAttr("executemany") and
|
||||
result in [Cursor::instance(), Connection::instance()]
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = executemany(t2).track(t2, t))
|
||||
}
|
||||
|
||||
private DataFlow::Node executemany() { executemany(DataFlow::TypeTracker::end()).flowsTo(result) }
|
||||
|
||||
/**
|
||||
* A call to the `executemany` method on a cursor or a connection.
|
||||
*
|
||||
* See https://peps.python.org/pep-0249/#executemany
|
||||
*
|
||||
* Note: While `executemany` method on a connection is not part of PEP249, if it is used, we
|
||||
* recognize it as an alias for constructing a cursor and calling `executemany` on it.
|
||||
*/
|
||||
private class ExecutemanyCall extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ExecutemanyCall() { this.getFunction() = executemany() }
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added model of `executemany` calls on PEP-249 compliant Database APIs, resulting in additional sinks for `py/sql-injection`.
|
||||
@@ -3,4 +3,4 @@ connection = pymssql.connect(host="localhost", user="user", password="passwd")
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("some sql", (42,)) # $ getSql="some sql"
|
||||
cursor.executemany("some sql", [(42,)]) # $ MISSING: getSql="some sql"
|
||||
cursor.executemany("some sql", [(42,)]) # $ getSql="some sql"
|
||||
|
||||
@@ -3,3 +3,4 @@ connection = pymysql.connect(host="localhost", user="user", password="passwd")
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("some sql", (42,)) # $ getSql="some sql"
|
||||
cursor.executemany("some sql", [(42,)]) # $ getSql="some sql"
|
||||
|
||||
Reference in New Issue
Block a user