mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #12803 from michaelnebel/csharp/refactordataflow3
C#: Re-factor dataflow queries to use the new API.
This commit is contained in:
@@ -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 { }
|
||||
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 { }
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user