C++: Use FlowSource in cpp/path-injection

This commit is contained in:
Jeroen Ketema
2022-12-09 13:43:13 +01:00
parent d5acd310ce
commit beb66d027e
3 changed files with 12 additions and 35 deletions

View File

@@ -16,7 +16,7 @@
import cpp
import semmle.code.cpp.security.FunctionWithWrappers
import semmle.code.cpp.security.Security
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.TaintTracking
import DataFlow::PathGraph
@@ -47,12 +47,6 @@ class FileFunction extends FunctionWithWrappers {
override predicate interestingArg(int arg) { arg = 0 }
}
Expr asSourceExpr(DataFlow::Node node) {
result = node.asConvertedExpr()
or
result = node.asDefiningArgument()
}
Expr asSinkExpr(DataFlow::Node node) {
result =
node.asOperand()
@@ -89,7 +83,7 @@ predicate hasUpperBoundsCheck(Variable var) {
class TaintedPathConfiguration extends TaintTracking::Configuration {
TaintedPathConfiguration() { this = "TaintedPathConfiguration" }
override predicate isSource(DataFlow::Node node) { isUserInput(asSourceExpr(node), _) }
override predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
override predicate isSink(DataFlow::Node node) {
exists(FileFunction fileFunction |
@@ -108,31 +102,16 @@ class TaintedPathConfiguration extends TaintTracking::Configuration {
hasUpperBoundsCheck(checkedVar)
)
}
predicate hasFilteredFlowPath(DataFlow::PathNode source, DataFlow::PathNode sink) {
this.hasFlowPath(source, sink) and
// The use of `isUserInput` in `isSink` in combination with `asSourceExpr` causes
// duplicate results. Filter these duplicates. The proper solution is to switch to
// using `LocalFlowSource` and `RemoteFlowSource`, but this currently only supports
// a subset of the cases supported by `isUserInput`.
not exists(DataFlow::PathNode source2 |
this.hasFlowPath(source2, sink) and
asSourceExpr(source.getNode()) = asSourceExpr(source2.getNode())
|
not exists(source.getNode().asConvertedExpr()) and exists(source2.getNode().asConvertedExpr())
)
}
}
from
FileFunction fileFunction, Expr taintedArg, Expr taintSource, TaintedPathConfiguration cfg,
DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string taintCause, string callChain
FileFunction fileFunction, Expr taintedArg, FlowSource taintSource, TaintedPathConfiguration cfg,
DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, string callChain
where
taintedArg = asSinkExpr(sinkNode.getNode()) and
fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and
cfg.hasFilteredFlowPath(sourceNode, sinkNode) and
taintSource = asSourceExpr(sourceNode.getNode()) and
isUserInput(taintSource, taintCause)
cfg.hasFlowPath(sourceNode, sinkNode) and
taintSource = sourceNode.getNode()
select taintedArg, sourceNode, sinkNode,
"This argument to a file access function is derived from $@ and then passed to " + callChain + ".",
taintSource, "user input (" + taintCause + ")"
taintSource, "user input (" + taintSource.getSourceType() + ")"

View File

@@ -5,4 +5,4 @@ nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
subpaths
#select
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | user input (string read by fgets) |

View File

@@ -2,7 +2,6 @@ edges
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
| test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
| test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
nodes
| test.c:9:23:9:26 | argv | semmle.label | argv |
@@ -11,12 +10,11 @@ nodes
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:38:11:38:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:43:17:43:24 | fileName | semmle.label | fileName |
| test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:44:11:44:18 | fileName indirection | semmle.label | fileName indirection |
subpaths
#select
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (argv) |
| test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (argv) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | fileName | user input (scanf) |
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | fileName | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | fileName | user input (scanf) |
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (a command-line argument) |
| test.c:32:11:32:18 | fileName | test.c:31:22:31:25 | argv | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:31:22:31:25 | argv | user input (a command-line argument) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |