Skip to content

Commit 7d99d61

Browse files
committed
CPP: Convert SQL tainted to IR dataflow.
1 parent 08d44c1 commit 7d99d61

File tree

2 files changed

+54
-37
lines changed

2 files changed

+54
-37
lines changed

cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,56 @@
1414

1515
import cpp
1616
import semmle.code.cpp.security.Security
17+
import semmle.code.cpp.security.FlowSources
1718
import semmle.code.cpp.security.FunctionWithWrappers
18-
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
19-
import TaintedWithPath
19+
import semmle.code.cpp.ir.IR
20+
import semmle.code.cpp.ir.dataflow.TaintTracking
2021

2122
class SqlLikeFunction extends FunctionWithWrappers {
2223
SqlLikeFunction() { sqlArgument(this.getName(), _) }
2324

2425
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
2526
}
2627

27-
class Configuration extends TaintTrackingConfiguration {
28-
override predicate isSink(Element tainted) {
29-
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
28+
Expr asSinkExpr(DataFlow::Node node) {
29+
result = node.asIndirectArgument()
30+
or
31+
// We want the conversion so we only get one node for the expression
32+
result = node.asConvertedExpr()
33+
}
34+
35+
module SqlTaintedConfig implements DataFlow::ConfigSig {
36+
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
37+
38+
predicate isSink(DataFlow::Node node) {
39+
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _))
3040
}
3141

32-
override predicate isBarrier(Expr e) {
33-
super.isBarrier(e)
34-
or
35-
e.getUnspecifiedType() instanceof IntegralType
36-
or
42+
predicate isBarrier(DataFlow::Node node) {
43+
node.asExpr().getUnspecifiedType() instanceof IntegralType
44+
}
45+
46+
predicate isBarrierIn(DataFlow::Node node) {
3747
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
38-
e = sql.getACallToThisFunction().getArgument(arg) and
48+
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
3949
input.isParameterDeref(arg) and
4050
sql.barrierSqlArgument(input, _)
4151
)
4252
}
4353
}
4454

55+
module SqlTainted = TaintTracking::Global<SqlTaintedConfig>;
56+
57+
import SqlTainted::PathGraph
58+
4559
from
46-
SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
47-
string taintCause, string callChain
60+
SqlLikeFunction runSql, Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode,
61+
SqlTainted::PathNode sinkNode, string callChain
4862
where
4963
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
50-
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
51-
isUserInput(taintSource, taintCause)
64+
SqlTainted::flowPath(sourceNode, sinkNode) and
65+
taintedArg = asSinkExpr(sinkNode.getNode()) and
66+
taintSource = sourceNode.getNode()
5267
select taintedArg, sourceNode, sinkNode,
5368
"This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".",
54-
taintSource, "user input (" + taintCause + ")"
69+
taintSource, "user input (" + taintSource.getSourceType() + ")"
Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
edges
2-
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
3-
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
4-
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
5-
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
6-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
7-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
8-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
9-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
10-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
11-
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
12-
subpaths
2+
| test.c:14:27:14:30 | argv | test.c:21:18:21:23 | query1 indirection |
3+
| test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection |
4+
| test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection |
5+
| test.cpp:39:27:39:30 | argv | test.cpp:43:27:43:33 | access to array |
6+
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array |
7+
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
8+
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
139
nodes
14-
| test.c:15:20:15:23 | argv | semmle.label | argv |
15-
| test.c:15:20:15:23 | argv | semmle.label | argv |
16-
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
17-
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
18-
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
19-
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
20-
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
21-
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
10+
| test.c:14:27:14:30 | argv | semmle.label | argv |
11+
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
12+
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
13+
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
14+
| test.cpp:39:27:39:30 | argv | semmle.label | argv |
15+
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
16+
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
2217
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
18+
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
19+
subpaths
2320
#select
24-
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:15:20:15:23 | argv | user input (argv) |
25-
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:43:27:43:30 | argv | user input (argv) |
21+
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv | user input (a command-line argument) |
22+
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
23+
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
24+
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
25+
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
26+
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
27+
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |

0 commit comments

Comments
 (0)