|
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