Merge pull request #12803 from michaelnebel/csharp/refactordataflow3

C#: Re-factor dataflow queries to use the new API.
This commit is contained in:
Michael Nebel
2023-04-14 16:30:55 +02:00
committed by GitHub
21 changed files with 249 additions and 109 deletions

View File

@@ -26,9 +26,11 @@ abstract class Sink extends DataFlow::ExprNode { }
abstract class Sanitizer extends DataFlow::ExprNode { }
/**
* DEPRECATED: Use `TaintedPath` instead.
*
* A taint-tracking configuration for uncontrolled data in path expression vulnerabilities.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "TaintedPath" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -38,6 +40,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking configuration for uncontrolled data in path expression vulnerabilities.
*/
private module TaintedPathConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking module for uncontrolled data in path expression vulnerabilities.
*/
module TaintedPath = TaintTracking::Global<TaintedPathConfig>;
/** A source of remote user input. */
class RemoteSource extends Source instanceof RemoteFlowSource { }

View File

@@ -33,9 +33,11 @@ abstract class Sanitizer extends DataFlow::ExprNode { }
abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { }
/**
* DEPRECATED: Use `UrlRedirect` instead.
*
* A taint-tracking configuration for reasoning about unvalidated URL redirect vulnerabilities.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "UrlRedirect" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -49,6 +51,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
/**
* A taint-tracking configuration for reasoning about unvalidated URL redirect vulnerabilities.
*/
private module UrlRedirectConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking module for reasoning about unvalidated URL redirect vulnerabilities.
*/
module UrlRedirect = TaintTracking::Global<UrlRedirectConfig>;
/** A source of remote user input. */
class RemoteSource extends Source instanceof RemoteFlowSource { }

View File

