Skip to content

Commit 5df1f7a

Browse files
committed
Ruby: use CfgNodes classes to implement case value to pattern variable taint steps
1 parent 7d7e9ba commit 5df1f7a

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,54 @@ predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
2424
bindingset[node]
2525
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
2626

27+
private CfgNodes::ExprNodes::VariableWriteAccessCfgNode variablesInPattern(
28+
CfgNodes::ExprNodes::CasePatternCfgNode p
29+
) {
30+
result = p
31+
or
32+
exists(CfgNodes::ExprNodes::AsPatternCfgNode ap | p = ap |
33+
result = variablesInPattern(ap.getPattern()) or
34+
result = ap.getVariableAccess()
35+
)
36+
or
37+
exists(CfgNodes::ExprNodes::ParenthesizedPatternCfgNode pp | p = pp |
38+
result = variablesInPattern(pp.getPattern())
39+
)
40+
or
41+
exists(CfgNodes::ExprNodes::AlternativePatternCfgNode ap | p = ap |
42+
result = variablesInPattern(ap.getAlternative(_))
43+
)
44+
or
45+
exists(CfgNodes::ExprNodes::ArrayPatternCfgNode ap | p = ap |
46+
result = variablesInPattern(ap.getPrefixElement(_)) or
47+
result = variablesInPattern(ap.getSuffixElement(_)) or
48+
result = ap.getRestVariableAccess()
49+
)
50+
or
51+
exists(CfgNodes::ExprNodes::FindPatternCfgNode fp | p = fp |
52+
result = variablesInPattern(fp.getElement(_)) or
53+
result = fp.getPrefixVariableAccess() or
54+
result = fp.getSuffixVariableAccess()
55+
)
56+
or
57+
exists(CfgNodes::ExprNodes::HashPatternCfgNode hp | p = hp |
58+
result = variablesInPattern(hp.getValue(_)) or
59+
result = hp.getRestVariableAccess()
60+
)
61+
}
62+
2763
/**
2864
* Holds if the additional step from `nodeFrom` to `nodeTo` should be included
2965
* in all global taint flow configurations.
3066
*/
3167
cached
3268
predicate defaultAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
3369
// value of `case` expression into variables in patterns
34-
exists(VariableWriteAccess varDef, CaseExpr case, InClause clause, CfgNode nodeToCfg |
35-
clause = case.getABranch() and
36-
varDef.getParent*() = clause.getPattern() and
37-
nodeFrom.asExpr().getExpr() = case.getValue() and
38-
nodeToCfg = nodeTo.(SsaDefinitionNode).getDefinition().getControlFlowNode() and
39-
nodeToCfg = nodeFrom.asExpr().getASuccessor+() and
40-
nodeToCfg.getNode() = varDef
70+
exists(CfgNodes::ExprNodes::CaseExprCfgNode case, CfgNodes::ExprNodes::InClauseCfgNode clause |
71+
nodeFrom.asExpr() = case.getValue() and
72+
clause = case.getBranch(_) and
73+
nodeTo.(SsaDefinitionNode).getDefinition().getControlFlowNode() =
74+
variablesInPattern(clause.getPattern())
4175
)
4276
or
4377
// operation involving `nodeFrom`

0 commit comments

Comments
 (0)