From 2dfff879cdfe85dd6769427ed8816a1dac8c5bc6 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 | 94 +++++++++++++++++++ .../dataflow/flowsources/AllSources.qll | 93 ++++++++++++++++++ csharp/ql/src/Telemetry/ExternalApi.qll | 9 +- 3 files changed, 191 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..a0dd06c6fc854 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/AllSinks.qll @@ -0,0 +1,94 @@ +/** 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`. + */ +private module AllSinks { + private import ParallelSink as ParallelSink + private import Remote as Remote + private import semmle.code.csharp.security.cryptography.EncryptionKeyDataFlowQuery as EncryptionKeyDataFlowQuery + 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.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 EncryptionKeyDataFlowSink extends SinkNode instanceof EncryptionKeyDataFlowQuery::SymmetricEncryptionKeySink + { } + + private class HardcodedSymmetricEncryptionKeySink extends SinkNode instanceof HardcodedSymmetricEncryptionKey::Sink + { } + + private class CleartextStorageSink extends SinkNode instanceof CleartextStorageQuery::Sink { } + + 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..d87182fb6418e --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/AllSources.qll @@ -0,0 +1,93 @@ +/** 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`. + */ +private module AllSources { + private import FlowSources as FlowSources + private import semmle.code.csharp.security.cryptography.EncryptionKeyDataFlowQuery as EncryptionKeyDataFlowQuery + 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 { } + + /** TODO: Should this be improved? */ + private class EncryptionKeyDataFlowSource extends SourceNode instanceof EncryptionKeyDataFlowQuery::KeySource + { } + + private class HardcodedSymmetricEncryptionKeySource extends SourceNode instanceof HardcodedSymmetricEncryptionKey::Source + { } + + private class CleartextStorageSource extends SourceNode instanceof CleartextStorageQuery::Source { + } + + private class CodeInjectionSource extends SourceNode instanceof CodeInjectionQuery::Source { } + + private class ConditionalBypassSource extends SourceNode instanceof ConditionalBypassQuery::Source + { } + + private class ExposureOfPrivateInformationSource extends SourceNode instanceof ExposureOfPrivateInformationQuery::Source + { } + + private class HardcodedCredentialsSource extends SourceNode instanceof HardcodedCredentialsQuery::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]