From 8a43909f6da09d2e947a891c7d160ed5dce0a309 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 15 Apr 2024 16:16:29 +0200 Subject: [PATCH] C#: Take more sources and sinks into account when reporting in the telemetry queries. --- .../security/dataflow/flowsinks/AllSinks.qll | 84 +++++++++++++++++++ .../dataflow/flowsources/AllSources.qll | 77 +++++++++++++++++ csharp/ql/src/Telemetry/ExternalApi.qll | 9 +- 3 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll create mode 100644 csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll new file mode 100644 index 0000000000000..b0af48947479d --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll @@ -0,0 +1,84 @@ +/** Provides classes representing various flow sinks for data flow / taint tracking. */ + +private import semmle.code.csharp.dataflow.internal.ExternalFlow + +/** + * Module that adds all sinks to `SinkNode`, excluding sinks for cryptography based + * queries, and queries where sinks are not succifiently explicit. + */ +private module AllSinks { + private import ParallelSink as ParallelSink + private import Remote as Remote + private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery + private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery + private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery + private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery + private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery + private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery + private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery + private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery + private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery + private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery + private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery + private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery + private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery + private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery + private import semmle.code.csharp.security.dataflow.XSSSinks as XssSinks + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery + + private class ParallelSink extends SinkNode instanceof ParallelSink::ParallelSink { } + + private class RemoteSinkFlowSinks extends SinkNode instanceof Remote::RemoteFlowSink { } + + private class CodeInjectionSink extends SinkNode instanceof CodeInjectionQuery::Sink { } + + private class ConditionalBypassSink extends SinkNode instanceof ConditionalBypassQuery::Sink { } + + private class ExposureOfPrivateInformationSink extends SinkNode instanceof ExposureOfPrivateInformationQuery::Sink + { } + + private class HardcodedCredentialsSink extends SinkNode instanceof HardcodedCredentialsQuery::Sink + { } + + private class LdapInjectionSink extends SinkNode instanceof LdapInjectionQuery::Sink { } + + private class LogForgingSink extends SinkNode instanceof LogForgingQuery::Sink { } + + private class MissingXmlValidationSink extends SinkNode instanceof MissingXmlValidationQuery::Sink + { } + + private class ReDosSink extends SinkNode instanceof ReDosQuery::Sink { } + + private class RegexInjectionSink extends SinkNode instanceof RegexInjectionQuery::Sink { } + + private class ResourceInjectionSink extends SinkNode instanceof ResourceInjectionQuery::Sink { } + + private class SqlInjectionSink extends SinkNode instanceof SqlInjectionQuery::Sink { } + + private class TaintedPathSink extends SinkNode instanceof TaintedPathQuery::Sink { } + + private class UnsafeDeserializationSink extends SinkNode instanceof UnsafeDeserializationQuery::Sink + { } + + private class UrlRedirectSink extends SinkNode instanceof UrlRedirectQuery::Sink { } + + private class XmlEntityInjectionSink extends SinkNode instanceof XmlEntityInjectionQuery::Sink { } + + private class XpathInjectionSink extends SinkNode instanceof XpathInjectionQuery::Sink { } + + private class XssSink extends SinkNode instanceof XssSinks::Sink { } + + /** + * Add all models as data sinks. + */ + private class SinkNodeExternal extends SinkNode { + SinkNodeExternal() { sinkNode(this, _) } + } +} + +/** + * A data flow sink node. + */ +abstract class SinkNode extends DataFlow::Node { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll new file mode 100644 index 0000000000000..11ff5ae2a553f --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll @@ -0,0 +1,77 @@ +/** Provides classes representing various flow sources for data flow / taint tracking. */ + +private import semmle.code.csharp.dataflow.internal.ExternalFlow + +/** + * Module that adds all sources to `SourceNode`, excluding source for cryptography based + * queries, and queries where sources are not succifiently explicit or mainly hardcoded constants. + */ +private module AllSources { + private import FlowSources as FlowSources + private import semmle.code.csharp.security.cryptography.HardcodedSymmetricEncryptionKey + private import semmle.code.csharp.security.dataflow.CleartextStorageQuery as CleartextStorageQuery + private import semmle.code.csharp.security.dataflow.CodeInjectionQuery as CodeInjectionQuery + private import semmle.code.csharp.security.dataflow.ConditionalBypassQuery as ConditionalBypassQuery + private import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery as ExposureOfPrivateInformationQuery + private import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentialsQuery + private import semmle.code.csharp.security.dataflow.LDAPInjectionQuery as LdapInjectionQuery + private import semmle.code.csharp.security.dataflow.LogForgingQuery as LogForgingQuery + private import semmle.code.csharp.security.dataflow.MissingXMLValidationQuery as MissingXmlValidationQuery + private import semmle.code.csharp.security.dataflow.ReDoSQuery as ReDosQuery + private import semmle.code.csharp.security.dataflow.RegexInjectionQuery as RegexInjectionQuery + private import semmle.code.csharp.security.dataflow.ResourceInjectionQuery as ResourceInjectionQuery + private import semmle.code.csharp.security.dataflow.SqlInjectionQuery as SqlInjectionQuery + private import semmle.code.csharp.security.dataflow.TaintedPathQuery as TaintedPathQuery + private import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery as UnsafeDeserializationQuery + private import semmle.code.csharp.security.dataflow.UrlRedirectQuery as UrlRedirectQuery + private import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery as XmlEntityInjectionQuery + private import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XpathInjectionQuery + private import semmle.code.csharp.security.dataflow.ZipSlipQuery as ZipSlipQuery + + private class FlowSourcesSources extends SourceNode instanceof FlowSources::SourceNode { } + + private class CodeInjectionSource extends SourceNode instanceof CodeInjectionQuery::Source { } + + private class ConditionalBypassSource extends SourceNode instanceof ConditionalBypassQuery::Source + { } + + private class LdapInjectionSource extends SourceNode instanceof LdapInjectionQuery::Source { } + + private class LogForgingSource extends SourceNode instanceof LogForgingQuery::Source { } + + private class MissingXmlValidationSource extends SourceNode instanceof MissingXmlValidationQuery::Source + { } + + private class ReDosSource extends SourceNode instanceof ReDosQuery::Source { } + + private class RegexInjectionSource extends SourceNode instanceof RegexInjectionQuery::Source { } + + private class ResourceInjectionSource extends SourceNode instanceof ResourceInjectionQuery::Source + { } + + private class SqlInjectionSource extends SourceNode instanceof SqlInjectionQuery::Source { } + + private class TaintedPathSource extends SourceNode instanceof TaintedPathQuery::Source { } + + private class UnsafeDeserializationSource extends SourceNode instanceof UnsafeDeserializationQuery::Source + { } + + private class UrlRedirectSource extends SourceNode instanceof UrlRedirectQuery::Source { } + + private class XmlEntityInjectionSource extends SourceNode instanceof XmlEntityInjectionQuery::Source + { } + + private class XpathInjectionSource extends SourceNode instanceof XpathInjectionQuery::Source { } + + /** + * Add all models as data sources. + */ + private class SourceNodeExternal extends SourceNode { + SourceNodeExternal() { sourceNode(this, _) } + } +} + +/** + * A data flow source node. + */ +abstract class SourceNode extends DataFlow::Node { } diff --git a/csharp/ql/src/Telemetry/ExternalApi.qll b/csharp/ql/src/Telemetry/ExternalApi.qll index ebb2411d3a0e0..bae32930bd608 100644 --- a/csharp/ql/src/Telemetry/ExternalApi.qll +++ b/csharp/ql/src/Telemetry/ExternalApi.qll @@ -8,7 +8,8 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlow private import semmle.code.csharp.dataflow.internal.ExternalFlow private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate -private import semmle.code.csharp.security.dataflow.flowsources.Remote +private import semmle.code.csharp.security.dataflow.flowsources.AllSources +private import semmle.code.csharp.security.dataflow.flowsinks.AllSinks private import TestLibrary /** Holds if the given callable is not worth supporting. */ @@ -79,13 +80,11 @@ class ExternalApi extends Callable { /** Holds if this API is a known source. */ pragma[nomagic] - predicate isSource() { - this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) - } + predicate isSource() { this.getAnOutput() instanceof SourceNode } /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { sinkNode(this.getAnInput(), _) } + predicate isSink() { this.getAnInput() instanceof SinkNode } /** Holds if this API is a known neutral. */ pragma[nomagic]