Skip to content

Commit 715da38

Browse files
authored
Merge pull request #22360 from hugo-syn/hugo-syn/csharp-additional-taint-step
C#: add AdditionalTaintStep extension point for taint-tracking
2 parents 7f60101 + 522bcd9 commit 715da38

6 files changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* Added the `AdditionalTaintStep` extension point (`semmle.code.csharp.dataflow.FlowSteps`). Extend this class to add additional taint steps that apply to all taint-tracking configurations.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Provides classes representing various flow steps for taint tracking.
3+
*/
4+
5+
private import codeql.util.Unit
6+
private import semmle.code.csharp.dataflow.DataFlow
7+
8+
/**
9+
* A unit class for adding additional taint steps.
10+
*
11+
* Extend this class to add additional taint steps that should apply to all
12+
* taint configurations.
13+
*/
14+
class AdditionalTaintStep extends Unit {
15+
/**
16+
* Holds if the step from `node1` to `node2` should be considered a taint
17+
* step for all configurations.
18+
*/
19+
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
20+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ private import csharp
22
private import TaintTrackingPublic
33
private import FlowSummaryImpl as FlowSummaryImpl
44
private import semmle.code.csharp.Caching
5+
private import semmle.code.csharp.dataflow.FlowSteps
56
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
67
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
78
private import semmle.code.csharp.dispatch.Dispatch
@@ -172,6 +173,8 @@ private module Cached {
172173
model = ""
173174
or
174175
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false, model)
176+
or
177+
any(AdditionalTaintStep a).step(nodeFrom, nodeTo) and model = "AdditionalTaintStep"
175178
}
176179
}
177180

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| Test.cs:13:35:13:45 | access to parameter taintSource | Test.cs:13:23:13:46 | call to method Step | AdditionalTaintStep |
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import csharp
2+
import semmle.code.csharp.dataflow.FlowSteps
3+
import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
4+
5+
/**
6+
* A test-only additional taint step that treats calls to `Marker.Step` as
7+
* propagating taint from the argument to the call result, to verify that
8+
* `AdditionalTaintStep` subclasses are picked up by `defaultAdditionalTaintStep`.
9+
*/
10+
private class MarkerStepTaintStep extends AdditionalTaintStep {
11+
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
12+
exists(MethodCall mc |
13+
mc.getTarget().hasName("Step") and
14+
mc.getTarget().getDeclaringType().hasName("Marker")
15+
|
16+
node1.asExpr() = mc.getArgument(0) and
17+
node2.asExpr() = mc
18+
)
19+
}
20+
}
21+
22+
from DataFlow::Node src, DataFlow::Node sink, string model
23+
where defaultAdditionalTaintStep(src, sink, model) and model = "AdditionalTaintStep"
24+
select src, sink, model
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Marker
2+
{
3+
// A stand-in for a framework method that isn't otherwise understood by the
4+
// taint-tracking library, whose taint behaviour is modelled by a test-only
5+
// `AdditionalTaintStep` subclass instead.
6+
public static object Step(object x) => new object();
7+
}
8+
9+
class Test
10+
{
11+
void M(object taintSource)
12+
{
13+
var tainted = Marker.Step(taintSource);
14+
Sink(tainted);
15+
}
16+
17+
static void Sink(object o) { }
18+
}

0 commit comments

Comments
 (0)