mirror of
https://github.com/github/codeql.git
synced 2026-05-05 13:45:19 +02:00
C#: Address review comments.
This commit is contained in:
@@ -1746,3 +1746,28 @@ class SystemNetWebUtilityFlow extends LibraryTypeDataFlow, SystemNetWebUtility {
|
||||
preservesValue = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `StringValues` class used in many .NET Core libraries. Requires special `LibraryTypeDataFlow` flow.
|
||||
*/
|
||||
class StringValues extends Struct {
|
||||
StringValues() { this.hasQualifiedName("Microsoft.Extensions.Primitives", "StringValues") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom flow through StringValues.StringValues library class
|
||||
*/
|
||||
class StringValuesFlow extends LibraryTypeDataFlow, StringValues {
|
||||
override predicate callableFlow(
|
||||
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
|
||||
boolean preservesValue
|
||||
) {
|
||||
c = any(Callable ca | this = ca.getDeclaringType()) and
|
||||
(
|
||||
source = any(CallableFlowSourceArg a) or
|
||||
source = any(CallableFlowSourceQualifier q)
|
||||
) and
|
||||
sink = any(CallableFlowSinkReturn r) and
|
||||
preservesValue = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,8 @@ 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.Primitives
|
||||
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. */
|
||||
@@ -31,9 +29,8 @@ class AspNetQueryStringMember extends Member {
|
||||
t instanceof SystemWebHttpRequestClass or
|
||||
t instanceof SystemNetHttpListenerRequestClass or
|
||||
t instanceof SystemWebHttpRequestBaseClass
|
||||
|
|
||||
this = t.getProperty(getHttpRequestFlowPropertyNames())
|
||||
or
|
||||
|
|
||||
this = t.getProperty(getHttpRequestFlowPropertyNames()) or
|
||||
this.(Field).getType() = t or
|
||||
this.(Property).getType() = t or
|
||||
this.(Callable).getReturnType() = t
|
||||
@@ -64,7 +61,7 @@ class AspNetQueryStringRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow
|
||||
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
|
||||
)
|
||||
@@ -72,39 +69,35 @@ class AspNetQueryStringRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow
|
||||
this.getExpr() = any(AspNetQueryStringMember m).getAnAccess()
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET query string" }
|
||||
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 {
|
||||
class AspNetUnvalidatedQueryStringRemoteFlowSource extends AspNetRemoteFlowSource,
|
||||
DataFlow::ExprNode {
|
||||
AspNetUnvalidatedQueryStringRemoteFlowSource() {
|
||||
this.getExpr() = any(SystemWebUnvalidatedRequestValues c).getAProperty().getGetter().getACall() or
|
||||
this.getExpr() = any(SystemWebUnvalidatedRequestValuesBase c).getAProperty().getGetter().getACall()
|
||||
this.getExpr() = any(SystemWebUnvalidatedRequestValuesBase c)
|
||||
.getAProperty()
|
||||
.getGetter()
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET unvalidated request data" }
|
||||
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
|
||||
}
|
||||
AspNetUserInputRemoteFlowSource() { getType() instanceof SystemWebUIWebControlsTextBoxClass }
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET user input" }
|
||||
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())
|
||||
}
|
||||
WcfRemoteFlowSource() { exists(OperationMethod om | om.getAParameter() = this.getParameter()) }
|
||||
|
||||
override
|
||||
string getSourceType() { result = "web service input" }
|
||||
override string getSourceType() { result = "web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET web service). */
|
||||
@@ -116,8 +109,7 @@ class AspNetServiceRemoteFlowSource extends RemoteFlowSource, DataFlow::Paramete
|
||||
)
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET web service input" }
|
||||
override string getSourceType() { result = "ASP.NET web service input" }
|
||||
}
|
||||
|
||||
/** A data flow source of remote user input (ASP.NET request message). */
|
||||
@@ -126,8 +118,7 @@ class SystemNetHttpRequestMessageRemoteFlowSource extends RemoteFlowSource, Data
|
||||
getType() instanceof SystemWebHttpRequestMessageClass
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET request message" }
|
||||
override string getSourceType() { result = "ASP.NET request message" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,15 +130,15 @@ class MicrosoftOwinStringFlowSource extends RemoteFlowSource, DataFlow::ExprNode
|
||||
this.getExpr() = any(MicrosoftOwinString owinString).getValueProperty().getGetter().getACall()
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "Microsoft Owin request or query string" }
|
||||
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() |
|
||||
this.getExpr() = p.getGetter().getACall()
|
||||
|
|
||||
p = owinRequest.getAcceptProperty() or
|
||||
p = owinRequest.getBodyProperty() or
|
||||
p = owinRequest.getCacheControlProperty() or
|
||||
@@ -168,8 +159,7 @@ class MicrosoftOwinRequestRemoteFlowSource extends RemoteFlowSource, DataFlow::E
|
||||
)
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "Microsoft Owin request" }
|
||||
override string getSourceType() { result = "Microsoft Owin request" }
|
||||
}
|
||||
|
||||
/** A parameter to an Mvc controller action method, viewed as a source of remote user input. */
|
||||
@@ -177,45 +167,42 @@ class ActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode {
|
||||
ActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource() |
|
||||
p = any(Controller c).getAnActionMethod().getAParameter()
|
||||
or
|
||||
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" }
|
||||
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 MicrosoftAspNetCoreHttpHttpRequest or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryCollection or
|
||||
t instanceof MicrosoftAspNetCoreHttpQueryString
|
||||
|
|
||||
this.getExpr().(Call).getTarget().getDeclaringType() = t
|
||||
or
|
||||
|
|
||||
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()
|
||||
.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" }
|
||||
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. */
|
||||
@@ -223,11 +210,11 @@ class AspNetCoreActionMethodParameter extends RemoteFlowSource, DataFlow::Parame
|
||||
AspNetCoreActionMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource() |
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override
|
||||
string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.frameworks.Microsoft
|
||||
|
||||
/** The `Microsoft.AspNetCore` namespace. */
|
||||
class MicrosoftAspNetCoreNamespace extends Namespace {
|
||||
MicrosoftAspNetCoreNamespace() {
|
||||
getParentNamespace() instanceof MicrosoftNamespace and
|
||||
@@ -29,36 +30,28 @@ class MicrosoftAspNetCoreMvcViewFeatures extends Namespace {
|
||||
/** An attribute whose type is in the `Microsoft.AspNetCore.Mvc` namespace. */
|
||||
class MicrosoftAspNetCoreMvcAttribute extends Attribute {
|
||||
MicrosoftAspNetCoreMvcAttribute() {
|
||||
getType().getNamespace() = any(MicrosoftAspNetCoreMvcNamespace mvc)
|
||||
getType().getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace
|
||||
}
|
||||
}
|
||||
|
||||
/** A `Microsoft.AspNetCore.Mvc.HttpPost` attribute. */
|
||||
class MicrosoftAspNetCoreMvcHttpPostAttribute extends MicrosoftAspNetCoreMvcAttribute {
|
||||
MicrosoftAspNetCoreMvcHttpPostAttribute() {
|
||||
getType().hasName("HttpPostAttribute")
|
||||
}
|
||||
MicrosoftAspNetCoreMvcHttpPostAttribute() { getType().hasName("HttpPostAttribute") }
|
||||
}
|
||||
|
||||
/** A `Microsoft.AspNetCore.Mvc.HttpPut`. */
|
||||
/** A `Microsoft.AspNetCore.Mvc.HttpPut` attribute. */
|
||||
class MicrosoftAspNetCoreMvcHttpPutAttribute extends MicrosoftAspNetCoreMvcAttribute {
|
||||
MicrosoftAspNetCoreMvcHttpPutAttribute() {
|
||||
getType().hasName("HttpPutAttribute")
|
||||
}
|
||||
MicrosoftAspNetCoreMvcHttpPutAttribute() { getType().hasName("HttpPutAttribute") }
|
||||
}
|
||||
|
||||
/** A `Microsoft.AspNetCore.Mvc.HttpDelete` attribute. */
|
||||
class MicrosoftAspNetCoreMvcHttpDeleteAttribute extends MicrosoftAspNetCoreMvcAttribute {
|
||||
MicrosoftAspNetCoreMvcHttpDeleteAttribute() {
|
||||
getType().hasName("HttpDeleteAttribute")
|
||||
}
|
||||
MicrosoftAspNetCoreMvcHttpDeleteAttribute() { getType().hasName("HttpDeleteAttribute") }
|
||||
}
|
||||
|
||||
/** A `Microsoft.AspNetCore.Mvc.NonAction` attribute. */
|
||||
class MicrosoftAspNetCoreMvcNonActionAttribute extends MicrosoftAspNetCoreMvcAttribute {
|
||||
MicrosoftAspNetCoreMvcNonActionAttribute() {
|
||||
getType().hasName("NonActionAttribute")
|
||||
}
|
||||
MicrosoftAspNetCoreMvcNonActionAttribute() { getType().hasName("NonActionAttribute") }
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.Antiforgery` namespace. */
|
||||
@@ -85,7 +78,7 @@ class MicrosoftAspNetCoreMvcIFilterMetadataInterface extends Interface {
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.IAuthorizationFilter` interface. */
|
||||
/** The `Microsoft.AspNetCore.IAuthorizationFilter` interface. */
|
||||
class MicrosoftAspNetCoreIAuthorizationFilterInterface extends Interface {
|
||||
MicrosoftAspNetCoreIAuthorizationFilterInterface() {
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
|
||||
@@ -93,9 +86,7 @@ class MicrosoftAspNetCoreIAuthorizationFilterInterface extends Interface {
|
||||
}
|
||||
|
||||
/** Gets the `OnAuthorizationAsync` method. */
|
||||
Method getOnAuthorizationMethod() {
|
||||
result = getAMethod("OnAuthorizationAsync")
|
||||
}
|
||||
Method getOnAuthorizationMethod() { result = getAMethod("OnAuthorizationAsync") }
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.IAntiforgery` interface. */
|
||||
@@ -106,40 +97,30 @@ class MicrosoftAspNetCoreIAntiForgeryInterface extends Interface {
|
||||
}
|
||||
|
||||
/** Gets the `ValidateRequestAsync` method. */
|
||||
Method getValidateMethod() {
|
||||
result = getAMethod("ValidateRequestAsync")
|
||||
}
|
||||
Method getValidateMethod() { result = getAMethod("ValidateRequestAsync") }
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.DefaultAntiForgery` class, or another user-supplied class that implements `IAntiForgery`. */
|
||||
class AntiForgeryClass extends Class {
|
||||
AntiForgeryClass () {
|
||||
getABaseInterface*() instanceof MicrosoftAspNetCoreIAntiForgeryInterface
|
||||
}
|
||||
AntiForgeryClass() { getABaseInterface*() instanceof MicrosoftAspNetCoreIAntiForgeryInterface }
|
||||
|
||||
/** Gets the `ValidateRequestAsync` method. */
|
||||
Method getValidateMethod() {
|
||||
result = getAMethod("ValidateRequestAsync")
|
||||
}
|
||||
Method getValidateMethod() { result = getAMethod("ValidateRequestAsync") }
|
||||
}
|
||||
|
||||
/** Authorization filter class defined by AspNetCore or the user. */
|
||||
/** An authorization filter class defined by AspNetCore or the user. */
|
||||
class AuthorizationFilterClass extends Class {
|
||||
AuthorizationFilterClass() {
|
||||
getABaseInterface*() instanceof MicrosoftAspNetCoreIAuthorizationFilterInterface
|
||||
}
|
||||
|
||||
/** Gets the `OnAuthorization` method provided by this filter. */
|
||||
Method getOnAuthorizationMethod() {
|
||||
result = getAMethod("OnAuthorizationAsync")
|
||||
}
|
||||
Method getOnAuthorizationMethod() { result = getAMethod("OnAuthorizationAsync") }
|
||||
}
|
||||
|
||||
/** An attribute whose type has a name like `[Auto...]Validate[...]Anti[Ff]orgery[...Token]Attribute`. */
|
||||
class ValidateAntiForgeryAttribute extends Attribute {
|
||||
ValidateAntiForgeryAttribute() {
|
||||
getType().getName().matches("%Validate%Anti_orgery%Attribute")
|
||||
}
|
||||
ValidateAntiForgeryAttribute() { getType().getName().matches("%Validate%Anti_orgery%Attribute") }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,7 +129,7 @@ class ValidateAntiForgeryAttribute extends Attribute {
|
||||
*/
|
||||
class ValidateAntiforgeryTokenAuthorizationFilter extends Class {
|
||||
ValidateAntiforgeryTokenAuthorizationFilter() {
|
||||
getABaseInterface*() instanceof MicrosoftAspNetCoreMvcIFilterMetadataInterface and
|
||||
getABaseInterface*() instanceof MicrosoftAspNetCoreMvcIFilterMetadataInterface and
|
||||
getName().matches("%Validate%Anti_orgery%")
|
||||
}
|
||||
}
|
||||
@@ -156,7 +137,7 @@ class ValidateAntiforgeryTokenAuthorizationFilter extends Class {
|
||||
/** The `Microsoft.AspNetCore.Mvc.Filters.FilterCollection` class. */
|
||||
class MicrosoftAspNetCoreMvcFilterCollection extends Class {
|
||||
MicrosoftAspNetCoreMvcFilterCollection() {
|
||||
getNamespace() = any(MicrosoftAspNetCoreMvcFilters h) and
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
|
||||
hasName("FilterCollection")
|
||||
}
|
||||
|
||||
@@ -170,22 +151,20 @@ class MicrosoftAspNetCoreMvcFilterCollection extends Class {
|
||||
/** The `Microsoft.AspNetCore.Mvc.MvcOptions` class. */
|
||||
class MicrosoftAspNetCoreMvcOptions extends Class {
|
||||
MicrosoftAspNetCoreMvcOptions() {
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
|
||||
hasName("MvcOptions")
|
||||
}
|
||||
|
||||
/** Gets the `Filters` property. */
|
||||
Property getFilterCollectionProperty() {
|
||||
result = getProperty("Filters")
|
||||
}
|
||||
Property getFilterCollectionProperty() { result = getProperty("Filters") }
|
||||
}
|
||||
|
||||
/** The base class for controllers in MVC, i.e. `Microsoft.AspNetCore.Mvc.Controller` or `Microsoft.AspNetCore.Mvc.ControllerBase` class. */
|
||||
class MicrosoftAspNetCoreMvcControllerBaseClass extends Class {
|
||||
MicrosoftAspNetCoreMvcControllerBaseClass() {
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and (
|
||||
hasName("Controller")
|
||||
or
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
|
||||
(
|
||||
hasName("Controller") or
|
||||
hasName("ControllerBase")
|
||||
)
|
||||
}
|
||||
@@ -199,137 +178,102 @@ class MicrosoftAspNetCoreMvcController extends Class {
|
||||
|
||||
/** Gets an action method for this controller. */
|
||||
Method getAnActionMethod() {
|
||||
result = getAMethod() and
|
||||
result.isPublic() and
|
||||
not result.isStatic() and
|
||||
not result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcNonActionAttribute
|
||||
result = getAMethod() and
|
||||
result.isPublic() and
|
||||
not result.isStatic() and
|
||||
not result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcNonActionAttribute
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an "action" method handling POST, PUT and DELETE request, which may be called by the MVC framework in response to a user
|
||||
* request.
|
||||
*/
|
||||
Method getAnActionModifyingMethod() {
|
||||
result = getAnActionMethod() and (
|
||||
result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpPostAttribute
|
||||
or
|
||||
result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpPutAttribute
|
||||
or
|
||||
result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpDeleteAttribute
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a `Redirect*` method. */
|
||||
Method getARedirectMethod() {
|
||||
result = this.getAMethod() and
|
||||
result.getName().matches("Redirect%")
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets a string corresponding to the HTTP method used in the action method. */
|
||||
string httpMethodType(Method m) {
|
||||
m.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpPostAttribute and result = "POST" or
|
||||
m.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpPutAttribute and result = "PUT" or
|
||||
m.getAnAttribute() instanceof MicrosoftAspNetCoreMvcHttpDeleteAttribute and result = "DELETE"
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper` class. */
|
||||
class MicrosoftAspNetCoreMvcHtmlHelperClass extends Class {
|
||||
MicrosoftAspNetCoreMvcHtmlHelperClass() {
|
||||
getNamespace() = any(MicrosoftAspNetCoreMvcViewFeatures mvc) and
|
||||
getNamespace() instanceof MicrosoftAspNetCoreMvcViewFeatures and
|
||||
hasName("HtmlHelper")
|
||||
}
|
||||
|
||||
/** Gets the `Raw` method. */
|
||||
Method getRawMethod() {
|
||||
result = getAMethod("Raw")
|
||||
}
|
||||
Method getRawMethod() { result = getAMethod("Raw") }
|
||||
}
|
||||
|
||||
/** Class deriving from `Microsoft.AspNetCore.Mvc.Razor.RazorPageBase`, implements Razor page in ASPNET Core. */
|
||||
/** A class deriving from `Microsoft.AspNetCore.Mvc.Razor.RazorPageBase`, implements Razor page in ASPNET Core. */
|
||||
class MicrosoftAspNetCoreMvcRazorPageBase extends Class {
|
||||
MicrosoftAspNetCoreMvcRazorPageBase () {
|
||||
MicrosoftAspNetCoreMvcRazorPageBase() {
|
||||
this.getABaseType*().hasQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorPageBase")
|
||||
}
|
||||
|
||||
/** Gets the `WriteLiteral` method. */
|
||||
Method getWriteLiteralMethod() {
|
||||
result = getAMethod("WriteLiteral")
|
||||
}
|
||||
Method getWriteLiteralMethod() { result = getAMethod("WriteLiteral") }
|
||||
}
|
||||
|
||||
/** Class deriving from `Microsoft.AspNetCore.Http.HttpRequest`, implements `HttpRequest` in ASP.NET Core. */
|
||||
/** A class deriving from `Microsoft.AspNetCore.Http.HttpRequest`, implements `HttpRequest` in ASP.NET Core. */
|
||||
class MicrosoftAspNetCoreHttpHttpRequest extends Class {
|
||||
MicrosoftAspNetCoreHttpHttpRequest() {
|
||||
this.getABaseType*().hasQualifiedName("Microsoft.AspNetCore.Http", "HttpRequest")
|
||||
}
|
||||
}
|
||||
|
||||
/** Class deriving from `Microsoft.AspNetCore.Http.HttpResponse`, implements `HttpResponse` in ASP.NET Core. */
|
||||
/** A class deriving from `Microsoft.AspNetCore.Http.HttpResponse`, implements `HttpResponse` in ASP.NET Core. */
|
||||
class MicrosoftAspNetCoreHttpHttpResponse extends Class {
|
||||
MicrosoftAspNetCoreHttpHttpResponse() {
|
||||
this.getABaseType*().hasQualifiedName("Microsoft.AspNetCore.Http", "HttpResponse")
|
||||
}
|
||||
|
||||
/** Gets the `Redirect` method. */
|
||||
Method getRedirectMethod() {
|
||||
result = this.getAMethod("Redirect")
|
||||
}
|
||||
Method getRedirectMethod() { result = this.getAMethod("Redirect") }
|
||||
|
||||
/** Gets the `Headers` property. */
|
||||
Property getHeadersProperty() {
|
||||
result = this.getProperty("Headers")
|
||||
}
|
||||
Property getHeadersProperty() { result = this.getProperty("Headers") }
|
||||
}
|
||||
|
||||
/** Class is a wrapper around the collection of cookies in the response. */
|
||||
class MicrosoftAspNetCoreHttpResponseCookies extends Interface{
|
||||
/** An interface that is a wrapper around the collection of cookies in the response. */
|
||||
class MicrosoftAspNetCoreHttpResponseCookies extends Interface {
|
||||
MicrosoftAspNetCoreHttpResponseCookies() {
|
||||
this.hasQualifiedName("Microsoft.AspNetCore.Http.IResponseCookies")
|
||||
}
|
||||
|
||||
/** Gets the `Append` method. */
|
||||
Method getAppendMethod() {
|
||||
result = this.getAMethod("Append")
|
||||
}
|
||||
Method getAppendMethod() { result = this.getAMethod("Append") }
|
||||
}
|
||||
|
||||
/** Class `Microsoft.AspNetCore.Http.QueryString`, holds query string in ASP.NET Core. */
|
||||
/** The class `Microsoft.AspNetCore.Http.QueryString`, holds query string in ASP.NET Core. */
|
||||
class MicrosoftAspNetCoreHttpQueryString extends Struct {
|
||||
MicrosoftAspNetCoreHttpQueryString() {
|
||||
this.hasQualifiedName("Microsoft.AspNetCore.Http", "QueryString")
|
||||
}
|
||||
}
|
||||
|
||||
/** Class implementing `IQueryCollection`, holds parsed query string in ASP.NET Core. */
|
||||
|
||||
/** A class or interface implementing `IQueryCollection`, holds parsed query string in ASP.NET Core. */
|
||||
class MicrosoftAspNetCoreHttpQueryCollection extends RefType {
|
||||
MicrosoftAspNetCoreHttpQueryCollection() {
|
||||
this.getABaseInterface().hasQualifiedName("Microsoft.AspNetCore.Http", "IQueryCollection")
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper class for setting headers. */
|
||||
/** The helper class `ResponseHeaders` for setting headers. */
|
||||
class MicrosoftAspNetCoreHttpResponseHeaders extends RefType {
|
||||
MicrosoftAspNetCoreHttpResponseHeaders() {
|
||||
this.hasQualifiedName("Microsoft.AspNetCore.Http.Headers", "ResponseHeaders")
|
||||
}
|
||||
|
||||
/** Gets the `Location` property. */
|
||||
Property getLocationProperty() {
|
||||
result = this.getProperty("Location")
|
||||
}
|
||||
Property getLocationProperty() { result = this.getProperty("Location") }
|
||||
}
|
||||
|
||||
/** The `Microsoft.AspNetCore.Http.HeaderDictionaryExtensions` class. */
|
||||
class MicrosoftAspNetCoreHttpHeaderDictionaryExtensions extends RefType {
|
||||
MicrosoftAspNetCoreHttpHeaderDictionaryExtensions () {
|
||||
MicrosoftAspNetCoreHttpHeaderDictionaryExtensions() {
|
||||
this.hasQualifiedName("Microsoft.AspNetCore.Http", "HeaderDictionaryExtensions")
|
||||
}
|
||||
|
||||
/** Gets the `Append` extension method. */
|
||||
Method getAppendMethod() {
|
||||
result = this.getAMethod("Append")
|
||||
}
|
||||
Method getAppendMethod() { result = this.getAMethod("Append") }
|
||||
|
||||
/** Gets the `AppendCommaSeparatedValues` extension method. */
|
||||
Method getAppendCommaSeparatedValuesMethod() {
|
||||
@@ -337,9 +281,7 @@ class MicrosoftAspNetCoreHttpHeaderDictionaryExtensions extends RefType {
|
||||
}
|
||||
|
||||
/** Gets the `SetCommaSeparatedValues` extension method. */
|
||||
Method getSetCommaSeparatedValuesMethod() {
|
||||
result = this.getAMethod("SetCommaSeparatedValues")
|
||||
}
|
||||
Method getSetCommaSeparatedValuesMethod() { result = this.getAMethod("SetCommaSeparatedValues") }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Provides definitions for working with classes in Microsoft.Extensions.Primitives namespace
|
||||
*/
|
||||
import csharp
|
||||
|
||||
module ExtensionPrimitives {
|
||||
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
|
||||
|
||||
/**
|
||||
* StringValues class used in many .Net Core libraries. Requreres special LibraryTypeDataFlow flow.
|
||||
*/
|
||||
class StringValues extends Struct {
|
||||
StringValues() {
|
||||
this.hasQualifiedName("Microsoft.Extensions.Primitives", "StringValues")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom flow through StringValues.StringValues library class
|
||||
*/
|
||||
class StringValuesFlow extends LibraryTypeDataFlow, StringValues {
|
||||
override predicate callableFlow(CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c, boolean preservesValue) {
|
||||
c = any(Callable ca | this = ca.getDeclaringType())
|
||||
and
|
||||
(source = any(CallableFlowSourceArg a) or
|
||||
source = any(CallableFlowSourceQualifier q))
|
||||
and
|
||||
sink = any(CallableFlowSinkReturn r)
|
||||
and preservesValue = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,10 +181,10 @@ module UrlRedirect {
|
||||
class AspNetCoreLocationHeaderSink extends Sink {
|
||||
AspNetCoreLocationHeaderSink () {
|
||||
// ResponseHeaders.Location = <user-provided value>
|
||||
exists(Assignment propAssign, PropertyAccess pa |
|
||||
pa.getTarget() = any(MicrosoftAspNetCoreHttpResponseHeaders headers).getLocationProperty() and
|
||||
pa = propAssign.getLValue() and
|
||||
this.asExpr() = propAssign.getRValue())
|
||||
exists(AssignableDefinition def |
|
||||
def.getTarget() = any(MicrosoftAspNetCoreHttpResponseHeaders headers).getLocationProperty() |
|
||||
this.asExpr() = def.getSource()
|
||||
)
|
||||
or // HttpResponse.Headers.Append("location", <user-provided value>)
|
||||
exists(MethodCall mc, MicrosoftAspNetCoreHttpHeaderDictionaryExtensions ext |
|
||||
mc.getTarget() = ext.getAppendMethod() or
|
||||
@@ -193,17 +193,17 @@ module UrlRedirect {
|
||||
mc.getArgumentForName("key").getValue().toLowerCase() = "location" and
|
||||
this.getExpr() = mc.getArgument(2))
|
||||
or // HttpResponse.Headers.Add("location", <user-provided value>)
|
||||
exists(RefType cl, MicrosoftAspNetCoreHttpHttpResponse resp, PropertyAccess c, MethodCall add |
|
||||
c.getTarget() = resp.getHeadersProperty() and
|
||||
exists(RefType cl, MicrosoftAspNetCoreHttpHttpResponse resp, PropertyAccess qualifier, MethodCall add |
|
||||
qualifier.getTarget() = resp.getHeadersProperty() and
|
||||
add.getTarget() = cl.getAMethod("Add") and
|
||||
c = add.getQualifier() and
|
||||
qualifier = add.getQualifier() and
|
||||
add.getArgument(0).getValue().toLowerCase() = "location" and
|
||||
this.getExpr() = add.getArgument(1))
|
||||
or // HttpResponse.Headers["location"] = <user-provided value>
|
||||
exists(RefType cl, MicrosoftAspNetCoreHttpHttpResponse resp, IndexerAccess ci, Call cs, PropertyAccess pa |
|
||||
pa.getTarget() = resp.getHeadersProperty() and
|
||||
exists(RefType cl, MicrosoftAspNetCoreHttpHttpResponse resp, IndexerAccess ci, Call cs, PropertyAccess qualifier |
|
||||
qualifier.getTarget() = resp.getHeadersProperty() and
|
||||
ci.getTarget() = cl.getAnIndexer() and
|
||||
pa = ci.getQualifier() and
|
||||
qualifier = ci.getQualifier() and
|
||||
cs.getTarget() = cl.getAnIndexer().getSetter() and
|
||||
cs.getArgument(0).getValue().toLowerCase() = "location" and
|
||||
this.asExpr() = cs.getArgument(1))
|
||||
|
||||
@@ -6,6 +6,7 @@ import csharp
|
||||
|
||||
module XSS {
|
||||
import semmle.code.csharp.dataflow.flowsources.Remote
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
import semmle.code.csharp.frameworks.system.Net
|
||||
import semmle.code.csharp.frameworks.system.Web
|
||||
import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
@@ -15,7 +16,6 @@ module XSS {
|
||||
import semmle.code.csharp.frameworks.system.windows.Forms
|
||||
import semmle.code.csharp.security.Sanitizers
|
||||
import semmle.code.asp.AspNet
|
||||
import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
|
||||
/**
|
||||
* Holds if there is tainted flow from `source` to `sink` that may lead to a
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace ASP
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
// using System.Web.UI;
|
||||
using System.Web.WebPages;
|
||||
|
||||
public class _Page_Views_Home_Contact_cshtml : System.Web.Mvc.WebViewPage<dynamic>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| XSS.cs:28:30:28:34 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteral() method. | XSS.cs:21:25:21:43 | access to property QueryString | User-provided value |
|
||||
| XSS.cs:38:40:38:44 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteralTo() method. | XSS.cs:21:25:21:43 | access to property QueryString | User-provided value |
|
||||
| XSS.cs:45:28:45:55 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:45:28:45:46 | access to property QueryString | User-provided value |
|
||||
| XSS.cs:27:30:27:34 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteral() method. | XSS.cs:20:25:20:43 | access to property QueryString | User-provided value |
|
||||
| XSS.cs:37:40:37:44 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteralTo() method. | XSS.cs:20:25:20:43 | access to property QueryString | User-provided value |
|
||||
| XSS.cs:44:28:44:55 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:44:28:44:46 | access to property QueryString | User-provided value |
|
||||
|
||||
Reference in New Issue
Block a user