Skip to content

Commit a5a7f3e

Browse files
committed
Python: Add taint-step for sqlalchemy.text
1 parent ef48734 commit a5a7f3e

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

python/ql/src/experimental/semmle/python/frameworks/SqlAlchemy.qll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,38 @@ private module SqlAlchemy {
8383

8484
override DataFlow::Node getSql() { result = this.getArg(0) }
8585
}
86+
87+
/**
88+
* Additional taint-steps for `sqlalchemy.text()`
89+
*
90+
* See https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.text
91+
* See https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.TextClause
92+
*/
93+
class SqlAlchemyTextAdditionalTaintSteps extends TaintTracking::AdditionalTaintStep {
94+
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
95+
exists(DataFlow::CallCfgNode call |
96+
(
97+
call = API::moduleImport("sqlalchemy").getMember("text").getACall()
98+
or
99+
call = API::moduleImport("sqlalchemy").getMember("sql").getMember("text").getACall()
100+
or
101+
call =
102+
API::moduleImport("sqlalchemy")
103+
.getMember("sql")
104+
.getMember("expression")
105+
.getMember("text")
106+
.getACall()
107+
or
108+
call =
109+
API::moduleImport("sqlalchemy")
110+
.getMember("sql")
111+
.getMember("expression")
112+
.getMember("TextClause")
113+
.getACall()
114+
) and
115+
nodeFrom in [call.getArg(0), call.getArgByName("text")] and
116+
nodeTo = call
117+
)
118+
}
119+
}
86120
}

python/ql/test/experimental/library-tests/frameworks/sqlalchemy/taint_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ def test_taint():
55

66
ensure_tainted(
77
ts, # $ tainted
8-
sqlalchemy.text(ts), # $ MISSING: tainted
9-
sqlalchemy.sql.text(ts),# $ MISSING: tainted
10-
sqlalchemy.sql.expression.text(ts),# $ MISSING: tainted
11-
sqlalchemy.sql.expression.TextClause(ts),# $ MISSING: tainted
8+
sqlalchemy.text(ts), # $ tainted
9+
sqlalchemy.sql.text(ts),# $ tainted
10+
sqlalchemy.sql.expression.text(ts),# $ tainted
11+
sqlalchemy.sql.expression.TextClause(ts),# $ tainted
1212
)

0 commit comments

Comments
 (0)