Merge pull request #17663 from aschackmull/dataflow/speculative-flow

Dataflow: Add support for speculative taint flow.
This commit is contained in:
Anders Schack-Mulligen
2024-10-31 08:12:43 +01:00
committed by GitHub
47 changed files with 656 additions and 121 deletions

View File

@@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig {
model = ""
}
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
predicate isAdditionalFlowStep(
Node node1, FlowState state1, Node node2, FlowState state2, string model
) {
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
getConfig(state2) = getConfig(state1)
getConfig(state2) = getConfig(state1) and
model = ""
or
not singleConfiguration() and
getConfig(state1).isAdditionalFlowStep(node1, node2) and
state2 = state1
state2 = state1 and
model = ""
}
predicate allowImplicitRead(Node node, ContentSet c) {

View File

@@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig {
model = ""
}
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
predicate isAdditionalFlowStep(
Node node1, FlowState state1, Node node2, FlowState state2, string model
) {
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
getConfig(state2) = getConfig(state1)
getConfig(state2) = getConfig(state1) and
model = ""
or
not singleConfiguration() and
getConfig(state1).isAdditionalFlowStep(node1, node2) and
state2 = state1
state2 = state1 and
model = ""
}
predicate allowImplicitRead(Node node, ContentSet c) {

View File

@@ -149,3 +149,37 @@ private module Cached {
}
import Cached
import SpeculativeTaintFlow
private module SpeculativeTaintFlow {
private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
private import codeql.ruby.dataflow.internal.DataFlowPublic as DataFlowPublic
/**
* Holds if the additional step from `src` to `sink` should be considered in
* speculative taint flow exploration.
*/
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) {
exists(
DataFlowDispatch::DataFlowCall call, MethodCall srcCall,
DataFlowDispatch::ArgumentPosition argpos, MethodCall mc
|
// TODO: exclude neutrals and anything that has QL modeling.
not exists(DataFlowDispatch::viableCallable(call)) and
call.asCall().getExpr() = srcCall and
src.(ArgumentNode).argumentOf(call, argpos) and
call.asCall().getExpr() = mc and
not mc instanceof Operation and
not mc instanceof SetterMethodCall and
not mc instanceof ElementReference
|
not argpos.isSelf() and
sink.(DataFlowPublic::PostUpdateNode)
.getPreUpdateNode()
.(ArgumentNode)
.argumentOf(call, any(DataFlowDispatch::ArgumentPosition qualpos | qualpos.isSelf()))
or
sink.(OutNode).getCall(_) = call
)
}
}