Skip to content

Commit ae3227f

Browse files
Rasmus Lerchedahl PetersenRasmus Lerchedahl Petersen
authored andcommitted
Python: initial sketch
1 parent 4a59e69 commit ae3227f

File tree

1 file changed

+99
-0
lines changed
  • python/ql/src/experimental/semmle/python/frameworks

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
private import python
2+
private import experimental.dataflow.DataFlow
3+
private import experimental.dataflow.RemoteFlowSources
4+
private import experimental.semmle.python.Concepts
5+
6+
abstract class PEP249Module extends DataFlow::Node { }
7+
8+
/** Gets a reference to a connect call. */
9+
private DataFlow::Node connect(DataFlow::TypeTracker t) {
10+
t.startInAttr("connect") and
11+
result instanceof PEP249Module
12+
or
13+
exists(DataFlow::TypeTracker t2 | result = connect(t2).track(t2, t))
14+
}
15+
16+
/** Gets a reference to a connect call. */
17+
DataFlow::Node connect() { result = connect(DataFlow::TypeTracker::end()) }
18+
19+
/**
20+
* Provides models for the `db.Conection` class
21+
*
22+
* See apiref.
23+
*/
24+
module Connection {
25+
/**
26+
* A source of an instance of `db.Conection`.
27+
*
28+
* This can include instantiation of the class, return value from function
29+
* calls, or a special parameter that will be set when functions are call by external
30+
* library.
31+
*
32+
* Use `Conection::instance()` predicate to get references to instances of `db.Conection`.
33+
*/
34+
abstract class InstanceSource extends DataFlow::Node { }
35+
36+
/** A direct instantiation of `db.Conection`. */
37+
private class ClassInstantiation extends InstanceSource, DataFlow::CfgNode {
38+
override CallNode node;
39+
40+
ClassInstantiation() { node.getFunction() = connect().asCfgNode() }
41+
}
42+
43+
/** Gets a reference to an instance of `db.Conection`. */
44+
private DataFlow::Node instance(DataFlow::TypeTracker t) {
45+
t.start() and
46+
result instanceof InstanceSource
47+
or
48+
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
49+
}
50+
51+
/** Gets a reference to an instance of `db.Conection`. */
52+
DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }
53+
}
54+
55+
/** Provides models for the `django.db.connection.cursor` method. */
56+
module cursor {
57+
/** Gets a reference to the `django.db.connection.cursor` metod. */
58+
private DataFlow::Node methodRef(DataFlow::TypeTracker t) {
59+
t.startInAttr("cursor") and
60+
result = Connection::instance()
61+
or
62+
exists(DataFlow::TypeTracker t2 | result = methodRef(t2).track(t2, t))
63+
}
64+
65+
/** Gets a reference to the `django.db.connection.cursor` metod. */
66+
DataFlow::Node methodRef() { result = methodRef(DataFlow::TypeTracker::end()) }
67+
68+
/** Gets a reference to a result of calling `django.db.connection.cursor`. */
69+
private DataFlow::Node methodResult(DataFlow::TypeTracker t) {
70+
t.start() and
71+
result.asCfgNode().(CallNode).getFunction() = methodRef().asCfgNode()
72+
or
73+
exists(DataFlow::TypeTracker t2 | result = methodResult(t2).track(t2, t))
74+
}
75+
76+
/** Gets a reference to a result of calling `django.db.connection.cursor`. */
77+
DataFlow::Node methodResult() { result = methodResult(DataFlow::TypeTracker::end()) }
78+
}
79+
80+
/** Gets a reference to the `django.db.connection.cursor.execute` function. */
81+
private DataFlow::Node execute(DataFlow::TypeTracker t) {
82+
t.startInAttr("execute") and
83+
result = cursor::methodResult()
84+
or
85+
exists(DataFlow::TypeTracker t2 | result = execute(t2).track(t2, t))
86+
}
87+
88+
/** Gets a reference to the `django.db.connection.cursor.execute` function. */
89+
DataFlow::Node execute() { result = execute(DataFlow::TypeTracker::end()) }
90+
91+
private class DbConnectionExecute extends SqlExecution::Range, DataFlow::CfgNode {
92+
override CallNode node;
93+
94+
DbConnectionExecute() { node.getFunction() = execute().asCfgNode() }
95+
96+
override DataFlow::Node getSql() {
97+
result.asCfgNode() in [node.getArg(0), node.getArgByName("sql")]
98+
}
99+
}

0 commit comments

Comments
 (0)