|
14 | 14 |
|
15 | 15 | import cpp |
16 | 16 | import semmle.code.cpp.security.Security |
| 17 | +import semmle.code.cpp.security.FlowSources |
17 | 18 | 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 |
| 21 | +import SqlTainted::PathGraph |
20 | 22 |
|
21 | 23 | class SqlLikeFunction extends FunctionWithWrappers { |
22 | 24 | SqlLikeFunction() { sqlArgument(this.getName(), _) } |
23 | 25 |
|
24 | 26 | override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) } |
25 | 27 | } |
26 | 28 |
|
27 | | -class Configuration extends TaintTrackingConfiguration { |
28 | | - override predicate isSink(Element tainted) { |
29 | | - exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _)) |
| 29 | +Expr asSinkExpr(DataFlow::Node node) { |
| 30 | + result = node.asIndirectArgument() |
| 31 | + or |
| 32 | + // We want the conversion so we only get one node for the expression |
| 33 | + result = node.asConvertedExpr() |
| 34 | +} |
| 35 | + |
| 36 | +module SqlTaintedConfig implements DataFlow::ConfigSig { |
| 37 | + predicate isSource(DataFlow::Node node) { node instanceof FlowSource } |
| 38 | + |
| 39 | + predicate isSink(DataFlow::Node node) { |
| 40 | + exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _)) |
30 | 41 | } |
31 | 42 |
|
32 | | - override predicate isBarrier(Expr e) { |
33 | | - super.isBarrier(e) |
34 | | - or |
35 | | - e.getUnspecifiedType() instanceof IntegralType |
36 | | - or |
| 43 | + predicate isBarrier(DataFlow::Node node) { |
| 44 | + node.asExpr().getUnspecifiedType() instanceof IntegralType |
| 45 | + } |
| 46 | + |
| 47 | + predicate isBarrierIn(DataFlow::Node node) { |
37 | 48 | exists(SqlBarrierFunction sql, int arg, FunctionInput input | |
38 | | - e = sql.getACallToThisFunction().getArgument(arg) and |
| 49 | + node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and |
39 | 50 | input.isParameterDeref(arg) and |
40 | 51 | sql.barrierSqlArgument(input, _) |
41 | 52 | ) |
42 | 53 | } |
43 | 54 | } |
44 | 55 |
|
| 56 | +module SqlTainted = TaintTracking::Global<SqlTaintedConfig>; |
| 57 | + |
45 | 58 | from |
46 | | - SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode, |
47 | | - string taintCause, string callChain |
| 59 | + SqlLikeFunction runSql, Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode, |
| 60 | + SqlTainted::PathNode sinkNode, string callChain |
48 | 61 | where |
49 | 62 | runSql.outermostWrapperFunctionCall(taintedArg, callChain) and |
50 | | - taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and |
51 | | - isUserInput(taintSource, taintCause) |
| 63 | + SqlTainted::flowPath(sourceNode, sinkNode) and |
| 64 | + taintedArg = asSinkExpr(sinkNode.getNode()) and |
| 65 | + taintSource = sourceNode.getNode() |
52 | 66 | select taintedArg, sourceNode, sinkNode, |
53 | 67 | "This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".", |
54 | | - taintSource, "user input (" + taintCause + ")" |
| 68 | + taintSource, "user input (" + taintSource.getSourceType() + ")" |
0 commit comments