Skip to content

Commit 4d3d07a

Browse files
authored
Merge pull request #16215 from michaelnebel/csharp/telemetryissupported
C#: Take more sources and sinks into account when reporting in the te…
2 parents dc4cc74 + bc0e580 commit 4d3d07a

File tree

8 files changed

+214
-29
lines changed

8 files changed

+214
-29
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/** Provides classes representing various flow sinks for data flow / taint tracking. */
2+
3+
private import semmle.code.csharp.dataflow.internal.ExternalFlow
4+
5+
/**
6+
* A data flow sink node.
7+
*/
8+
abstract class SinkNode extends DataFlow::Node { }
9+
10+
/**
11+
* Module that adds all sinks to `SinkNode`, excluding sinks for cryptography based
12+
* queries, and queries where sinks are not succifiently explicit.
13+
*/
14+
private module AllSinks {
15+
private import ParallelSink as ParallelSink
16+
private import Remote as Remote
17+
private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery
18+
private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery
19+
private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery
20+
private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery
21+
private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery
22+
private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery
23+
private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery
24+
private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery
25+
private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery
26+
private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery
27+
private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery
28+
private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery
29+
private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery
30+
private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery
31+
private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery
32+
private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery
33+
private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks
34+
private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery
35+
36+
private class ParallelSink extends SinkNode instanceof ParallelSink::ParallelSink { }
37+
38+
private class RemoteSinkFlowSinks extends SinkNode instanceof Remote::RemoteFlowSink { }
39+
40+
private class CodeInjectionSink extends SinkNode instanceof CodeInjectionQuery::Sink { }
41+
42+
private class ConditionalBypassSink extends SinkNode instanceof ConditionalBypassQuery::Sink { }
43+
44+
private class ExposureOfPrivateInformationSink extends SinkNode instanceof ExposureOfPrivateInformationQuery::Sink
45+
{ }
46+
47+
private class HardcodedCredentialsSink extends SinkNode instanceof HardcodedCredentialsQuery::Sink
48+
{ }
49+
50+
private class LdapInjectionSink extends SinkNode instanceof LdapInjectionQuery::Sink { }
51+
52+
private class LogForgingSink extends SinkNode instanceof LogForgingQuery::Sink { }
53+
54+
private class MissingXmlValidationSink extends SinkNode instanceof MissingXmlValidationQuery::Sink
55+
{ }
56+
57+
private class ReDosSink extends SinkNode instanceof ReDosQuery::Sink { }
58+
59+
private class RegexInjectionSink extends SinkNode instanceof RegexInjectionQuery::Sink { }
60+
61+
private class ResourceInjectionSink extends SinkNode instanceof ResourceInjectionQuery::Sink { }
62+
63+
private class SqlInjectionSink extends SinkNode instanceof SqlInjectionQuery::Sink { }
64+
65+
private class TaintedPathSink extends SinkNode instanceof TaintedPathQuery::Sink { }
66+
67+
private class UnsafeDeserializationSink extends SinkNode instanceof UnsafeDeserializationQuery::Sink
68+
{ }
69+
70+
private class UrlRedirectSink extends SinkNode instanceof UrlRedirectQuery::Sink { }
71+
72+
private class XmlEntityInjectionSink extends SinkNode instanceof XmlEntityInjectionQuery::Sink { }
73+
74+
private class XpathInjectionSink extends SinkNode instanceof XpathInjectionQuery::Sink { }
75+
76+
private class XssSink extends SinkNode instanceof XssSinks::Sink { }
77+
78+
/**
79+
* Add all models as data sinks.
80+
*/
81+
private class SinkNodeExternal extends SinkNode {
82+
SinkNodeExternal() { sinkNode(this, _) }
83+
}
84+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Provides class representing parallel sink nodes.
3+
*/
4+
5+
import csharp
6+
7+
/**
8+
* A data flow sink node for parallel execution.
9+
*/
10+
abstract class ParallelSink extends DataFlow::Node { }
11+
12+
/**
13+
* A data flow sink node for lambda parallel sink.
14+
*/
15+
class LambdaParallelSink extends ParallelSink {
16+
LambdaParallelSink() {
17+
exists(Class c, Method m, MethodCall mc, Expr e | e = this.asExpr() |
18+
c.getABaseType*().hasFullyQualifiedName("System.Threading.Tasks", "Parallel") and
19+
c.getAMethod() = m and
20+
m.getName() = "Invoke" and
21+
m.getACall() = mc and
22+
mc.getAnArgument() = e
23+
)
24+
}
25+
}
26+
27+
/**
28+
* A data flow sink node for thread start parallel sink.
29+
*/
30+
class ThreadStartParallelSink extends ParallelSink {
31+
ThreadStartParallelSink() {
32+
exists(DelegateCreation dc, Expr e | e = this.asExpr() |
33+
dc.getArgument() = e and
34+
dc.getType().getName().matches("%Start")
35+
)
36+
}
37+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/** Provides classes representing various flow sources for data flow / taint tracking. */
2+
3+
private import semmle.code.csharp.dataflow.internal.ExternalFlow
4+
5+
/**
6+
* A data flow source node.
7+
*/
8+
abstract class SourceNode extends DataFlow::Node { }
9+
10+
/**
11+
* Module that adds all sources to `SourceNode`, excluding source for cryptography based
12+
* queries, and queries where sources are not succifiently explicit or mainly hardcoded constants.
13+
*/
14+
private module AllSources {
15+
private import FlowSources as FlowSources
16+
private import semmle.code.csharp.security.cryptography.HardcodedSymmetricEncryptionKey
17+
private import semmle.code.csharp.security.dataflow.CleartextStorageQuery as CleartextStorageQuery
18+
private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery
19+
private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery
20+
private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery
21+
private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery
22+
private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery
23+
private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery
24+
private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery
25+
private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery
26+
private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery
27+
private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery
28+
private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery
29+
private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery
30+
private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery
31+
private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery
32+
private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery
33+
private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery
34+
private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery
35+
36+
private class FlowSourcesSources extends SourceNode instanceof FlowSources::SourceNode { }
37+
38+
private class CodeInjectionSource extends SourceNode instanceof CodeInjectionQuery::Source { }
39+
40+
private class ConditionalBypassSource extends SourceNode instanceof ConditionalBypassQuery::Source
41+
{ }
42+
43+
private class LdapInjectionSource extends SourceNode instanceof LdapInjectionQuery::Source { }
44+
45+
private class LogForgingSource extends SourceNode instanceof LogForgingQuery::Source { }
46+
47+
private class MissingXmlValidationSource extends SourceNode instanceof MissingXmlValidationQuery::Source
48+
{ }
49+
50+
private class ReDosSource extends SourceNode instanceof ReDosQuery::Source { }
51+
52+
private class RegexInjectionSource extends SourceNode instanceof RegexInjectionQuery::Source { }
53+
54+
private class ResourceInjectionSource extends SourceNode instanceof ResourceInjectionQuery::Source
55+
{ }
56+
57+
private class SqlInjectionSource extends SourceNode instanceof SqlInjectionQuery::Source { }
58+
59+
private class TaintedPathSource extends SourceNode instanceof TaintedPathQuery::Source { }
60+
61+
private class UnsafeDeserializationSource extends SourceNode instanceof UnsafeDeserializationQuery::Source
62+
{ }
63+
64+
private class UrlRedirectSource extends SourceNode instanceof UrlRedirectQuery::Source { }
65+
66+
private class XmlEntityInjectionSource extends SourceNode instanceof XmlEntityInjectionQuery::Source
67+
{ }
68+
69+
private class XpathInjectionSource extends SourceNode instanceof XpathInjectionQuery::Source { }
70+
71+
/**
72+
* Add all models as data sources.
73+
*/
74+
private class SourceNodeExternal extends SourceNode {
75+
SourceNodeExternal() { sourceNode(this, _) }
76+
}
77+
}
Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
1-
import csharp
2-
3-
abstract class ParallelSink extends DataFlow::Node { }
1+
/**
2+
* DEPRECATED: Use `ParallelSink` from `flowsinks.ParallelSink` instead.
3+
*/
44

5-
class LambdaParallelSink extends ParallelSink {
6-
LambdaParallelSink() {
7-
exists(Class c, Method m, MethodCall mc, Expr e | e = this.asExpr() |
8-
c.getABaseType*().hasFullyQualifiedName("System.Threading.Tasks", "Parallel") and
9-
c.getAMethod() = m and
10-
m.getName() = "Invoke" and
11-
m.getACall() = mc and
12-
mc.getAnArgument() = e
13-
)
14-
}
15-
}
16-
17-
class ThreadStartParallelSink extends ParallelSink {
18-
ThreadStartParallelSink() {
19-
exists(DelegateCreation dc, Expr e | e = this.asExpr() |
20-
dc.getArgument() = e and
21-
dc.getType().getName().matches("%Start")
22-
)
23-
}
24-
}
5+
import csharp
6+
deprecated import semmle.code.csharp.security.dataflow.flowsinks.ParallelSink

csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransformLambda.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import csharp
18-
import ParallelSink
18+
import semmle.code.csharp.security.dataflow.flowsinks.ParallelSink
1919
import ICryptoTransform
2020

2121
module NotThreadSafeCryptoUsageIntoParallelInvokeConfig implements DataFlow::ConfigSig {

csharp/ql/src/Telemetry/ExternalApi.qll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlow
88
private import semmle.code.csharp.dataflow.internal.ExternalFlow
99
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1010
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
11-
private import semmle.code.csharp.security.dataflow.flowsources.Remote
11+
private import semmle.code.csharp.security.dataflow.flowsources.AllSources
12+
private import semmle.code.csharp.security.dataflow.flowsinks.AllSinks
1213
private import TestLibrary
1314

1415
/** Holds if the given callable is not worth supporting. */
@@ -84,13 +85,11 @@ class ExternalApi extends Callable {
8485

8586
/** Holds if this API is a known source. */
8687
pragma[nomagic]
87-
predicate isSource() {
88-
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
89-
}
88+
predicate isSource() { this.getAnOutput() instanceof SourceNode }
9089

9190
/** Holds if this API is a known sink. */
9291
pragma[nomagic]
93-
predicate isSink() { sinkNode(this.getAnInput(), _) }
92+
predicate isSink() { this.getAnInput() instanceof SinkNode }
9493

9594
/** Holds if this API is a known neutral. */
9695
pragma[nomagic]

csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ public void M5()
4545
Console.SetError(Console.Out); // Has no flow summary, supported as neutral summary model
4646
var x = Console.Read(); // Known source
4747
}
48+
49+
public void M6()
50+
{
51+
var html = new HtmlString("html"); // Supported HtmlSink defined in QL.
52+
}
4853
}

csharp/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
| System#DateTime.AddDays(System.Double) | 1 |
99
| System#DateTime.DateTime(System.Int32,System.Int32,System.Int32) | 1 |
1010
| System#Guid.Parse(System.String) | 1 |
11+
| System.Web#HtmlString.HtmlString(System.String) | 1 |
1112
| System.Web#HttpResponse.WriteFile(System.String) | 1 |

0 commit comments

Comments
 (0)