Skip to content

Commit a5c8a5b

Browse files
committed
C#: Remove splitting-awareness for taint steps.
1 parent d52e9bc commit a5c8a5b

File tree

1 file changed

+47
-75
lines changed

1 file changed

+47
-75
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 47 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -45,82 +45,58 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c)
4545
)
4646
}
4747

48-
private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityConfiguration {
49-
LocalTaintExprStepConfiguration() { this = "LocalTaintExprStepConfiguration" }
50-
51-
override predicate candidate(
52-
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
53-
) {
54-
exactScope = false and
55-
isSuccessor = true and
56-
(
57-
e1 = e2.(ElementAccess).getQualifier() and
58-
scope = e2
59-
or
60-
e1 = e2.(AddExpr).getAnOperand() and
61-
scope = e2
62-
or
63-
// A comparison expression where taint can flow from one of the
64-
// operands if the other operand is a constant value.
65-
exists(ComparisonTest ct, Expr other |
66-
ct.getExpr() = e2 and
67-
e1 = ct.getAnArgument() and
68-
other = ct.getAnArgument() and
69-
other.stripCasts().hasValue() and
70-
e1 != other and
71-
scope = e2
72-
)
73-
or
74-
e1 = e2.(UnaryLogicalOperation).getAnOperand() and
75-
scope = e2
76-
or
77-
e1 = e2.(BinaryLogicalOperation).getAnOperand() and
78-
scope = e2
79-
or
80-
e1 = e2.(InterpolatedStringExpr).getAChild() and
81-
scope = e2
82-
or
83-
e1 = e2.(InterpolatedStringInsertExpr).getInsert() and
84-
scope = e2
85-
or
86-
e2 =
87-
any(OperatorCall oc |
88-
oc.getTarget().(ConversionOperator).fromLibrary() and
89-
e1 = oc.getAnArgument() and
90-
scope = e2
91-
)
92-
or
93-
e1 = e2.(AwaitExpr).getExpr() and
94-
scope = e2
95-
or
96-
// Taint flows from the operand of a cast to the cast expression if the cast is to an interpolated string handler.
97-
e2 =
98-
any(CastExpr ce |
99-
e1 = ce.getExpr() and
100-
scope = ce and
101-
ce.getTargetType()
102-
.(Attributable)
103-
.getAnAttribute()
104-
.getType()
105-
.hasFullyQualifiedName("System.Runtime.CompilerServices",
106-
"InterpolatedStringHandlerAttribute")
107-
)
48+
private predicate localTaintExprStep(Expr e1, Expr e2) {
49+
e1 = e2.(ElementAccess).getQualifier()
50+
or
51+
e1 = e2.(AddExpr).getAnOperand()
52+
or
53+
// A comparison expression where taint can flow from one of the
54+
// operands if the other operand is a constant value.
55+
exists(ComparisonTest ct, Expr other |
56+
ct.getExpr() = e2 and
57+
e1 = ct.getAnArgument() and
58+
other = ct.getAnArgument() and
59+
other.stripCasts().hasValue() and
60+
e1 != other
61+
)
62+
or
63+
e1 = e2.(UnaryLogicalOperation).getAnOperand()
64+
or
65+
e1 = e2.(BinaryLogicalOperation).getAnOperand()
66+
or
67+
e1 = e2.(InterpolatedStringExpr).getAChild()
68+
or
69+
e1 = e2.(InterpolatedStringInsertExpr).getInsert()
70+
or
71+
e2 =
72+
any(OperatorCall oc |
73+
oc.getTarget().(ConversionOperator).fromLibrary() and
74+
e1 = oc.getAnArgument()
75+
)
76+
or
77+
e1 = e2.(AwaitExpr).getExpr()
78+
or
79+
// Taint flows from the operand of a cast to the cast expression if the cast is to an interpolated string handler.
80+
e2 =
81+
any(CastExpr ce |
82+
e1 = ce.getExpr() and
83+
ce.getTargetType()
84+
.(Attributable)
85+
.getAnAttribute()
86+
.getType()
87+
.hasFullyQualifiedName("System.Runtime.CompilerServices",
88+
"InterpolatedStringHandlerAttribute")
10889
)
109-
}
11090
}
11191

112-
private ControlFlow::Nodes::ExprNode getALastEvalNode(ControlFlow::Nodes::ExprNode cfn) {
113-
exists(OperatorCall oc | any(LocalTaintExprStepConfiguration x).hasExprPath(_, result, oc, cfn) |
114-
oc.getTarget() instanceof ImplicitConversionOperator
115-
)
92+
private Expr getALastEvalNode(OperatorCall oc) {
93+
localTaintExprStep(result, oc) and oc.getTarget() instanceof ImplicitConversionOperator
11694
}
11795

118-
private ControlFlow::Nodes::ExprNode getPostUpdateReverseStep(ControlFlow::Nodes::ExprNode e) {
119-
result = getALastEvalNode(e)
120-
}
96+
private Expr getPostUpdateReverseStep(Expr e) { result = getALastEvalNode(e) }
12197

12298
private predicate localTaintStepCommon(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
123-
hasNodePath(any(LocalTaintExprStepConfiguration x), nodeFrom, nodeTo)
99+
localTaintExprStep(nodeFrom.asExpr(), nodeTo.asExpr())
124100
}
125101

126102
cached
@@ -191,12 +167,8 @@ private module Cached {
191167
// Allow reverse update flow for implicit conversion operator calls.
192168
// This is needed to support flow out of method call arguments, where an implicit conversion is applied
193169
// to a call argument.
194-
nodeTo.(PostUpdateNode).getPreUpdateNode().(DataFlow::ExprNode).getControlFlowNode() =
195-
getPostUpdateReverseStep(nodeFrom
196-
.(PostUpdateNode)
197-
.getPreUpdateNode()
198-
.(DataFlow::ExprNode)
199-
.getControlFlowNode())
170+
nodeTo.(PostUpdateNode).getPreUpdateNode().asExpr() =
171+
getPostUpdateReverseStep(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr())
200172
) and
201173
model = ""
202174
or

0 commit comments

Comments
 (0)