Skip to content

Commit 170a93c

Browse files
committed
Python: Model cassandra-driver PyPI package
1 parent e4db5f9 commit 170a93c

File tree

6 files changed

+79
-3
lines changed

6 files changed

+79
-3
lines changed

docs/codeql/reusables/supported-frameworks.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co
224224
aiomysql, Database
225225
aiopg, Database
226226
asyncpg, Database
227+
cassandra-driver, Database
227228
clickhouse-driver, Database
228229
cx_Oracle, Database
229230
mysql-connector-python, Database
@@ -233,9 +234,9 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co
233234
oracledb, Database
234235
phoenixdb, Database
235236
psycopg2, Database
236-
pyodbc, Database
237237
pymssql, Database
238238
PyMySQL, Database
239+
pyodbc, Database
239240
sqlite3, Database
240241
Flask-SQLAlchemy, Database ORM
241242
peewee, Database ORM
@@ -276,4 +277,3 @@ and the CodeQL library pack ``codeql/ruby-all`` (`changelog <https://github.com/
276277
Ruby on Rails, Web framework
277278
rubyzip, Compression library
278279
typhoeus, HTTP client
279-

python/ql/lib/semmle/python/Frameworks.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
*/
44

55
// If you add modeling of a new framework/library, remember to add it to the docs in
6-
// `docs/codeql/support/reusables/frameworks.rst`
6+
// `docs/codeql/reusables/supported-frameworks.rst`
77
private import semmle.python.frameworks.Aioch
88
private import semmle.python.frameworks.Aiohttp
99
private import semmle.python.frameworks.Aiomysql
1010
private import semmle.python.frameworks.Aiopg
1111
private import semmle.python.frameworks.Asyncpg
12+
private import semmle.python.frameworks.CassandraDriver
1213
private import semmle.python.frameworks.ClickhouseDriver
1314
private import semmle.python.frameworks.Cryptodome
1415
private import semmle.python.frameworks.Cryptography
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `cassandra-driver` PyPI package.
3+
* See https://pypi.org/project/cassandra-driver/
4+
*/
5+
6+
private import python
7+
private import semmle.python.dataflow.new.DataFlow
8+
private import semmle.python.dataflow.new.RemoteFlowSources
9+
private import semmle.python.Concepts
10+
private import semmle.python.ApiGraphs
11+
private import semmle.python.frameworks.PEP249
12+
13+
/**
14+
* Provides models for the `cassandra-driver` PyPI package.
15+
* See https://pypi.org/project/cassandra-driver/
16+
*/
17+
private module CassandraDriver {
18+
/**
19+
* A cassandra cluster session.
20+
*
21+
* see
22+
* - https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Cluster.connect
23+
* - https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session
24+
*/
25+
API::Node session() {
26+
result =
27+
API::moduleImport("cassandra")
28+
.getMember("cluster")
29+
.getMember("Cluster")
30+
.getReturn()
31+
.getMember("connect")
32+
.getReturn()
33+
}
34+
35+
/**
36+
* see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.execute
37+
*/
38+
class CassandraSessionExecuteCall extends SqlExecution::Range, API::CallNode {
39+
CassandraSessionExecuteCall() { this = session().getMember("execute").getACall() }
40+
41+
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
42+
}
43+
44+
/**
45+
* see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.execute_async
46+
*/
47+
class CassandraSessionExecuteAsyncCall extends SqlConstruction::Range, API::CallNode {
48+
CassandraSessionExecuteAsyncCall() { this = session().getMember("execute_async").getACall() }
49+
50+
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
51+
}
52+
53+
/**
54+
* see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.prepare
55+
*/
56+
class CassandraSessionPrepareCall extends SqlConstruction::Range, API::CallNode {
57+
CassandraSessionPrepareCall() { this = session().getMember("prepare").getACall() }
58+
59+
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
60+
}
61+
}

python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected

Whitespace-only changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import python
2+
import experimental.meta.ConceptsTest
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from cassandra.cluster import Cluster
2+
3+
cluster = Cluster(...)
4+
session = cluster.connect()
5+
6+
session.execute("sql") # $ getSql="sql"
7+
8+
future = session.execute_async("sql") # $ constructedSql="sql"
9+
future.result()
10+
11+
prepared = session.prepare("sql") # $ constructedSql="sql"
12+
session.execute(prepared) # $ SPURIOUS: getSql=prepared

0 commit comments

Comments
 (0)