@@ -44,9 +44,11 @@ private class InsecureXmlSink extends Sink {
abstract class Sanitizer extends DataFlow::Node { }
/**
* DEPRECATED: Use `XmlEntityInjection` instead.
*
* A taint-tracking configuration for untrusted user input used in XML processing.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "XMLInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -61,6 +63,36 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
/**
* A taint-tracking configuration for untrusted user input used in XML processing.
*/
private module XmlEntityInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking module for untrusted user input used in XML processing.
*/
module XmlEntityInjection implements DataFlow::GlobalFlowSig {
import TaintTracking::Global<XmlEntityInjectionConfig> as Super
import Super
/**
* Holds if data can flow from `source` to `sink`.
*
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate flowPath(XmlEntityInjection::PathNode source, XmlEntityInjection::PathNode sink) {
Super::flowPath(source, sink) and
exists(sink.getNode().(Sink).getReason())
}
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }
private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { }

View File

@@ -24,9 +24,11 @@ abstract class Sink extends DataFlow::ExprNode { }
abstract class Sanitizer extends DataFlow::ExprNode { }
/**
* DEPRECATED: Use `XpathInjection` instead.
*
* A taint-tracking configuration for untrusted user input used in XPath expression.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "XPathInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -36,6 +38,32 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking configuration for untrusted user input used in XPath expression.
*/
module XpathInjectionConfig implements DataFlow::ConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(DataFlow::Node source) { source instanceof Source }
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking module for untrusted user input used in XPath expression.
*/
module XpathInjection = TaintTracking::Global<XpathInjectionConfig>;
/** A source of remote user input. */
class RemoteSource extends Source instanceof RemoteFlowSource { }

View File

@@ -27,8 +27,12 @@ abstract class Sanitizer extends DataFlow::ExprNode { }
*/
abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { }
/** A taint tracking configuration for Zip Slip */
class TaintTrackingConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `ZipSlip` instead.
*
* A taint tracking configuration for Zip Slip.
*/
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "ZipSlipTaintTracking" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -42,6 +46,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
/**
* A taint tracking configuration for Zip Slip.
*/
private module ZipSlipConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint tracking module for Zip Slip.
*/
module ZipSlip = TaintTracking::Global<ZipSlipConfig>;
/** An access to the `FullName` property of a `ZipArchiveEntry`. */
class ArchiveFullNameSource extends Source {
ArchiveFullNameSource() {

View File

@@ -10,21 +10,17 @@
*/
import csharp
import DataFlow::PathGraph
import UnsafeYearCreationFromArithmetic::PathGraph
class UnsafeYearCreationFromArithmeticConfiguration extends TaintTracking::Configuration {
UnsafeYearCreationFromArithmeticConfiguration() {
this = "UnsafeYearCreationFromArithmeticConfiguration"
}
override predicate isSource(DataFlow::Node source) {
module UnsafeYearCreationFromArithmeticConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(ArithmeticOperation ao, PropertyAccess pa | ao = source.asExpr() |
pa = ao.getAChild*() and
pa.getProperty().hasQualifiedName("System.DateTime", "Year")
)
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(ObjectCreation oc |
sink.asExpr() = oc.getArgumentForName("year") and
oc.getObjectType().getABaseType*().hasQualifiedName("System", "DateTime")
@@ -32,10 +28,12 @@ class UnsafeYearCreationFromArithmeticConfiguration extends TaintTracking::Confi
}
}
module UnsafeYearCreationFromArithmetic =
TaintTracking::Global<UnsafeYearCreationFromArithmeticConfig>;
from
UnsafeYearCreationFromArithmeticConfiguration config, DataFlow::PathNode source,
DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
UnsafeYearCreationFromArithmetic::PathNode source, UnsafeYearCreationFromArithmetic::PathNode sink
where UnsafeYearCreationFromArithmetic::flowPath(source, sink)
select sink, source, sink,
"This $@ based on a 'System.DateTime.Year' property is used in a construction of a new 'System.DateTime' object, flowing to the 'year' argument.",
source, "arithmetic operation"

View File

@@ -18,21 +18,20 @@ import csharp
import ParallelSink
import ICryptoTransform
class NotThreadSafeCryptoUsageIntoParallelInvokeConfig extends TaintTracking::Configuration {
NotThreadSafeCryptoUsageIntoParallelInvokeConfig() {
this = "NotThreadSafeCryptoUsageIntoParallelInvokeConfig"
}
override predicate isSource(DataFlow::Node source) {
module NotThreadSafeCryptoUsageIntoParallelInvokeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof LambdaCapturingICryptoTransformSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ParallelSink }
predicate isSink(DataFlow::Node sink) { sink instanceof ParallelSink }
}
from Expr e, string m, LambdaExpr l, NotThreadSafeCryptoUsageIntoParallelInvokeConfig config
module NotThreadSafeCryptoUsageIntoParallelInvoke =
TaintTracking::Global<NotThreadSafeCryptoUsageIntoParallelInvokeConfig>;
from Expr e, string m, LambdaExpr l
where
config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e)) and
NotThreadSafeCryptoUsageIntoParallelInvoke::flow(DataFlow::exprNode(l), DataFlow::exprNode(e)) and
m =
"A $@ seems to be used to start a new thread is capturing a local variable that either implements 'System.Security.Cryptography.ICryptoTransform' or has a field of this type."
select e, m, l, "lambda expression"

View File

@@ -16,9 +16,9 @@
import csharp
import semmle.code.csharp.security.dataflow.TaintedPathQuery
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import TaintedPath::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
from TaintedPath::PathNode source, TaintedPath::PathNode sink
where TaintedPath::flowPath(source, sink)
select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -14,10 +14,10 @@
import csharp
import semmle.code.csharp.security.dataflow.ZipSlipQuery
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import ZipSlip::PathGraph
from TaintTrackingConfiguration zipTaintTracking, DataFlow::PathNode source, DataFlow::PathNode sink
where zipTaintTracking.hasFlowPath(source, sink)
from ZipSlip::PathNode source, ZipSlip::PathNode sink
where ZipSlip::flowPath(source, sink)
select source.getNode(), source, sink,
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
"file system operation"

View File

@@ -12,19 +12,17 @@
*/
import csharp
import DataFlow::PathGraph
import semmle.code.csharp.security.dataflow.flowsources.Remote
import semmle.code.csharp.frameworks.system.Xml
import XmlInjection::PathGraph
/**
* A taint-tracking configuration for untrusted user input used in XML.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "XMLInjection" }
module XmlInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc |
mc.getTarget().hasName("WriteRaw") and
mc.getTarget().getDeclaringType().getABaseType*().hasQualifiedName("System.Xml", "XmlWriter")
@@ -33,7 +31,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
)
}
override predicate isSanitizer(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
exists(MethodCall mc |
mc.getTarget().hasName("Escape") and
mc.getTarget()
@@ -46,7 +44,12 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
/**
* A taint-tracking module for untrusted user input used in XML.
*/
module XmlInjection = TaintTracking::Global<XmlInjectionConfig>;
from XmlInjection::PathNode source, XmlInjection::PathNode sink
where XmlInjection::flowPath(source, sink)
select sink.getNode(), source, sink, "This XML element depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -15,20 +15,18 @@
import csharp
import semmle.code.csharp.security.dataflow.flowsources.Remote
import semmle.code.csharp.commons.Util
import DataFlow::PathGraph
import AssemblyPathInjection::PathGraph
/**
* A taint-tracking configuration for untrusted user input used to load a DLL.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "DLLInjection" }
override predicate isSource(DataFlow::Node source) {
module AssemblyPathInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource or
source.asExpr() = any(MainMethod main).getParameter(0).getAnAccess()
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, string name, int arg |
mc.getTarget().getName().matches(name) and
mc.getTarget()
@@ -48,7 +46,12 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
/**
* A taint-tracking module for untrusted user input used to load a DLL.
*/
module AssemblyPathInjection = TaintTracking::Global<AssemblyPathInjectionConfig>;
from AssemblyPathInjection::PathNode source, AssemblyPathInjection::PathNode sink
where AssemblyPathInjection::flowPath(source, sink)
select sink.getNode(), source, sink, "This assembly path depends on a $@.", source,
"user-provided value"

View File

@@ -15,29 +15,29 @@ import csharp
import semmle.code.csharp.security.dataflow.flowsources.Remote
import semmle.code.csharp.security.dataflow.flowsources.Local
import semmle.code.csharp.frameworks.Format
import DataFlow::PathGraph
import FormatString::PathGraph
class FormatStringConfiguration extends TaintTracking::Configuration {
FormatStringConfiguration() { this = "FormatStringConfiguration" }
override predicate isSource(DataFlow::Node source) {
module FormatStringConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
or
source instanceof LocalFlowSource
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(FormatCall call | call.hasInsertions()).getFormatExpr()
}
}
module FormatString = TaintTracking::Global<FormatStringConfig>;
string getSourceType(DataFlow::Node node) {
result = node.(RemoteFlowSource).getSourceType()
or
result = node.(LocalFlowSource).getSourceType()
}
from FormatStringConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
from FormatString::PathNode source, FormatString::PathNode sink
where FormatString::flowPath(source, sink)
select sink.getNode(), source, sink, "This format string depends on $@.", source.getNode(),
("this" + getSourceType(source.getNode()))

View File

@@ -15,12 +15,10 @@ import semmle.code.csharp.security.SensitiveActions
import semmle.code.csharp.security.dataflow.flowsinks.Remote
import semmle.code.csharp.frameworks.system.data.Common
import semmle.code.csharp.frameworks.System
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import ExposureInTransmittedData::PathGraph
class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "Exposure through transmitted data" }
override predicate isSource(DataFlow::Node source) {
module ExposureInTransmittedDataConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// `source` may contain a password
source.asExpr() instanceof PasswordExpr
or
@@ -42,10 +40,12 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
}
from TaintTrackingConfiguration configuration, DataFlow::PathNode source, DataFlow::PathNode sink
where configuration.hasFlowPath(source, sink)
module ExposureInTransmittedData = TaintTracking::Global<ExposureInTransmittedDataConfig>;
from ExposureInTransmittedData::PathNode source, ExposureInTransmittedData::PathNode sink
where ExposureInTransmittedData::flowPath(source, sink)
select sink.getNode(), source, sink, "This data transmitted to the user depends on $@.",
source.getNode(), "sensitive information"

View File

@@ -16,15 +16,13 @@
import csharp
import semmle.code.csharp.frameworks.System
import semmle.code.csharp.security.dataflow.flowsinks.Remote
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import ExceptionInformationExposure::PathGraph
/**
* A taint-tracking configuration for reasoning about stack traces that flow to web page outputs.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "StackTrace" }
override predicate isSource(DataFlow::Node source) {
module ExceptionInformationExposureConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr exceptionExpr |
// Writing an exception directly is bad
source.asExpr() = exceptionExpr
@@ -40,7 +38,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
)
}
override predicate isAdditionalTaintStep(DataFlow::Node source, DataFlow::Node sink) {
predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node sink) {
sink.asExpr() =
any(MethodCall mc |
source.asExpr() = mc.getQualifier() and
@@ -49,20 +47,25 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
override predicate isSanitizer(DataFlow::Node sanitizer) {
predicate isBarrier(DataFlow::Node sanitizer) {
// Do not flow through Message
sanitizer.asExpr() = any(SystemExceptionClass se).getProperty("Message").getAnAccess()
}
override predicate isSanitizerIn(DataFlow::Node sanitizer) {
predicate isBarrierIn(DataFlow::Node sanitizer) {
// Do not flow through Message
sanitizer.asExpr().getType().(RefType).getABaseType*() instanceof SystemExceptionClass
}
}
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
/**
* A taint-tracking module for reasoning about stack traces that flow to web page outputs.
*/
module ExceptionInformationExposure = TaintTracking::Global<ExceptionInformationExposureConfig>;
from ExceptionInformationExposure::PathNode source, ExceptionInformationExposure::PathNode sink
where ExceptionInformationExposure::flowPath(source, sink)
select sink.getNode(), source, sink, "This information exposed to the user depends on $@.",
source.getNode(), "exception information"

View File

@@ -13,9 +13,9 @@
import csharp
import semmle.code.csharp.security.dataflow.UrlRedirectQuery
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import UrlRedirect::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
from UrlRedirect::PathNode source, UrlRedirect::PathNode sink
where UrlRedirect::flowPath(source, sink)
select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.", source.getNode(),
"user-provided value"

View File

@@ -14,10 +14,10 @@
import csharp
import semmle.code.csharp.security.dataflow.XMLEntityInjectionQuery
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import XmlEntityInjection::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
from XmlEntityInjection::PathNode source, XmlEntityInjection::PathNode sink
where XmlEntityInjection::flowPath(source, sink)
select sink.getNode(), source, sink,
"This insecure XML processing depends on a $@ (" + sink.getNode().(Sink).getReason() + ").",
source.getNode(), "user-provided value"

View File

@@ -13,14 +13,20 @@
import csharp
import semmle.code.csharp.security.dataflow.flowsources.Stored
import semmle.code.csharp.security.dataflow.XPathInjectionQuery as XPathInjection
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import semmle.code.csharp.security.dataflow.XPathInjectionQuery
import StoredXpathInjection::PathGraph
class StoredTaintTrackingConfiguration extends XPathInjection::TaintTrackingConfiguration {
override predicate isSource(DataFlow::Node source) { source instanceof StoredFlowSource }
module StoredXpathInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof StoredFlowSource }
predicate isSink = XpathInjectionConfig::isSink/1;
predicate isBarrier = XpathInjectionConfig::isBarrier/1;
}
from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
module StoredXpathInjection = TaintTracking::Global<StoredXpathInjectionConfig>;
from StoredXpathInjection::PathNode source, StoredXpathInjection::PathNode sink
where StoredXpathInjection::flowPath(source, sink)
select sink.getNode(), source, sink, "This XPath expression depends on a $@.", source.getNode(),
"stored (potentially user-provided) value"

View File

@@ -13,9 +13,9 @@
import csharp
import semmle.code.csharp.security.dataflow.XPathInjectionQuery
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import XpathInjection::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
from XpathInjection::PathNode source, XpathInjection::PathNode sink
where XpathInjection::flowPath(source, sink)
select sink.getNode(), source, sink, "This XPath expression depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -16,9 +16,9 @@
import csharp
import TaintedWebClientLib
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
import TaintedWebClient::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
from TaintedWebClient::PathNode source, TaintedWebClient::PathNode sink
where TaintedWebClient::flowPath(source, sink)
select sink.getNode(), source, sink, "A method of WebClient depepends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -38,9 +38,11 @@ abstract class Sink extends DataFlow::ExprNode { }
abstract class Sanitizer extends DataFlow::ExprNode { }
/**
* DEPRECATED: Use `TaintedWebClient` instead.
*
* A taint-tracking configuration for uncontrolled data in path expression vulnerabilities.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "TaintedWebClientLib" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -50,6 +52,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking configuration for uncontrolled data in path expression vulnerabilities.
*/
private module TaintedWebClientConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking module for uncontrolled data in path expression vulnerabilities.
*/
module TaintedWebClient = TaintTracking::Global<TaintedWebClientConfig>;
/** A source of remote user input. */
class RemoteSource extends Source instanceof RemoteFlowSource { }

View File

@@ -11,23 +11,17 @@
*/
import csharp
import DataFlow::PathGraph
import experimental.code.csharp.Cryptography.NonCryptographicHashes
import DataFlowFromMethodToHash::PathGraph
class DataFlowFromMethodToHash extends TaintTracking::Configuration {
DataFlowFromMethodToHash() { this = "DataFlowFromMethodNameToHashFunction" }
module DataFlowFromMethodToHashConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSuspiciousPropertyName(source.asExpr()) }
/**
* Holds if `source` is a relevant data flow source.
*/
override predicate isSource(DataFlow::Node source) { isSuspiciousPropertyName(source.asExpr()) }
/**
* Holds if `sink` is a relevant data flow sink.
*/
override predicate isSink(DataFlow::Node sink) { isGetHash(sink.asExpr()) }
predicate isSink(DataFlow::Node sink) { isGetHash(sink.asExpr()) }
}
module DataFlowFromMethodToHash = TaintTracking::Global<DataFlowFromMethodToHashConfig>;
predicate isGetHash(Expr arg) {
exists(MethodCall mc |
(
@@ -48,8 +42,8 @@ predicate isSuspiciousPropertyName(PropertyRead pr) {
pr.getTarget().hasQualifiedName("System.Diagnostics", "Process", "ProcessName")
}
from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf
where conf.hasFlow(src.getNode(), sink.getNode())
from DataFlowFromMethodToHash::PathNode src, DataFlowFromMethodToHash::PathNode sink
where DataFlowFromMethodToHash::flow(src.getNode(), sink.getNode())
select src.getNode(), src, sink,
"The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent.",
sink.getNode(), "this process name"