mirror of
https://github.com/github/codeql.git
synced 2026-03-05 23:26:51 +01:00
Merge branch 'main' into mathiasvp/replace-ast-with-ir-use-usedataflow
This commit is contained in:
@@ -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() + ")"
|
||||
|
||||
@@ -116,10 +116,6 @@ class ImproperArrayIndexValidationConfig extends TaintTracking::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets `str` where the first letter has been lowercased. */
|
||||
bindingset[str]
|
||||
string lowerFirst(string str) { result = str.prefix(1).toLowerCase() + str.suffix(1) }
|
||||
|
||||
from
|
||||
ImproperArrayIndexValidationConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
string sourceType
|
||||
@@ -128,4 +124,4 @@ where
|
||||
isFlowSource(source.getNode(), sourceType)
|
||||
select sink.getNode(), source, sink,
|
||||
"An array indexing expression depends on $@ that might be outside the bounds of the array.",
|
||||
source.getNode(), lowerFirst(sourceType)
|
||||
source.getNode(), sourceType
|
||||
|
||||
@@ -19,7 +19,25 @@ import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* A taint flow configuration for flow from user input to a buffer write.
|
||||
* A buffer write into a sensitive expression.
|
||||
*/
|
||||
class SensitiveBufferWrite extends Expr instanceof BufferWrite::BufferWrite {
|
||||
SensitiveBufferWrite() { super.getDest() instanceof SensitiveExpr }
|
||||
|
||||
/**
|
||||
* Gets a data source of this operation.
|
||||
*/
|
||||
Expr getASource() { result = super.getASource() }
|
||||
|
||||
/**
|
||||
* Gets the destination buffer of this operation.
|
||||
*/
|
||||
Expr getDest() { result = super.getDest() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint flow configuration for flow from user input to a buffer write
|
||||
* into a sensitive expression.
|
||||
*/
|
||||
class ToBufferConfiguration extends TaintTracking::Configuration {
|
||||
ToBufferConfiguration() { this = "ToBufferConfiguration" }
|
||||
@@ -31,18 +49,17 @@ class ToBufferConfiguration extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr())
|
||||
exists(SensitiveBufferWrite w | w.getASource() = sink.asExpr())
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
ToBufferConfiguration config, BufferWrite::BufferWrite w, DataFlow::PathNode sourceNode,
|
||||
DataFlow::PathNode sinkNode, FlowSource source, SensitiveExpr dest
|
||||
ToBufferConfiguration config, SensitiveBufferWrite w, DataFlow::PathNode sourceNode,
|
||||
DataFlow::PathNode sinkNode, FlowSource source
|
||||
where
|
||||
config.hasFlowPath(sourceNode, sinkNode) and
|
||||
sourceNode.getNode() = source and
|
||||
w.getASource() = sinkNode.getNode().asExpr() and
|
||||
dest = w.getDest()
|
||||
w.getASource() = sinkNode.getNode().asExpr()
|
||||
select w, sourceNode, sinkNode,
|
||||
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@.", source,
|
||||
"user input (" + source.getSourceType() + ")"
|
||||
"This write into buffer '" + w.getDest().toString() + "' may contain unencrypted data from $@.",
|
||||
source, "user input (" + source.getSourceType() + ")"
|
||||
|
||||
Reference in New Issue
Block a user