зеркало из https://github.com/github/codeql.git
Merge pull request #3124 from hvitved/csharp/dataflow/sources-and-sinks
C#: Introduce `RemoteFlowSink` class
This commit is contained in:
Коммит
6cce0de9b2
|
@ -22,6 +22,8 @@ The following changes in version 1.24 affect C# analysis in all applications.
|
|||
| Dereferenced variable may be null (`cs/dereferenced-value-may-be-null`) | More results | Results are reported from parameters with a default value of `null`. |
|
||||
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the value assigned is an (implicitly or explicitly) cast default-like value. For example, `var s = (string)null` and `string s = default`. |
|
||||
| XPath injection (`cs/xml/xpath-injection`) | More results | The query now recognizes calls to methods on `System.Xml.XPath.XPathNavigator` objects. |
|
||||
| Information exposure through transmitted data (`cs/sensitive-data-transmission`) | More results | The query now recognizes writes to cookies and writes to ASP.NET (`Inner`)`Text` properties as additional sinks. |
|
||||
| Information exposure through an exception (`cs/information-exposure-through-exception`) | More results | The query now recognizes writes to cookies, writes to ASP.NET (`Inner`)`Text` properties, and email contents as additional sinks. |
|
||||
|
||||
## Removal of old queries
|
||||
|
||||
|
@ -42,5 +44,6 @@ The following changes in version 1.24 affect C# analysis in all applications.
|
|||
* [Code contracts](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts) are now recognized, and are treated like any other assertion methods.
|
||||
* Expression nullability flow state is given by the predicates `Expr.hasNotNullFlowState()` and `Expr.hasMaybeNullFlowState()`.
|
||||
* `stackalloc` array creations are now represented by the QL class `Stackalloc`. Previously they were represented by the class `ArrayCreation`.
|
||||
* A new class `RemoteFlowSink` has been added to model sinks where data might be exposed to external users. Examples include web page output, e-mails, and cookies.
|
||||
|
||||
## Changes to autobuilder
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.Xml
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.commons.Util
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.dataflow.TaintTracking
|
||||
import semmle.code.csharp.frameworks.Format
|
||||
import DataFlow::PathGraph
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
|
||||
import csharp
|
||||
import semmle.code.csharp.security.SensitiveActions
|
||||
import semmle.code.csharp.security.dataflow.XSS
|
||||
import semmle.code.csharp.security.dataflow.Email
|
||||
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
|
||||
|
@ -42,11 +41,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
|
|||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof XSS::Sink
|
||||
or
|
||||
sink instanceof Email::Sink
|
||||
}
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
|
||||
}
|
||||
|
||||
from TaintTrackingConfiguration configuration, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import csharp
|
||||
import semmle.code.csharp.frameworks.System
|
||||
import semmle.code.csharp.security.dataflow.XSS
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.Remote
|
||||
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
|
|||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof XSS::Sink }
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) {
|
||||
// Do not flow through Message
|
||||
|
|
|
@ -16,7 +16,7 @@ import semmle.code.csharp.frameworks.system.Net
|
|||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.system.web.UI
|
||||
import semmle.code.csharp.security.dataflow.SqlInjection
|
||||
import semmle.code.csharp.security.dataflow.XSS
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.Html
|
||||
import semmle.code.csharp.security.dataflow.UrlRedirect
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
import semmle.code.csharp.dataflow.DataFlow2::DataFlow2
|
||||
|
@ -114,7 +114,7 @@ module EncodingConfigurations {
|
|||
|
||||
override string getKind() { result = "HTML expression" }
|
||||
|
||||
override predicate requiresEncoding(Node n) { n instanceof XSS::HtmlSink }
|
||||
override predicate requiresEncoding(Node n) { n instanceof HtmlSink }
|
||||
|
||||
override predicate isPossibleEncodedValue(Expr e) { e instanceof HtmlSanitizedExpr }
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import semmle.code.csharp.frameworks.Test
|
|||
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
|
||||
|
||||
module Random {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.SensitiveActions
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/**
|
||||
* DEPRECATED.
|
||||
*
|
||||
* Provides classes representing data flow sources for parameters of public callables.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
|
||||
/**
|
||||
* A parameter of a public callable, for example `p` in
|
||||
|
|
|
@ -1,218 +1,7 @@
|
|||
/**
|
||||
* Provides classes representing data flow sources for remote user input.
|
||||
* DEPRECATED.
|
||||
*
|
||||
* Use `semmle.code.csharp.security.dataflow.flowsources.Remote` instead.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import semmle.code.csharp.frameworks.system.Net
|
||||
private import semmle.code.csharp.frameworks.system.Web
|
||||
private import semmle.code.csharp.frameworks.system.web.Http
|
||||
private import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
private import semmle.code.csharp.frameworks.system.web.Services
|
||||
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
private import semmle.code.csharp.frameworks.microsoft.Owin
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
|
||||
/** A data flow source of remote user input. */
|
||||
abstract class RemoteFlowSource extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this remote flow source. */
|
||||
abstract string getSourceType();
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET). */
|
||||
abstract class AspNetRemoteFlowSource extends RemoteFlowSource { }
|
||||
|
||||
/** A member containing an ASP.NET query string. */
|
||||
class AspNetQueryStringMember extends Member {
|
||||
AspNetQueryStringMember() {
|
||||
exists(RefType t |
|
||||
t instanceof SystemWebHttpRequestClass or
|
||||
t instanceof SystemNetHttpListenerRequestClass or
|
||||
t instanceof SystemWebHttpRequestBaseClass
|
||||
|
|
||||
this = t.getProperty(getHttpRequestFlowPropertyNames()) or
|
||||
this.(Field).getType() = t or
|
||||
this.(Property).getType() = t or
|
||||
this.(Callable).getReturnType() = t
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of the properties in `HttpRequest` classes that should propagate taint out of the
|
||||
* request.
|
||||
*/
|
||||
private string getHttpRequestFlowPropertyNames() {
|
||||
result = "QueryString" or
|
||||
result = "Headers" or
|
||||
result = "RawUrl" or
|
||||
result = "Url" or
|
||||
result = "Cookies" or
|
||||
result = "Form" or
|
||||
result = "Params" or
|
||||
result = "Path" or
|
||||
result = "PathInfo"
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET query string). */
|
||||
class AspNetQueryStringRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetQueryStringRemoteFlowSource() {
|
||||
exists(RefType t |
|
||||
t instanceof SystemWebHttpRequestClass or
|
||||
t instanceof SystemNetHttpListenerRequestClass or
|
||||
t instanceof SystemWebHttpRequestBaseClass
|
||||
|
|
||||
// A request object can be indexed, so taint the object as well
|
||||
this.getExpr().getType() = t
|
||||
)
|
||||
or
|
||||
this.getExpr() = any(AspNetQueryStringMember m).getAnAccess()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET query string" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET unvalidated request data). */
|
||||
class AspNetUnvalidatedQueryStringRemoteFlowSource extends AspNetRemoteFlowSource,
|
||||
DataFlow::ExprNode {
|
||||
AspNetUnvalidatedQueryStringRemoteFlowSource() {
|
||||
this.getExpr() = any(SystemWebUnvalidatedRequestValues c).getAProperty().getGetter().getACall() or
|
||||
this.getExpr() =
|
||||
any(SystemWebUnvalidatedRequestValuesBase c).getAProperty().getGetter().getACall()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET unvalidated request data" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET user input). */
|
||||
class AspNetUserInputRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetUserInputRemoteFlowSource() { getType() instanceof SystemWebUIWebControlsTextBoxClass }
|
||||
|
||||
override string getSourceType() { result = "ASP.NET user input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (WCF based web service). */
|
||||
class WcfRemoteFlowSource extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
WcfRemoteFlowSource() { exists(OperationMethod om | om.getAParameter() = this.getParameter()) }
|
||||
|
||||
override string getSourceType() { result = "web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET web service). */
|
||||
class AspNetServiceRemoteFlowSource extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
AspNetServiceRemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.getAParameter() = this.getParameter() and
|
||||
m.getAnAttribute().getType() instanceof SystemWebServicesWebMethodAttributeClass
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET request message). */
|
||||
class SystemNetHttpRequestMessageRemoteFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
SystemNetHttpRequestMessageRemoteFlowSource() {
|
||||
getType() instanceof SystemWebHttpRequestMessageClass
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET request message" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source of remote user input (Microsoft Owin, a query, request,
|
||||
* or path string).
|
||||
*/
|
||||
class MicrosoftOwinStringFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
MicrosoftOwinStringFlowSource() {
|
||||
this.getExpr() = any(MicrosoftOwinString owinString).getValueProperty().getGetter().getACall()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Microsoft Owin request or query string" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (`Microsoft Owin IOwinRequest`). */
|
||||
class MicrosoftOwinRequestRemoteFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
MicrosoftOwinRequestRemoteFlowSource() {
|
||||
exists(Property p, MicrosoftOwinIOwinRequestClass owinRequest |
|
||||
this.getExpr() = p.getGetter().getACall()
|
||||
|
|
||||
p = owinRequest.getAcceptProperty() or
|
||||
p = owinRequest.getBodyProperty() or
|
||||
p = owinRequest.getCacheControlProperty() or
|
||||
p = owinRequest.getContentTypeProperty() or
|
||||
p = owinRequest.getContextProperty() or
|
||||
p = owinRequest.getCookiesProperty() or
|
||||
p = owinRequest.getHeadersProperty() or
|
||||
p = owinRequest.getHostProperty() or
|
||||
p = owinRequest.getMediaTypeProperty() or
|
||||
p = owinRequest.getMethodProperty() or
|
||||
p = owinRequest.getPathProperty() or
|
||||
p = owinRequest.getPathBaseProperty() or
|
||||
p = owinRequest.getQueryProperty() or
|
||||
p = owinRequest.getQueryStringProperty() or
|
||||
p = owinRequest.getRemoteIpAddressProperty() or
|
||||
p = owinRequest.getSchemeProperty() or
|
||||
p = owinRequest.getURIProperty()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Microsoft Owin request" }
|
||||
}
|
||||
|
||||
/** A parameter to an Mvc controller action method, viewed as a source of remote user input. */
|
||||
class ActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
ActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(Controller c).getAnActionMethod().getAParameter() or
|
||||
p = any(ApiController c).getAnActionMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET MVC action method parameter" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET Core). */
|
||||
abstract class AspNetCoreRemoteFlowSource extends RemoteFlowSource { }
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET query collection). */
|
||||
class AspNetCoreQueryRemoteFlowSource extends AspNetCoreRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetCoreQueryRemoteFlowSource() {
|
||||
exists(ValueOrRefType t |
|
||||
t instanceof MicrosoftAspNetCoreHttpHttpRequest or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryCollection or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryString
|
||||
|
|
||||
this.getExpr().(Call).getTarget().getDeclaringType() = t or
|
||||
this.asExpr().(Access).getTarget().getDeclaringType() = t
|
||||
)
|
||||
or
|
||||
exists(Call c |
|
||||
c
|
||||
.getTarget()
|
||||
.getDeclaringType()
|
||||
.hasQualifiedName("Microsoft.AspNetCore.Http", "IQueryCollection") and
|
||||
c.getTarget().getName() = "TryGetValue" and
|
||||
this.asExpr() = c.getArgumentForName("value")
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core query string" }
|
||||
}
|
||||
|
||||
/** A parameter to a `Mvc` controller action method, viewed as a source of remote user input. */
|
||||
class AspNetCoreActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
AspNetCoreActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
}
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
import csharp
|
||||
|
||||
module CleartextStorage {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.security.SensitiveActions
|
||||
import semmle.code.csharp.security.sinks.ExternalLocationSink
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
|
||||
|
||||
/**
|
||||
* A data flow source for cleartext storage of sensitive information.
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
import csharp
|
||||
|
||||
module CodeInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.frameworks.system.codedom.Compiler
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import csharp
|
||||
|
||||
module CommandInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.Diagnostics
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import csharp
|
|||
module UserControlledBypassOfSensitiveMethod {
|
||||
import semmle.code.csharp.controlflow.Guards
|
||||
import semmle.code.csharp.controlflow.BasicBlocks
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.System
|
||||
import semmle.code.csharp.frameworks.system.Net
|
||||
import semmle.code.csharp.security.SensitiveActions
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
import csharp
|
||||
|
||||
module ExposureOfPrivateInformation {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.sinks.ExternalLocationSink
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
|
||||
import semmle.code.csharp.security.PrivateData
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import csharp
|
||||
|
||||
module LDAPInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.DirectoryServices
|
||||
import semmle.code.csharp.frameworks.system.directoryservices.Protocols
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
import csharp
|
||||
|
||||
module LogForging {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.System
|
||||
import semmle.code.csharp.frameworks.system.text.RegularExpressions
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
import semmle.code.csharp.security.sinks.ExternalLocationSink
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
|
||||
|
||||
/**
|
||||
* A data flow source for untrusted user input used in log entries.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import csharp
|
||||
|
||||
module MissingXMLValidation {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.Xml
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import csharp
|
|||
|
||||
module ReDoS {
|
||||
private import semmle.code.csharp.dataflow.DataFlow2
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.text.RegularExpressions
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import csharp
|
||||
|
||||
module RegexInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.text.RegularExpressions
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
import csharp
|
||||
|
||||
module ResourceInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.frameworks.system.Data
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
import csharp
|
||||
|
||||
module SqlInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Local
|
||||
import semmle.code.csharp.frameworks.Sql
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import csharp
|
|||
|
||||
module TaintedPath {
|
||||
import semmle.code.csharp.controlflow.Guards
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.IO
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import csharp
|
||||
|
||||
module UnsafeDeserialization {
|
||||
private import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
private import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
private import semmle.code.csharp.serialization.Deserializers
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import csharp
|
||||
|
||||
module UrlRedirect {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.controlflow.Guards
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import csharp
|
||||
|
||||
module XMLEntityInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.System
|
||||
import semmle.code.csharp.frameworks.system.text.RegularExpressions
|
||||
import semmle.code.csharp.security.xml.InsecureXML
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import csharp
|
||||
|
||||
module XPathInjection {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.system.xml.XPath
|
||||
import semmle.code.csharp.frameworks.system.Xml
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
|
|
|
@ -6,17 +6,14 @@
|
|||
import csharp
|
||||
|
||||
module XSS {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
import semmle.code.asp.AspNet
|
||||
import semmle.code.csharp.frameworks.system.Net
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
import semmle.code.csharp.frameworks.system.web.WebPages
|
||||
import semmle.code.csharp.frameworks.system.web.UI
|
||||
import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
import semmle.code.csharp.frameworks.system.windows.Forms
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
import semmle.code.asp.AspNet
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.Html
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
|
||||
/**
|
||||
* Holds if there is tainted flow from `source` to `sink` that may lead to a
|
||||
|
@ -112,8 +109,11 @@ module XSS {
|
|||
|
||||
/**
|
||||
* A data flow sink for cross-site scripting (XSS) vulnerabilities.
|
||||
*
|
||||
* Any XSS sink is also a remote flow sink, so this class contributes
|
||||
* to the abstract class `RemoteFlowSink`.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::ExprNode {
|
||||
abstract class Sink extends DataFlow::ExprNode, RemoteFlowSink {
|
||||
string explanation() { none() }
|
||||
}
|
||||
|
||||
|
@ -166,78 +166,21 @@ module XSS {
|
|||
UrlEncodeSanitizer() { this.getExpr() instanceof UrlSanitizedExpr }
|
||||
}
|
||||
|
||||
/** A sink where the value of the expression may be rendered as HTML. */
|
||||
abstract class HtmlSink extends DataFlow::Node { }
|
||||
private class HtmlSinkSink extends Sink {
|
||||
HtmlSinkSink() { this instanceof HtmlSink }
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an XSS sink method on
|
||||
* `HttpResponse`.
|
||||
*/
|
||||
private class HttpResponseSink extends Sink, HtmlSink {
|
||||
HttpResponseSink() {
|
||||
exists(Method m, SystemWebHttpResponseClass responseClass |
|
||||
m = responseClass.getAWriteMethod() or
|
||||
m = responseClass.getAWriteFileMethod() or
|
||||
m = responseClass.getATransmitFileMethod() or
|
||||
m = responseClass.getABinaryWriteMethod()
|
||||
|
|
||||
// Calls to these methods, or overrides of them
|
||||
this.getExpr() = m.getAnOverrider*().getParameter(0).getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an XSS sink method on
|
||||
* `HtmlTextWriter`.
|
||||
*/
|
||||
private class HtmlTextWriterSink extends Sink, HtmlSink {
|
||||
HtmlTextWriterSink() {
|
||||
exists(SystemWebUIHtmlTextWriterClass writeClass, Method m, Call c, int paramPos |
|
||||
paramPos = 0 and
|
||||
(
|
||||
m = writeClass.getAWriteMethod() or
|
||||
m = writeClass.getAWriteLineMethod() or
|
||||
m = writeClass.getAWriteLineNoTabsMethod() or
|
||||
m = writeClass.getAWriteBeginTagMethod() or
|
||||
m = writeClass.getAWriteAttributeMethod()
|
||||
)
|
||||
or
|
||||
// The second parameter to the `WriteAttribute` method is the attribute value, which we
|
||||
// should only consider as tainted if the call does not ask for the attribute value to be
|
||||
// encoded using the final parameter.
|
||||
m = writeClass.getAWriteAttributeMethod() and
|
||||
paramPos = 1 and
|
||||
not c.getArgumentForParameter(m.getParameter(2)).(BoolLiteral).getBoolValue() = true
|
||||
|
|
||||
c = m.getACall() and
|
||||
this.getExpr() = c.getArgumentForParameter(m.getParameter(paramPos))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an XSS sink method on
|
||||
* `AttributeCollection`.
|
||||
*/
|
||||
private class AttributeCollectionSink extends Sink, HtmlSink {
|
||||
AttributeCollectionSink() {
|
||||
exists(SystemWebUIAttributeCollectionClass ac, Parameter p |
|
||||
p = ac.getAddMethod().getParameter(1) or
|
||||
p = ac.getItemProperty().getSetter().getParameter(0)
|
||||
|
|
||||
this.getExpr() = p.getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as the second argument `HtmlElement.SetAttribute`.
|
||||
*/
|
||||
private class SetAttributeSink extends Sink, HtmlSink {
|
||||
SetAttributeSink() {
|
||||
this.getExpr() =
|
||||
any(SystemWindowsFormsHtmlElement c).getSetAttributeMethod().getACall().getArgument(1)
|
||||
override string explanation() {
|
||||
this instanceof WebPageWriteLiteralSink and
|
||||
result = "System.Web.WebPages.WebPage.WriteLiteral() method"
|
||||
or
|
||||
this instanceof WebPageWriteLiteralToSink and
|
||||
result = "System.Web.WebPages.WebPage.WriteLiteralTo() method"
|
||||
or
|
||||
this instanceof MicrosoftAspNetCoreMvcHtmlHelperRawSink and
|
||||
result = "Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method"
|
||||
or
|
||||
this instanceof MicrosoftAspNetRazorPageWriteLiteralSink and
|
||||
result = "Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,31 +228,6 @@ module XSS {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an XSS sink setter, on
|
||||
* a class within the `System.Web.UI` namespace.
|
||||
*/
|
||||
private class SystemWebSetterHtmlSink extends Sink, HtmlSink {
|
||||
SystemWebSetterHtmlSink() {
|
||||
exists(Property p, string name, ValueOrRefType declaringType |
|
||||
declaringType = p.getDeclaringType() and
|
||||
any(SystemWebUINamespace n).getAChildNamespace*() = declaringType.getNamespace() and
|
||||
this.getExpr() = p.getSetter().getParameter(0).getAnAssignedArgument() and
|
||||
p.hasName(name)
|
||||
|
|
||||
name = "Caption" and
|
||||
(declaringType.hasName("Calendar") or declaringType.hasName("Table"))
|
||||
or
|
||||
name = "InnerHtml"
|
||||
)
|
||||
or
|
||||
exists(SystemWebUIWebControlsLabelClass c |
|
||||
// Unlike `Text` properties of other web controls, `Label.Text` is not automatically HTML encoded
|
||||
this.getExpr() = c.getTextProperty().getSetter().getParameter(0).getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an XSS sink setter, on
|
||||
* a class within the `System.Web.UI` namespace.
|
||||
|
@ -345,16 +263,6 @@ module XSS {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `HtmlHelper.Raw`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
private class SystemWebMvcHtmlHelperRawSink extends Sink, HtmlSink {
|
||||
SystemWebMvcHtmlHelperRawSink() {
|
||||
this.getExpr() = any(SystemWebMvcHtmlHelperClass h).getRawMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a member which is accessed by the given `AspInlineCode`.
|
||||
* The code body must consist only of an access to the member, possibly with qualified
|
||||
|
@ -493,31 +401,6 @@ module XSS {
|
|||
}
|
||||
}
|
||||
|
||||
/** An expression that is returned from a `ToHtmlString` method. */
|
||||
private class ToHtmlString extends Sink, HtmlSink {
|
||||
ToHtmlString() {
|
||||
exists(Method toHtmlString |
|
||||
toHtmlString =
|
||||
any(SystemWebIHtmlString i).getToHtmlStringMethod().getAnUltimateImplementor() and
|
||||
toHtmlString.canReturn(this.getExpr())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression passed to the constructor of an `HtmlString` or a `MvcHtmlString`.
|
||||
*/
|
||||
private class HtmlString extends Sink, HtmlSink {
|
||||
HtmlString() {
|
||||
exists(Class c |
|
||||
c = any(SystemWebMvcMvcHtmlString m) or
|
||||
c = any(SystemWebHtmlString m)
|
||||
|
|
||||
this.getExpr() = c.getAConstructor().getACall().getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression passed as the `content` argument to the constructor of `StringContent`.
|
||||
*/
|
||||
|
@ -529,75 +412,6 @@ module XSS {
|
|||
).getArgumentForName("content")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteral`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class WebPageWriteLiteralSink extends Sink, HtmlSink {
|
||||
WebPageWriteLiteralSink() {
|
||||
this.getExpr() = any(WebPageClass h).getWriteLiteralMethod().getACall().getAnArgument()
|
||||
}
|
||||
|
||||
override string explanation() { result = "System.Web.WebPages.WebPage.WriteLiteral() method" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteralTo`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class WebPageWriteLiteralToSink extends Sink, HtmlSink {
|
||||
WebPageWriteLiteralToSink() {
|
||||
this.getExpr() = any(WebPageClass h).getWriteLiteralToMethod().getACall().getAnArgument()
|
||||
}
|
||||
|
||||
override string explanation() { result = "System.Web.WebPages.WebPage.WriteLiteralTo() method" }
|
||||
}
|
||||
|
||||
abstract class AspNetCoreSink extends Sink, HtmlSink { }
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `HtmlHelper.Raw`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class MicrosoftAspNetCoreMvcHtmlHelperRawSink extends AspNetCoreSink {
|
||||
MicrosoftAspNetCoreMvcHtmlHelperRawSink() {
|
||||
this.getExpr() =
|
||||
any(MicrosoftAspNetCoreMvcHtmlHelperClass h).getRawMethod().getACall().getAnArgument()
|
||||
}
|
||||
|
||||
override string explanation() {
|
||||
result = "Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteral` in ASP.NET 6.0 razor page, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class MicrosoftAspNetRazorPageWriteLiteralSink extends AspNetCoreSink {
|
||||
MicrosoftAspNetRazorPageWriteLiteralSink() {
|
||||
this.getExpr() =
|
||||
any(MicrosoftAspNetCoreMvcRazorPageBase h)
|
||||
.getWriteLiteralMethod()
|
||||
.getACall()
|
||||
.getAnArgument()
|
||||
}
|
||||
|
||||
override string explanation() {
|
||||
result = "Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.WriteLiteral() method"
|
||||
}
|
||||
}
|
||||
|
||||
/** `HtmlString` that may be rendered as is need to have sanitized value. */
|
||||
class MicrosoftAspNetHtmlStringSink extends AspNetCoreSink {
|
||||
MicrosoftAspNetHtmlStringSink() {
|
||||
exists(ObjectCreation c, MicrosoftAspNetCoreHttpHtmlString s |
|
||||
c.getTarget() = s.getAConstructor() and
|
||||
this.asExpr() = c.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Type getMemberType(Member m) {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/** Provides data flow sinks for sending email. */
|
||||
|
||||
import csharp
|
||||
private import Remote
|
||||
private import semmle.code.csharp.frameworks.system.net.Mail
|
||||
|
||||
/** Provides sinks for emails. */
|
||||
module Email {
|
||||
/** A data flow sink for sending email. */
|
||||
abstract class Sink extends DataFlow::ExprNode { }
|
||||
abstract class Sink extends DataFlow::ExprNode, RemoteFlowSink { }
|
||||
|
||||
/** A data flow sink for sending email via `System.Net.Mail.MailMessage`. */
|
||||
class MailMessageSink extends Sink {
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
import csharp
|
||||
private import Remote
|
||||
private import semmle.code.csharp.commons.Loggers
|
||||
private import semmle.code.csharp.frameworks.system.Web
|
||||
|
||||
|
@ -45,7 +46,7 @@ class TraceMessageSink extends ExternalLocationSink {
|
|||
/**
|
||||
* An expression set as a value on a cookie instance.
|
||||
*/
|
||||
class CookieStorageSink extends ExternalLocationSink {
|
||||
class CookieStorageSink extends ExternalLocationSink, RemoteFlowSink {
|
||||
CookieStorageSink() {
|
||||
exists(Expr e | e = this.getExpr() |
|
||||
e = any(SystemWebHttpCookie cookie).getAConstructor().getACall().getArgumentForName("value")
|
|
@ -0,0 +1,208 @@
|
|||
/**
|
||||
* Provides classes representing HTML data flow sinks.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import Remote
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
private import semmle.code.csharp.frameworks.system.Net
|
||||
private import semmle.code.csharp.frameworks.system.Web
|
||||
private import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
private import semmle.code.csharp.frameworks.system.web.WebPages
|
||||
private import semmle.code.csharp.frameworks.system.web.UI
|
||||
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
private import semmle.code.csharp.frameworks.system.windows.Forms
|
||||
private import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
private import semmle.code.asp.AspNet
|
||||
|
||||
/**
|
||||
* A sink where the value of the expression may be rendered as HTML,
|
||||
* without implicit HTML encoding.
|
||||
*/
|
||||
abstract class HtmlSink extends DataFlow::ExprNode, RemoteFlowSink { }
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an HTML sink method on
|
||||
* `HttpResponse`.
|
||||
*/
|
||||
class HttpResponseSink extends HtmlSink {
|
||||
HttpResponseSink() {
|
||||
exists(Method m, SystemWebHttpResponseClass responseClass |
|
||||
m = responseClass.getAWriteMethod() or
|
||||
m = responseClass.getAWriteFileMethod() or
|
||||
m = responseClass.getATransmitFileMethod() or
|
||||
m = responseClass.getABinaryWriteMethod()
|
||||
|
|
||||
// Calls to these methods, or overrides of them
|
||||
this.getExpr() = m.getAnOverrider*().getParameter(0).getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an HTML sink method on
|
||||
* `HtmlTextWriter`.
|
||||
*/
|
||||
class HtmlTextWriterSink extends HtmlSink {
|
||||
HtmlTextWriterSink() {
|
||||
exists(SystemWebUIHtmlTextWriterClass writeClass, Method m, Call c, int paramPos |
|
||||
paramPos = 0 and
|
||||
(
|
||||
m = writeClass.getAWriteMethod() or
|
||||
m = writeClass.getAWriteLineMethod() or
|
||||
m = writeClass.getAWriteLineNoTabsMethod() or
|
||||
m = writeClass.getAWriteBeginTagMethod() or
|
||||
m = writeClass.getAWriteAttributeMethod()
|
||||
)
|
||||
or
|
||||
// The second parameter to the `WriteAttribute` method is the attribute value, which we
|
||||
// should only consider as tainted if the call does not ask for the attribute value to be
|
||||
// encoded using the final parameter.
|
||||
m = writeClass.getAWriteAttributeMethod() and
|
||||
paramPos = 1 and
|
||||
not c.getArgumentForParameter(m.getParameter(2)).(BoolLiteral).getBoolValue() = true
|
||||
|
|
||||
c = m.getACall() and
|
||||
this.getExpr() = c.getArgumentForParameter(m.getParameter(paramPos))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an HTML sink method on
|
||||
* `AttributeCollection`.
|
||||
*/
|
||||
class AttributeCollectionSink extends HtmlSink {
|
||||
AttributeCollectionSink() {
|
||||
exists(SystemWebUIAttributeCollectionClass ac, Parameter p |
|
||||
p = ac.getAddMethod().getParameter(1) or
|
||||
p = ac.getItemProperty().getSetter().getParameter(0)
|
||||
|
|
||||
this.getExpr() = p.getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as the second argument `HtmlElement.SetAttribute`.
|
||||
*/
|
||||
class SetAttributeSink extends HtmlSink {
|
||||
SetAttributeSink() {
|
||||
this.getExpr() =
|
||||
any(SystemWindowsFormsHtmlElement c).getSetAttributeMethod().getACall().getArgument(1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to an HTML sink setter, on
|
||||
* a class within the `System.Web.UI` namespace.
|
||||
*/
|
||||
class SystemWebSetterHtmlSink extends HtmlSink {
|
||||
SystemWebSetterHtmlSink() {
|
||||
exists(Property p, string name, ValueOrRefType declaringType |
|
||||
declaringType = p.getDeclaringType() and
|
||||
any(SystemWebUINamespace n).getAChildNamespace*() = declaringType.getNamespace() and
|
||||
this.getExpr() = p.getAnAssignedValue() and
|
||||
p.hasName(name)
|
||||
|
|
||||
name = "Caption" and
|
||||
(declaringType.hasName("Calendar") or declaringType.hasName("Table"))
|
||||
or
|
||||
name = "InnerHtml"
|
||||
)
|
||||
or
|
||||
exists(SystemWebUIWebControlsLabelClass c |
|
||||
// Unlike `Text` properties of other web controls, `Label.Text` is not automatically HTML encoded
|
||||
this.getExpr() = c.getTextProperty().getSetter().getParameter(0).getAnAssignedArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `HtmlHelper.Raw`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class SystemWebMvcHtmlHelperRawSink extends HtmlSink {
|
||||
SystemWebMvcHtmlHelperRawSink() {
|
||||
this.getExpr() = any(SystemWebMvcHtmlHelperClass h).getRawMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/** An expression that is returned from a `ToHtmlString` method. */
|
||||
class ToHtmlString extends HtmlSink {
|
||||
ToHtmlString() {
|
||||
exists(Method toHtmlString |
|
||||
toHtmlString = any(SystemWebIHtmlString i).getToHtmlStringMethod().getAnUltimateImplementor() and
|
||||
toHtmlString.canReturn(this.getExpr())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression passed to the constructor of an `HtmlString` or a `MvcHtmlString`.
|
||||
*/
|
||||
class HtmlString extends HtmlSink {
|
||||
HtmlString() {
|
||||
exists(Class c |
|
||||
c = any(SystemWebMvcMvcHtmlString m) or
|
||||
c = any(SystemWebHtmlString m)
|
||||
|
|
||||
this.getExpr() = c.getAConstructor().getACall().getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteral`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class WebPageWriteLiteralSink extends HtmlSink {
|
||||
WebPageWriteLiteralSink() {
|
||||
this.getExpr() = any(WebPageClass h).getWriteLiteralMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteralTo`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class WebPageWriteLiteralToSink extends HtmlSink {
|
||||
WebPageWriteLiteralToSink() {
|
||||
this.getExpr() = any(WebPageClass h).getWriteLiteralToMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/** An ASP.NET Core HTML sink. */
|
||||
abstract class AspNetCoreHtmlSink extends HtmlSink { }
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `HtmlHelper.Raw`, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class MicrosoftAspNetCoreMvcHtmlHelperRawSink extends AspNetCoreHtmlSink {
|
||||
MicrosoftAspNetCoreMvcHtmlHelperRawSink() {
|
||||
this.getExpr() =
|
||||
any(MicrosoftAspNetCoreMvcHtmlHelperClass h).getRawMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is used as an argument to `Page.WriteLiteral` in ASP.NET 6.0 razor page, typically in
|
||||
* a `.cshtml` file.
|
||||
*/
|
||||
class MicrosoftAspNetRazorPageWriteLiteralSink extends AspNetCoreHtmlSink {
|
||||
MicrosoftAspNetRazorPageWriteLiteralSink() {
|
||||
this.getExpr() =
|
||||
any(MicrosoftAspNetCoreMvcRazorPageBase h).getWriteLiteralMethod().getACall().getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/** `HtmlString` that may be rendered as is need to have sanitized value. */
|
||||
class MicrosoftAspNetHtmlStringSink extends AspNetCoreHtmlSink {
|
||||
MicrosoftAspNetHtmlStringSink() {
|
||||
exists(ObjectCreation c, MicrosoftAspNetCoreHttpHtmlString s |
|
||||
c.getTarget() = s.getAConstructor() and
|
||||
this.asExpr() = c.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Provides classes representing data flow sinks for remote user output.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import Email::Email
|
||||
private import ExternalLocationSink
|
||||
private import Html
|
||||
private import semmle.code.csharp.security.dataflow.XSS
|
||||
private import semmle.code.csharp.frameworks.system.web.UI
|
||||
|
||||
/** A data flow sink of remote user output. */
|
||||
abstract class RemoteFlowSink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A value written to the `[Inner]Text` property of an object defined in the
|
||||
* `System.Web.UI` namespace.
|
||||
*/
|
||||
class SystemWebUIText extends RemoteFlowSink {
|
||||
SystemWebUIText() {
|
||||
exists(Property p, string name |
|
||||
p.getDeclaringType().getNamespace().getParentNamespace*() instanceof SystemWebUINamespace and
|
||||
this.asExpr() = p.getAnAssignedValue() and
|
||||
p.hasName(name)
|
||||
|
|
||||
name = "Text"
|
||||
or
|
||||
name = "InnerText"
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* Provides classes representing data flow sources for remote user input.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import semmle.code.csharp.frameworks.system.Net
|
||||
private import semmle.code.csharp.frameworks.system.Web
|
||||
private import semmle.code.csharp.frameworks.system.web.Http
|
||||
private import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
private import semmle.code.csharp.frameworks.system.web.Services
|
||||
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
private import semmle.code.csharp.frameworks.microsoft.Owin
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
|
||||
/** A data flow source of remote user input. */
|
||||
abstract class RemoteFlowSource extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this remote flow source. */
|
||||
abstract string getSourceType();
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET). */
|
||||
abstract class AspNetRemoteFlowSource extends RemoteFlowSource { }
|
||||
|
||||
/** A member containing an ASP.NET query string. */
|
||||
class AspNetQueryStringMember extends Member {
|
||||
AspNetQueryStringMember() {
|
||||
exists(RefType t |
|
||||
t instanceof SystemWebHttpRequestClass or
|
||||
t instanceof SystemNetHttpListenerRequestClass or
|
||||
t instanceof SystemWebHttpRequestBaseClass
|
||||
|
|
||||
this = t.getProperty(getHttpRequestFlowPropertyNames()) or
|
||||
this.(Field).getType() = t or
|
||||
this.(Property).getType() = t or
|
||||
this.(Callable).getReturnType() = t
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of the properties in `HttpRequest` classes that should propagate taint out of the
|
||||
* request.
|
||||
*/
|
||||
private string getHttpRequestFlowPropertyNames() {
|
||||
result = "QueryString" or
|
||||
result = "Headers" or
|
||||
result = "RawUrl" or
|
||||
result = "Url" or
|
||||
result = "Cookies" or
|
||||
result = "Form" or
|
||||
result = "Params" or
|
||||
result = "Path" or
|
||||
result = "PathInfo"
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET query string). */
|
||||
class AspNetQueryStringRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetQueryStringRemoteFlowSource() {
|
||||
exists(RefType t |
|
||||
t instanceof SystemWebHttpRequestClass or
|
||||
t instanceof SystemNetHttpListenerRequestClass or
|
||||
t instanceof SystemWebHttpRequestBaseClass
|
||||
|
|
||||
// A request object can be indexed, so taint the object as well
|
||||
this.getExpr().getType() = t
|
||||
)
|
||||
or
|
||||
this.getExpr() = any(AspNetQueryStringMember m).getAnAccess()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET query string" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET unvalidated request data). */
|
||||
class AspNetUnvalidatedQueryStringRemoteFlowSource extends AspNetRemoteFlowSource,
|
||||
DataFlow::ExprNode {
|
||||
AspNetUnvalidatedQueryStringRemoteFlowSource() {
|
||||
this.getExpr() = any(SystemWebUnvalidatedRequestValues c).getAProperty().getGetter().getACall() or
|
||||
this.getExpr() =
|
||||
any(SystemWebUnvalidatedRequestValuesBase c).getAProperty().getGetter().getACall()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET unvalidated request data" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET user input). */
|
||||
class AspNetUserInputRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetUserInputRemoteFlowSource() { getType() instanceof SystemWebUIWebControlsTextBoxClass }
|
||||
|
||||
override string getSourceType() { result = "ASP.NET user input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (WCF based web service). */
|
||||
class WcfRemoteFlowSource extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
WcfRemoteFlowSource() { exists(OperationMethod om | om.getAParameter() = this.getParameter()) }
|
||||
|
||||
override string getSourceType() { result = "web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET web service). */
|
||||
class AspNetServiceRemoteFlowSource extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
AspNetServiceRemoteFlowSource() {
|
||||
exists(Method m |
|
||||
m.getAParameter() = this.getParameter() and
|
||||
m.getAnAttribute().getType() instanceof SystemWebServicesWebMethodAttributeClass
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET request message). */
|
||||
class SystemNetHttpRequestMessageRemoteFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
SystemNetHttpRequestMessageRemoteFlowSource() {
|
||||
getType() instanceof SystemWebHttpRequestMessageClass
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET request message" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source of remote user input (Microsoft Owin, a query, request,
|
||||
* or path string).
|
||||
*/
|
||||
class MicrosoftOwinStringFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
MicrosoftOwinStringFlowSource() {
|
||||
this.getExpr() = any(MicrosoftOwinString owinString).getValueProperty().getGetter().getACall()
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Microsoft Owin request or query string" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (`Microsoft Owin IOwinRequest`). */
|
||||
class MicrosoftOwinRequestRemoteFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
|
||||
MicrosoftOwinRequestRemoteFlowSource() {
|
||||
exists(Property p, MicrosoftOwinIOwinRequestClass owinRequest |
|
||||
this.getExpr() = p.getGetter().getACall()
|
||||
|
|
||||
p = owinRequest.getAcceptProperty() or
|
||||
p = owinRequest.getBodyProperty() or
|
||||
p = owinRequest.getCacheControlProperty() or
|
||||
p = owinRequest.getContentTypeProperty() or
|
||||
p = owinRequest.getContextProperty() or
|
||||
p = owinRequest.getCookiesProperty() or
|
||||
p = owinRequest.getHeadersProperty() or
|
||||
p = owinRequest.getHostProperty() or
|
||||
p = owinRequest.getMediaTypeProperty() or
|
||||
p = owinRequest.getMethodProperty() or
|
||||
p = owinRequest.getPathProperty() or
|
||||
p = owinRequest.getPathBaseProperty() or
|
||||
p = owinRequest.getQueryProperty() or
|
||||
p = owinRequest.getQueryStringProperty() or
|
||||
p = owinRequest.getRemoteIpAddressProperty() or
|
||||
p = owinRequest.getSchemeProperty() or
|
||||
p = owinRequest.getURIProperty()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Microsoft Owin request" }
|
||||
}
|
||||
|
||||
/** A parameter to an Mvc controller action method, viewed as a source of remote user input. */
|
||||
class ActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
ActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(Controller c).getAnActionMethod().getAParameter() or
|
||||
p = any(ApiController c).getAnActionMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET MVC action method parameter" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET Core). */
|
||||
abstract class AspNetCoreRemoteFlowSource extends RemoteFlowSource { }
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET query collection). */
|
||||
class AspNetCoreQueryRemoteFlowSource extends AspNetCoreRemoteFlowSource, DataFlow::ExprNode {
|
||||
AspNetCoreQueryRemoteFlowSource() {
|
||||
exists(ValueOrRefType t |
|
||||
t instanceof MicrosoftAspNetCoreHttpHttpRequest or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryCollection or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryString
|
||||
|
|
||||
this.getExpr().(Call).getTarget().getDeclaringType() = t or
|
||||
this.asExpr().(Access).getTarget().getDeclaringType() = t
|
||||
)
|
||||
or
|
||||
exists(Call c |
|
||||
c
|
||||
.getTarget()
|
||||
.getDeclaringType()
|
||||
.hasQualifiedName("Microsoft.AspNetCore.Http", "IQueryCollection") and
|
||||
c.getTarget().getName() = "TryGetValue" and
|
||||
this.asExpr() = c.getArgumentForName("value")
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core query string" }
|
||||
}
|
||||
|
||||
/** A parameter to a `Mvc` controller action method, viewed as a source of remote user input. */
|
||||
class AspNetCoreActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
AspNetCoreActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.security.dataflow.flowsources.Remote
|
||||
|
||||
from RemoteFlowSource source
|
||||
select source, source.getSourceType()
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public class StackTraceHandler : IHttpHandler
|
||||
{
|
||||
bool b;
|
||||
TextBox textBox;
|
||||
|
||||
public void ProcessRequest(HttpContext ctx)
|
||||
{
|
||||
try
|
||||
|
@ -34,6 +37,11 @@ public class StackTraceHandler : IHttpHandler
|
|||
// GOOD: log the stack trace, and send back a non-revealing response
|
||||
log("Exception occurred", ex);
|
||||
ctx.Response.Write("Exception occurred");
|
||||
|
||||
textBox.Text = ex.InnerException.StackTrace; // BAD
|
||||
textBox.Text = ex.StackTrace; // BAD
|
||||
textBox.Text = ex.ToString(); // BAD
|
||||
textBox.Text = ex.Message; // GOOD
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
edges
|
||||
| ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex |
|
||||
nodes
|
||||
| ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | semmle.label | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:21:32:21:44 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | semmle.label | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:25:32:25:44 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:55 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:42:28:42:40 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:43:28:43:40 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:49:28:49:55 | call to method ToString | semmle.label | call to method ToString |
|
||||
#select
|
||||
| ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:44 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:18:32:18:33 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:20:32:20:33 | access to local variable ex | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:22:32:22:44 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:55 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:21:32:21:44 | call to method ToString | ExceptionInformationExposure.cs:21:32:21:44 | call to method ToString | ExceptionInformationExposure.cs:21:32:21:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:21:32:21:44 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:25:32:25:44 | access to property StackTrace | ExceptionInformationExposure.cs:25:32:25:44 | access to property StackTrace | ExceptionInformationExposure.cs:25:32:25:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:25:32:25:44 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:55 | access to property StackTrace | ExceptionInformationExposure.cs:41:28:41:55 | access to property StackTrace | ExceptionInformationExposure.cs:41:28:41:55 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:55 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:42:28:42:40 | access to property StackTrace | ExceptionInformationExposure.cs:42:28:42:40 | access to property StackTrace | ExceptionInformationExposure.cs:42:28:42:40 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:42:28:42:40 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:43:28:43:40 | call to method ToString | ExceptionInformationExposure.cs:43:28:43:40 | call to method ToString | ExceptionInformationExposure.cs:43:28:43:40 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:43:28:43:40 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:49:28:49:55 | call to method ToString | ExceptionInformationExposure.cs:49:28:49:55 | call to method ToString | ExceptionInformationExposure.cs:49:28:49:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:49:28:49:55 | call to method ToString | call to method ToString |
|
||||
|
|
Загрузка…
Ссылка в новой задаче