Skip to content

Commit 45432f2

Browse files
committed
C#: Identify whether callables in the source code are supported in terms of MaD.
1 parent 3ebb9e1 commit 45432f2

File tree

4 files changed

+65
-38
lines changed

4 files changed

+65
-38
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,20 @@ Element interpretElement(
418418
)
419419
}
420420

421+
/**
422+
* A callable where there exists a MaD sink model that applies to it.
423+
*/
424+
class SinkCallable extends Callable {
425+
SinkCallable() { sinkElement(this, _, _, _) }
426+
}
427+
428+
/**
429+
* A callable where there exists a MaD source model that applies to it.
430+
*/
431+
class SourceCallable extends Callable {
432+
SourceCallable() { sourceElement(this, _, _, _) }
433+
}
434+
421435
cached
422436
private module Cached {
423437
/**

csharp/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,50 @@
88
*/
99

1010
private import csharp
11+
private import semmle.code.csharp.dataflow.ExternalFlow
12+
private import semmle.code.csharp.dataflow.FlowSummary
13+
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlowDispatch
14+
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
15+
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
16+
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
17+
private import semmle.code.csharp.security.dataflow.flowsources.Remote
1118
private import ModelEditor
1219

1320
class ExternalEndpoint extends Endpoint {
1421
ExternalEndpoint() { this.fromLibrary() }
22+
23+
/** Gets a node that is an input to a call to this API. */
24+
private ArgumentNode getAnInput() {
25+
result
26+
.getCall()
27+
.(DataFlowDispatch::NonDelegateDataFlowCall)
28+
.getATarget(_)
29+
.getUnboundDeclaration() = this
30+
}
31+
32+
/** Gets a node that is an output from a call to this API. */
33+
private DataFlow::Node getAnOutput() {
34+
exists(
35+
Call c, DataFlowDispatch::NonDelegateDataFlowCall dc, DataFlowImplCommon::ReturnKindExt ret
36+
|
37+
dc.getDispatchCall().getCall() = c and
38+
c.getTarget().getUnboundDeclaration() = this
39+
|
40+
result = ret.getAnOutNode(dc)
41+
)
42+
}
43+
44+
override predicate hasSummary() {
45+
this instanceof SummarizedCallable
46+
or
47+
defaultAdditionalTaintStep(this.getAnInput(), _)
48+
}
49+
50+
override predicate isSource() {
51+
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
52+
}
53+
54+
override predicate isSink() { sinkNode(this.getAnInput(), _) }
1555
}
1656

1757
private Call aUsage(ExternalEndpoint api) { result.getTarget().getUnboundDeclaration() = api }

csharp/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@
88
*/
99

1010
private import csharp
11-
private import dotnet
11+
private import semmle.code.csharp.dataflow.ExternalFlow
12+
private import semmle.code.csharp.dataflow.FlowSummary
1213
private import semmle.code.csharp.frameworks.Test
1314
private import ModelEditor
1415

1516
class PublicEndpointFromSource extends Endpoint {
1617
PublicEndpointFromSource() { this.fromSource() and not this.getFile() instanceof TestFile }
18+
19+
override predicate hasSummary() { this instanceof SummarizedCallable }
20+
21+
override predicate isSource() { this instanceof SourceCallable }
22+
23+
override predicate isSink() { this instanceof SinkCallable }
1724
}
1825

1926
from PublicEndpointFromSource endpoint, string apiName, boolean supported, string type

csharp/ql/src/utils/modeleditor/ModelEditor.qll

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,9 @@
22

33
private import csharp
44
private import dotnet
5-
private import semmle.code.csharp.dispatch.Dispatch
6-
private import semmle.code.csharp.dataflow.ExternalFlow
7-
private import semmle.code.csharp.dataflow.FlowSummary
8-
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
95
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
10-
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlowDispatch
116
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
12-
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
137
private import semmle.code.csharp.frameworks.Test
14-
private import semmle.code.csharp.security.dataflow.flowsources.Remote
158
private import Telemetry.TestLibrary
169

1710
/** Holds if the given callable is not worth supporting. */
@@ -69,44 +62,17 @@ class Endpoint extends DotNet::Callable {
6962
not exists(this.getDllVersion()) and result = ""
7063
}
7164

72-
/** Gets a node that is an input to a call to this API. */
73-
private ArgumentNode getAnInput() {
74-
result
75-
.getCall()
76-
.(DataFlowDispatch::NonDelegateDataFlowCall)
77-
.getATarget(_)
78-
.getUnboundDeclaration() = this
79-
}
80-
81-
/** Gets a node that is an output from a call to this API. */
82-
private DataFlow::Node getAnOutput() {
83-
exists(
84-
Call c, DataFlowDispatch::NonDelegateDataFlowCall dc, DataFlowImplCommon::ReturnKindExt ret
85-
|
86-
dc.getDispatchCall().getCall() = c and
87-
c.getTarget().getUnboundDeclaration() = this
88-
|
89-
result = ret.getAnOutNode(dc)
90-
)
91-
}
92-
9365
/** Holds if this API has a supported summary. */
9466
pragma[nomagic]
95-
predicate hasSummary() {
96-
this instanceof SummarizedCallable
97-
or
98-
defaultAdditionalTaintStep(this.getAnInput(), _)
99-
}
67+
abstract predicate hasSummary();
10068

10169
/** Holds if this API is a known source. */
10270
pragma[nomagic]
103-
predicate isSource() {
104-
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
105-
}
71+
abstract predicate isSource();
10672

10773
/** Holds if this API is a known sink. */
10874
pragma[nomagic]
109-
predicate isSink() { sinkNode(this.getAnInput(), _) }
75+
abstract predicate isSink();
11076

11177
/** Holds if this API is a known neutral. */
11278
pragma[nomagic]

0 commit comments

Comments
 (0)