C#: Address review comments.

This commit is contained in:
calum
2018-11-02 13:56:01 +00:00
parent 13f0a401f3
commit ae96b347e2
8 changed files with 122 additions and 201 deletions

View File

@@ -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
}
}

View File

@@ -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" }
}

View File

@@ -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") }
}
/**

View File

@@ -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
}
}
}

View File

@@ -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))

View File

@@ -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

View File

@@ -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>

View File

@@ -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 |