Merge pull request #359 from calumgrant/cs/with-stubs

C#: Sources and sinks for ASP.NET Core
This commit is contained in:
Tom Hvitved
2018-11-05 11:46:02 +01:00
committed by GitHub
28 changed files with 1357 additions and 46 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,6 +11,7 @@ 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 {
@@ -28,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
@@ -61,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
)
@@ -69,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). */
@@ -113,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). */
@@ -123,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" }
}
/**
@@ -136,17 +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`).
*/
/** 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
@@ -167,23 +159,62 @@ 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.
*/
/** 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.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 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" }
}

View File

@@ -0,0 +1,295 @@
/** Provides classes for working with `Microsoft.AspNetCore.Mvc`. */
import csharp
import semmle.code.csharp.frameworks.Microsoft
/** The `Microsoft.AspNetCore` namespace. */
class MicrosoftAspNetCoreNamespace extends Namespace {
MicrosoftAspNetCoreNamespace() {
getParentNamespace() instanceof MicrosoftNamespace and
hasName("AspNetCore")
}
}
/** The `Microsoft.AspNetCore.Mvc` namespace. */
class MicrosoftAspNetCoreMvcNamespace extends Namespace {
MicrosoftAspNetCoreMvcNamespace() {
getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
hasName("Mvc")
}
}
/** The 'Microsoft.AspNetCore.Mvc.ViewFeatures' namespace. */
class MicrosoftAspNetCoreMvcViewFeatures extends Namespace {
MicrosoftAspNetCoreMvcViewFeatures() {
getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
hasName("ViewFeatures")
}
}
/** An attribute whose type is in the `Microsoft.AspNetCore.Mvc` namespace. */
class MicrosoftAspNetCoreMvcAttribute extends Attribute {
MicrosoftAspNetCoreMvcAttribute() {
getType().getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace
}
}
/** A `Microsoft.AspNetCore.Mvc.HttpPost` attribute. */
class MicrosoftAspNetCoreMvcHttpPostAttribute extends MicrosoftAspNetCoreMvcAttribute {
MicrosoftAspNetCoreMvcHttpPostAttribute() { getType().hasName("HttpPostAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.HttpPut` attribute. */
class MicrosoftAspNetCoreMvcHttpPutAttribute extends MicrosoftAspNetCoreMvcAttribute {
MicrosoftAspNetCoreMvcHttpPutAttribute() { getType().hasName("HttpPutAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.HttpDelete` attribute. */
class MicrosoftAspNetCoreMvcHttpDeleteAttribute extends MicrosoftAspNetCoreMvcAttribute {
MicrosoftAspNetCoreMvcHttpDeleteAttribute() { getType().hasName("HttpDeleteAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.NonAction` attribute. */
class MicrosoftAspNetCoreMvcNonActionAttribute extends MicrosoftAspNetCoreMvcAttribute {
MicrosoftAspNetCoreMvcNonActionAttribute() { getType().hasName("NonActionAttribute") }
}
/** The `Microsoft.AspNetCore.Antiforgery` namespace. */
class MicrosoftAspNetCoreAntiforgeryNamespace extends Namespace {
MicrosoftAspNetCoreAntiforgeryNamespace() {
getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
hasName("Antiforgery")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters` namespace. */
class MicrosoftAspNetCoreMvcFilters extends Namespace {
MicrosoftAspNetCoreMvcFilters() {
getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
hasName("Filters")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters.IFilterMetadataInterface` interface. */
class MicrosoftAspNetCoreMvcIFilterMetadataInterface extends Interface {
MicrosoftAspNetCoreMvcIFilterMetadataInterface() {
getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
hasName("IFilterMetadata")
}
}
/** The `Microsoft.AspNetCore.IAuthorizationFilter` interface. */
class MicrosoftAspNetCoreIAuthorizationFilterInterface extends Interface {
MicrosoftAspNetCoreIAuthorizationFilterInterface() {
getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
hasName("IAsyncAuthorizationFilter")
}
/** Gets the `OnAuthorizationAsync` method. */
Method getOnAuthorizationMethod() { result = getAMethod("OnAuthorizationAsync") }
}
/** The `Microsoft.AspNetCore.IAntiforgery` interface. */
class MicrosoftAspNetCoreIAntiForgeryInterface extends Interface {
MicrosoftAspNetCoreIAntiForgeryInterface() {
getNamespace() instanceof MicrosoftAspNetCoreAntiforgeryNamespace and
hasName("IAntiforgery")
}
/** Gets the `ValidateRequestAsync` method. */
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 }
/** Gets the `ValidateRequestAsync` method. */
Method getValidateMethod() { result = getAMethod("ValidateRequestAsync") }
}
/** 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") }
}
/** 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") }
}
/**
* A class that has a name like `[Auto...]Validate[...]Anti[Ff]orgery[...Token]` and implements `IFilterMetadata` interface
* This class can be added to a collection of global `MvcOptions.Filters` collection.
*/
class ValidateAntiforgeryTokenAuthorizationFilter extends Class {
ValidateAntiforgeryTokenAuthorizationFilter() {
getABaseInterface*() instanceof MicrosoftAspNetCoreMvcIFilterMetadataInterface and
getName().matches("%Validate%Anti_orgery%")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters.FilterCollection` class. */
class MicrosoftAspNetCoreMvcFilterCollection extends Class {
MicrosoftAspNetCoreMvcFilterCollection() {
getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
hasName("FilterCollection")
}
/** Gets an `Add` method. */
Method getAddMethod() {
result = getAMethod("Add") or
result = getABaseType().getAMethod("Add")
}
}
/** The `Microsoft.AspNetCore.Mvc.MvcOptions` class. */
class MicrosoftAspNetCoreMvcOptions extends Class {
MicrosoftAspNetCoreMvcOptions() {
getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
hasName("MvcOptions")
}
/** Gets the `Filters` property. */
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
hasName("ControllerBase")
)
}
}
/** A subtype of `Microsoft.AspNetCore.Mvc.Controller` or `Microsoft.AspNetCore.Mvc.ControllerBase`. */
class MicrosoftAspNetCoreMvcController extends Class {
MicrosoftAspNetCoreMvcController() {
getABaseType*() instanceof MicrosoftAspNetCoreMvcControllerBaseClass
}
/** Gets an action method for this controller. */
Method getAnActionMethod() {
result = getAMethod() and
result.isPublic() and
not result.isStatic() and
not result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcNonActionAttribute
}
/** Gets a `Redirect*` method. */
Method getARedirectMethod() {
result = this.getAMethod() and
result.getName().matches("Redirect%")
}
}
/** The `Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper` class. */
class MicrosoftAspNetCoreMvcHtmlHelperClass extends Class {
MicrosoftAspNetCoreMvcHtmlHelperClass() {
getNamespace() instanceof MicrosoftAspNetCoreMvcViewFeatures and
hasName("HtmlHelper")
}
/** Gets the `Raw` method. */
Method getRawMethod() { result = getAMethod("Raw") }
}
/** A class deriving from `Microsoft.AspNetCore.Mvc.Razor.RazorPageBase`, implements Razor page in ASPNET Core. */
class MicrosoftAspNetCoreMvcRazorPageBase extends Class {
MicrosoftAspNetCoreMvcRazorPageBase() {
this.getABaseType*().hasQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorPageBase")
}
/** Gets the `WriteLiteral` method. */
Method getWriteLiteralMethod() { result = getAMethod("WriteLiteral") }
}
/** 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")
}
}
/** 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") }
/** Gets the `Headers` property. */
Property getHeadersProperty() { result = this.getProperty("Headers") }
}
/** 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") }
}
/** The class `Microsoft.AspNetCore.Http.QueryString`, holds query string in ASP.NET Core. */
class MicrosoftAspNetCoreHttpQueryString extends Struct {
MicrosoftAspNetCoreHttpQueryString() {
this.hasQualifiedName("Microsoft.AspNetCore.Http", "QueryString")
}
}
/** 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")
}
}
/** 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") }
}
/** The `Microsoft.AspNetCore.Http.HeaderDictionaryExtensions` class. */
class MicrosoftAspNetCoreHttpHeaderDictionaryExtensions extends RefType {
MicrosoftAspNetCoreHttpHeaderDictionaryExtensions() {
this.hasQualifiedName("Microsoft.AspNetCore.Http", "HeaderDictionaryExtensions")
}
/** Gets the `Append` extension method. */
Method getAppendMethod() { result = this.getAMethod("Append") }
/** Gets the `AppendCommaSeparatedValues` extension method. */
Method getAppendCommaSeparatedValuesMethod() {
result = this.getAMethod("AppendCommaSeparatedValues")
}
/** Gets the `SetCommaSeparatedValues` extension method. */
Method getSetCommaSeparatedValuesMethod() { result = this.getAMethod("SetCommaSeparatedValues") }
}
/**
* The `Microsoft.AspNetCore.Html.HtmlString` class, supposed to wrap HTML-encoded string in ASP.NET Core
* Untrusted and unsanitized data should never flow there.
*/
class MicrosoftAspNetCoreHttpHtmlString extends Class {
MicrosoftAspNetCoreHttpHtmlString() {
this.hasQualifiedName("Microsoft.AspNetCore.Html", "HtmlString")
}
}

View File

@@ -0,0 +1,37 @@
/** Definitions related to the namespace `System.Web.WebPages`, ASP.NET */
import csharp
private import semmle.code.csharp.frameworks.system.Web
/** The `System.Web.WebPages` namespace. */
class SystemWebWebPagesNamespace extends Namespace {
SystemWebWebPagesNamespace() {
getParentNamespace() instanceof SystemWebNamespace and
hasName("WebPages")
}
}
/** The `System.Web.WebPages.WebPageExecutingBase` class. */
class SystemWebWebPagesWebPageExecutingBaseClass extends Class {
SystemWebWebPagesWebPageExecutingBaseClass() {
getNamespace() instanceof SystemWebWebPagesNamespace and
hasName("WebPageExecutingBase")
}
}
/** A class that derives from `System.Web.WebPages.WebPageExecutingBase`. */
class WebPageClass extends Class {
WebPageClass () {
this.getBaseClass*() instanceof SystemWebWebPagesWebPageExecutingBaseClass
}
/** Gets the `WriteLiteral` method. */
Method getWriteLiteralMethod() {
result = getAMethod("WriteLiteral")
}
/** Gets the `WriteLiteralTo` method. */
Method getWriteLiteralToMethod() {
result = getAMethod("WriteLiteralTo")
}
}

View File

@@ -9,6 +9,7 @@ module UrlRedirect {
import semmle.code.csharp.frameworks.system.Web
import semmle.code.csharp.frameworks.system.web.Mvc
import semmle.code.csharp.security.Sanitizers
import semmle.code.csharp.frameworks.microsoft.AspNetCore
/**
* A data flow source for unvalidated URL redirect vulnerabilities.
@@ -149,4 +150,65 @@ module UrlRedirect {
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }
private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { }
/**
* A URL argument to a call to `HttpResponse.Redirect()` or `Controller.Redirect()`, that is a
* sink for URL redirects.
*/
class AspNetCoreRedirectSink extends Sink {
AspNetCoreRedirectSink() {
exists(MethodCall mc |
mc.getTarget() = any(MicrosoftAspNetCoreHttpHttpResponse response).getRedirectMethod() or
mc.getTarget() = any(MicrosoftAspNetCoreMvcController response).getARedirectMethod()
|
// Response.Redirect uses 'location' parameter
this.getExpr() = mc.getArgumentForName("location") or
// Redirect uses the parameter name 'url'
this.getExpr() = mc.getArgumentForName("url") or
// Controller.RedirectToAction*
this.getExpr() = mc.getArgumentForName("actionName") or
// Controller.RedirectToRoute*
this.getExpr() = mc.getArgumentForName("routeName") or
// Controller.RedirectToPage*
this.getExpr() = mc.getArgumentForName("pageName")
)
}
}
/**
* Anything that is setting "location" header in the response headers.
*/
class AspNetCoreLocationHeaderSink extends Sink {
AspNetCoreLocationHeaderSink () {
// ResponseHeaders.Location = <user-provided value>
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
mc.getTarget() = ext.getAppendCommaSeparatedValuesMethod() or
mc.getTarget() = ext.getSetCommaSeparatedValuesMethod() |
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 qualifier, MethodCall add |
qualifier.getTarget() = resp.getHeadersProperty() and
add.getTarget() = cl.getAMethod("Add") 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 qualifier |
qualifier.getTarget() = resp.getHeadersProperty() and
ci.getTarget() = cl.getAnIndexer() 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,9 +6,11 @@ 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
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
@@ -514,6 +516,75 @@ module XSS {
this.getExpr() = any(ObjectCreation oc | oc.getTarget().getDeclaringType().hasQualifiedName("System.Net.Http", "StringContent")).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) {

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: /r:${testdir}/../../../resources/assemblies/System.Data.dll /r:${testdir}/../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../resources/assemblies/System.Web.Mvc.dll /r:System.ComponentModel.Primitives.dll /r:System.Collections.Specialized.dll /r:${testdir}/../../../resources/assemblies/System.Net.Http.dll
// semmle-extractor-options: /r:${testdir}/../../../../resources/assemblies/System.Data.dll /r:${testdir}/../../../../resources/assemblies/System.Web.dll /r:${testdir}/../../../../resources/assemblies/System.Web.Mvc.dll /r:System.ComponentModel.Primitives.dll /r:System.Collections.Specialized.dll /r:${testdir}/../../../../resources/assemblies/System.Net.Http.dll
using System;
using System.Data.SqlClient;

View File

@@ -0,0 +1,10 @@
| XSSAspNet.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. | XSSAspNet.cs:20:25:20:43 | access to property QueryString | User-provided value |
| XSSAspNet.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. | XSSAspNet.cs:20:25:20:43 | access to property QueryString | User-provided value |
| XSSAspNet.cs:44:28:44:55 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSSAspNet.cs:44:28:44:46 | access to property QueryString | User-provided value |
| XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:21:52:21:64 | access to property Query | User-provided value |
| XSSAspNetCore.cs:44:51:44:53 | access to parameter foo | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:40:56:40:58 | foo | User-provided value |
| XSSAspNetCore.cs:51:43:51:67 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:51:43:51:67 | access to property Value | User-provided value |
| XSSAspNetCore.cs:58:43:58:73 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:58:43:58:55 | access to property Query | User-provided value |
| XSSAspNetCore.cs:61:44:61:66 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:61:44:61:56 | access to property Query | User-provided value |
| XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | User-provided value |
| XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:72:51:72:65 | access to property Headers | User-provided value |

View File

@@ -0,0 +1 @@
Security Features/CWE-079/XSS.ql

View File

@@ -0,0 +1,51 @@
// semmle-extractor-options: /r:System.Dynamic.Runtime.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Expressions.dll
namespace ASP
{
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Web.WebPages;
public class _Page_Views_Home_Contact_cshtml : System.Web.Mvc.WebViewPage<dynamic>
{
public _Page_Views_Home_Contact_cshtml()
{
}
public override void Execute()
{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "Contact";
var sayHi = Request.QueryString["sayHi"];
if (sayHi.IsEmpty())
{
WriteLiteral("<script>alert(\"XSS via WriteLiteral\")</script>"); // GOOD: hard-coded, not user input
}
else
{
WriteLiteral(sayHi); // BAD: user input flows to HTML unencoded
WriteLiteral(HttpUtility.HtmlEncode(sayHi)); // Good: user input is encoded before it flows to HTML
}
if (sayHi.IsEmpty())
{
WriteLiteralTo(Output, "<script > alert(\"XSS via WriteLiteralTo\")</script>"); // GOOD: hard-coded, not user input
}
else
{
WriteLiteralTo(Output, sayHi); // BAD: user input flows to HTML unencoded
WriteLiteralTo(Output, Html.Encode(sayHi)); // Good: user input is encoded before it flows to HTML
}
BeginContext("~/Views/Home/Contact.cshtml", 288, 32, false);
Write(Html.Raw("<script>alert(\"XSS via Html.Raw()\")</script>")); // GOOD: hard-coded, not user input
Write(Html.Raw(Request.QueryString["sayHi"])); // BAD: user input flows to HTML unencoded
Write(Html.Raw(HttpContext.Current.Server.HtmlEncode(Request.QueryString["sayHi"]))); // Good: user input is encoded before it flows to HTML
EndContext("~/Views/Home/Contact.cshtml", 288, 32, false);
}
}
}
// source-extractor-options: /r:${testdir}/../../../../../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.WebPages.dll /r:${testdir}/../../../../../packages/Microsoft.AspNet.Mvc.5.2.3/lib/net45/System.Web.Mvc.dll /r:System.Dynamic.Runtime.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Expressions.dll /r:System.Web.dll /r:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Web.dll /r:System.Collections.Specialized.dll

View File

@@ -0,0 +1,79 @@
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Html;
using Microsoft.Extensions.Primitives;
namespace Testing.Controllers
{
public class HomeViewModel
{
public string Message { get; set; }
public HtmlString Description { get; set; }
}
public class TestController : Controller
{
public IActionResult Index()
{
// BAD: flow of content type to.
var v = new ViewResult();
v.ViewData["BadData"] = new HtmlString(Request.Query["Bad data"]);
StringValues vOut;
Request.Query.TryGetValue("Foo", out vOut);
// BAD: via Enumerable. (false negative)
v.ViewData["FooFirst"] = new HtmlString(vOut.First());
// BAD: via toArray. (false negative)
v.ViewData["FooArray0"] = new HtmlString(vOut.ToArray()[0]);
// BAD: via implicit conversion operator. (false negative)
v.ViewData["FooImplicit"] = new HtmlString(vOut);
return v;
}
[HttpPost("Test")]
[ValidateAntiForgeryToken]
public IActionResult Submit([FromQuery] string foo)
{
var view = new ViewResult();
//BAD: flow of submitted value to view in HtmlString.
view.ViewData["FOO"] = new HtmlString(foo);
return view;
}
public IActionResult IndexToModel()
{
//BAD: flow of submitted value to view in HtmlString.
HtmlString v = new HtmlString(Request.QueryString.Value);
return View(new HomeViewModel() { Message = "Message from Index", Description = v });
}
public IActionResult About()
{
//BAD: flow of submitted value to view in HtmlString.
HtmlString v = new HtmlString(Request.Query["Foo"].ToString());
//BAD: flow of submitted value to view in HtmlString.
HtmlString v1 = new HtmlString(Request.Query["Foo"][0]);
return View(new HomeViewModel() { Message = "Message from About", Description = v });
}
public IActionResult Contact()
{
//BAD: flow of user content type to view in HtmlString.
HtmlString v = new HtmlString(Request.ContentType);
//BAD: flow of headers to view in HtmlString.
HtmlString v1 = new HtmlString(value: Request.Headers["Foo"]);
return View(new HomeViewModel() { Message = "Message from Contact", Description = v });
}
}
}
// initial-extractor-options: /r:netstandard.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.Core.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.Core.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Antiforgery.1.1.2/lib/net451/Microsoft.AspNetCore.Antiforgery.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.ViewFeatures.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.ViewFeatures.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.Abstractions.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.Abstractions.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Http.Abstractions.1.1.2\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Html.Abstractions.1.1.2/lib/netstandard1.0/Microsoft.AspNetCore.Html.Abstractions.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Http.Features.1.1.2\lib\net451\Microsoft.AspNetCore.Http.Features.dll /r:${testdir}/../../../../../packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll /r:System.Linq.dll /r:System.Linq.Expressions.dll /r:System.Linq.Queryable.dll

View File

@@ -0,0 +1,236 @@
namespace Microsoft
{
namespace AspNetCore
{
namespace Html
{
// Generated from `Microsoft.AspNetCore.Html.HtmlString` in `Microsoft.AspNetCore.Html.Abstractions, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class HtmlString : Microsoft.AspNetCore.Html.IHtmlContent
{
public HtmlString(string value) => throw null;
public override string ToString() => throw null;
}
// Generated from `Microsoft.AspNetCore.Html.IHtmlContent` in `Microsoft.AspNetCore.Html.Abstractions, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IHtmlContent
{
}
}
namespace Http
{
// Generated from `Microsoft.AspNetCore.Http.HttpRequest` in `Microsoft.AspNetCore.Http.Abstractions, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class HttpRequest
{
public abstract Microsoft.AspNetCore.Http.IHeaderDictionary Headers { get; }
public abstract Microsoft.AspNetCore.Http.IQueryCollection Query { get; set; }
public abstract Microsoft.AspNetCore.Http.QueryString QueryString { get; set; }
public abstract string ContentType { get; set; }
}
// Generated from `Microsoft.AspNetCore.Http.IHeaderDictionary` in `Microsoft.AspNetCore.Http.Features, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IHeaderDictionary : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.Generic.IDictionary<string, Microsoft.Extensions.Primitives.StringValues>, System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>
{
Microsoft.Extensions.Primitives.StringValues this[string key] { get; set; }
}
// Generated from `Microsoft.AspNetCore.Http.IQueryCollection` in `Microsoft.AspNetCore.Http.Features, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IQueryCollection : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>
{
Microsoft.Extensions.Primitives.StringValues this[string key] { get; }
bool TryGetValue(string key, out Microsoft.Extensions.Primitives.StringValues value);
}
// Generated from `Microsoft.AspNetCore.Http.QueryString` in `Microsoft.AspNetCore.Http.Abstractions, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public struct QueryString : System.IEquatable<Microsoft.AspNetCore.Http.QueryString>
{
public bool Equals(Microsoft.AspNetCore.Http.QueryString other) => throw null;
public override bool Equals(object obj) => throw null;
public override int GetHashCode() => throw null;
public override string ToString() => throw null;
public string Value { get => throw null; }
}
}
namespace Mvc
{
// Generated from `Microsoft.AspNetCore.Mvc.ActionResult` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class ActionResult : Microsoft.AspNetCore.Mvc.IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.ControllerBase` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class ControllerBase
{
public Microsoft.AspNetCore.Http.HttpRequest Request { get => throw null; }
}
// Generated from `Microsoft.AspNetCore.Mvc.Controller` in `Microsoft.AspNetCore.Mvc.ViewFeatures, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class Controller : Microsoft.AspNetCore.Mvc.ControllerBase, System.IDisposable, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, Microsoft.AspNetCore.Mvc.Filters.IActionFilter
{
public virtual Microsoft.AspNetCore.Mvc.ViewResult View(object model) => throw null;
public void Dispose() => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.FromQueryAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class FromQueryAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata
{
public FromQueryAttribute() => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.HttpPostAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class HttpPostAttribute : Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute
{
public HttpPostAttribute() => throw null;
public HttpPostAttribute(string template) => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.IActionResult` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.ValidateAntiForgeryTokenAttribute` in `Microsoft.AspNetCore.Mvc.ViewFeatures, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class ValidateAntiForgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory
{
public ValidateAntiForgeryTokenAttribute() => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.ViewResult` in `Microsoft.AspNetCore.Mvc.ViewFeatures, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class ViewResult : Microsoft.AspNetCore.Mvc.ActionResult
{
public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; set => throw null; }
public ViewResult() => throw null;
}
namespace Filters
{
// Generated from `Microsoft.AspNetCore.Mvc.Filters.IActionFilter` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IActionFilter : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IAsyncActionFilter : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Filters.IFilterFactory` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IFilterFactory : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IFilterMetadata
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IOrderedFilter : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
}
}
namespace ModelBinding
{
// Generated from `Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IBindingSourceMetadata
{
}
// Generated from `Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IModelNameProvider
{
}
}
namespace Routing
{
// Generated from `Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class HttpMethodAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IActionHttpMethodProvider
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider` in `Microsoft.AspNetCore.Mvc.Core, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IRouteTemplateProvider
{
}
}
namespace ViewFeatures
{
// Generated from `Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary` in `Microsoft.AspNetCore.Mvc.ViewFeatures, Version=1.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class ViewDataDictionary : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object>>
{
System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>>.GetEnumerator() => throw null;
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;
public System.Collections.Generic.ICollection<object> Values { get => throw null; }
public System.Collections.Generic.ICollection<string> Keys { get => throw null; }
public bool Contains(System.Collections.Generic.KeyValuePair<string, object> item) => throw null;
public bool ContainsKey(string key) => throw null;
public bool IsReadOnly { get => throw null; }
public bool Remove(System.Collections.Generic.KeyValuePair<string, object> item) => throw null;
public bool Remove(string key) => throw null;
public bool TryGetValue(string key, out object value) => throw null;
public int Count { get => throw null; }
public object this[string index] { get => throw null; set => throw null; }
public void Add(System.Collections.Generic.KeyValuePair<string, object> item) => throw null;
public void Add(string key, object value) => throw null;
public void Clear() => throw null;
public void CopyTo(System.Collections.Generic.KeyValuePair<string, object>[] array, int arrayIndex) => throw null;
}
}
}
}
namespace Extensions
{
namespace Primitives
{
// Generated from `Microsoft.Extensions.Primitives.StringValues` in `Microsoft.Extensions.Primitives, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public struct StringValues : System.IEquatable<string[]>, System.IEquatable<string>, System.IEquatable<Microsoft.Extensions.Primitives.StringValues>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList<string>, System.Collections.Generic.IReadOnlyCollection<string>,
System.Collections.Generic.IList<string>, System.Collections.Generic.IEnumerable<string>, System.Collections.Generic.ICollection<string>
{
System.Collections.Generic.IEnumerator<string> System.Collections.Generic.IEnumerable<string>.GetEnumerator() => throw null;
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;
bool System.Collections.Generic.ICollection<string>.Contains(string item) => throw null;
bool System.Collections.Generic.ICollection<string>.IsReadOnly { get => throw null; }
bool System.Collections.Generic.ICollection<string>.Remove(string item) => throw null;
int System.Collections.Generic.IList<string>.IndexOf(string item) => throw null;
public bool Equals(Microsoft.Extensions.Primitives.StringValues other) => throw null;
public bool Equals(string other) => throw null;
public bool Equals(string[] other) => throw null;
public int Count { get => throw null; }
public override bool Equals(object obj) => throw null;
public override int GetHashCode() => throw null;
public override string ToString() => throw null;
public static implicit operator string(Microsoft.Extensions.Primitives.StringValues values) => throw null;
public string this[int index] { get => throw null; set => throw null; }
public string[] ToArray() => throw null;
void System.Collections.Generic.ICollection<string>.Add(string item) => throw null;
void System.Collections.Generic.ICollection<string>.Clear() => throw null;
void System.Collections.Generic.ICollection<string>.CopyTo(string[] array, int arrayIndex) => throw null;
void System.Collections.Generic.IList<string>.Insert(int index, string item) => throw null;
void System.Collections.Generic.IList<string>.RemoveAt(int index) => throw null;
}
}
}
}
namespace System
{
namespace Linq
{
// Generated from `System.Linq.Enumerable` in `System.Linq, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
static public class Enumerable
{
public static TSource First<TSource>(this System.Collections.Generic.IEnumerable<TSource> source) => throw null;
}
}
}

View File

@@ -0,0 +1,153 @@
namespace System
{
namespace Collections
{
namespace Specialized
{
// Generated from `System.Collections.Specialized.NameObjectCollectionBase` in `System.Collections.Specialized, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
abstract public class NameObjectCollectionBase : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection
{
bool System.Collections.ICollection.IsSynchronized { get => throw null; }
object System.Collections.ICollection.SyncRoot { get => throw null; }
public virtual System.Collections.IEnumerator GetEnumerator() => throw null;
public virtual int Count { get => throw null; }
public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;
public virtual void OnDeserialization(object sender) => throw null;
void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;
}
// Generated from `System.Collections.Specialized.NameValueCollection` in `System.Collections.Specialized, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase
{
public string this[string name] { get => throw null; set => throw null; }
}
}
}
namespace IO
{
// Generated from `System.IO.TextWriter` in `System.Runtime.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
abstract public class TextWriter : System.MarshalByRefObject, System.IDisposable
{
public void Dispose() => throw null;
}
}
namespace Web
{
// Generated from `System.Web.HttpContext` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public class HttpContext : System.Web.IPrincipalContainer
{
public System.Web.HttpServerUtility Server { get => throw null; }
public static System.Web.HttpContext Current { get => throw null; set => throw null; }
}
// Generated from `System.Web.HttpRequestBase` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
abstract public class HttpRequestBase
{
public virtual System.Collections.Specialized.NameValueCollection QueryString { get => throw null; }
}
// Generated from `System.Web.HttpServerUtility` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public class HttpServerUtility
{
public string HtmlEncode(string s) => throw null;
}
// Generated from `System.Web.HttpUtility` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public class HttpUtility
{
public static string HtmlEncode(string s) => throw null;
}
// Generated from `System.Web.IHtmlString` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public interface IHtmlString
{
}
// Generated from `System.Web.IPrincipalContainer` in `System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
interface IPrincipalContainer
{
}
namespace Mvc
{
// Generated from `System.Web.Mvc.HtmlHelper<>` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
public class HtmlHelper<TModel> : System.Web.Mvc.HtmlHelper
{
}
// Generated from `System.Web.Mvc.HtmlHelper` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
public class HtmlHelper
{
public System.Web.IHtmlString Raw(string value) => throw null;
public string Encode(string value) => throw null;
}
// Generated from `System.Web.Mvc.IViewDataContainer` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
public interface IViewDataContainer
{
}
// Generated from `System.Web.Mvc.IViewStartPageChild` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
interface IViewStartPageChild
{
}
// Generated from `System.Web.Mvc.WebViewPage<>` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
abstract public class WebViewPage<TModel> : System.Web.Mvc.WebViewPage
{
public System.Web.Mvc.HtmlHelper<TModel> Html { get => throw null; set => throw null; }
}
// Generated from `System.Web.Mvc.WebViewPage` in `System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
abstract public class WebViewPage : System.Web.WebPages.WebPageBase, System.Web.Mvc.IViewStartPageChild, System.Web.Mvc.IViewDataContainer
{
}
}
namespace WebPages
{
// Generated from `System.Web.WebPages.ITemplateFile` in `System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
public interface ITemplateFile
{
}
// Generated from `System.Web.WebPages.StringExtensions` in `System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
static public class StringExtensions
{
public static bool IsEmpty(this string value) => throw null;
}
// Generated from `System.Web.WebPages.WebPageBase` in `System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
abstract public class WebPageBase : System.Web.WebPages.WebPageRenderingBase
{
public System.IO.TextWriter Output { get => throw null; }
public override dynamic Page { get => throw null; }
public override string Layout { get => throw null; set => throw null; }
public override void Write(object value) => throw null;
public override void WriteLiteral(object value) => throw null;
}
// Generated from `System.Web.WebPages.WebPageExecutingBase` in `System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
abstract public class WebPageExecutingBase
{
protected void BeginContext(string virtualPath, int startPosition, int length, bool isLiteral) => throw null;
protected void EndContext(string virtualPath, int startPosition, int length, bool isLiteral) => throw null;
public abstract void Execute();
public abstract void Write(object value);
public abstract void WriteLiteral(object value);
public static void WriteLiteralTo(System.IO.TextWriter writer, object content) => throw null;
}
// Generated from `System.Web.WebPages.WebPageRenderingBase` in `System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35`
abstract public class WebPageRenderingBase : System.Web.WebPages.WebPageExecutingBase, System.Web.WebPages.ITemplateFile
{
public abstract dynamic Page { get; }
public abstract string Layout { get; set; }
public virtual System.Web.HttpRequestBase Request { get => throw null; }
}
}
}
}

View File

@@ -1,4 +0,0 @@
| UrlRedirect.cs:14:31:14:61 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:14:31:14:53 | access to property QueryString | user-provided value |
| UrlRedirect.cs:39:44:39:74 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:39:44:39:66 | access to property QueryString | user-provided value |
| UrlRedirect.cs:40:47:40:77 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:40:47:40:69 | access to property QueryString | user-provided value |
| UrlRedirect.cs:49:29:49:31 | access to local variable url | Untrusted URL redirection due to $@. | UrlRedirect.cs:24:22:24:44 | access to property QueryString | user-provided value |

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll
// semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs /r:System.Collections.Specialized.dll
using System;
using System.Web;

View File

@@ -0,0 +1,14 @@
| UrlRedirect.cs:14:31:14:61 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:14:31:14:53 | access to property QueryString | user-provided value |
| UrlRedirect.cs:39:44:39:74 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:39:44:39:66 | access to property QueryString | user-provided value |
| UrlRedirect.cs:40:47:40:77 | access to indexer | Untrusted URL redirection due to $@. | UrlRedirect.cs:40:47:40:69 | access to property QueryString | user-provided value |
| UrlRedirect.cs:49:29:49:31 | access to local variable url | Untrusted URL redirection due to $@. | UrlRedirect.cs:24:22:24:44 | access to property QueryString | user-provided value |
| UrlRedirectCore.cs:18:22:18:26 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:21:44:21:48 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:27:46:27:50 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:33:66:33:70 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:36:49:36:53 | call to operator implicit conversion | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:39:69:39:73 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:42:39:42:53 | ... + ... | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:15:44:15:48 | value | user-provided value |
| UrlRedirectCore.cs:50:28:50:32 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value |
| UrlRedirectCore.cs:55:32:55:45 | object creation of type Uri | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value |
| UrlRedirectCore.cs:58:31:58:35 | access to parameter value | Untrusted URL redirection due to $@. | UrlRedirectCore.cs:47:51:47:55 | value | user-provided value |

View File

@@ -0,0 +1,67 @@
// semmle-extractor-options: /r:System.Private.Uri.dll
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Headers;
using Microsoft.AspNetCore.Mvc;
namespace Testing.Controllers
{
public class SomeController : ControllerBase
{
private static string SomeValue = "HeaderValue";
[HttpPost]
public void Post([FromBody] string value)
{
// BAD: straight up controller redirect
Redirect(value);
// BAD: Setting response headers collection, location = redirect
Response.Headers["location"] = value;
// GOOD: Setting response header to a constant value
Response.Headers["location"] = SomeValue;
// BAD: Setting response headers collection, location = redirect via add method
Response.Headers.Add("location", value);
// GOOD: Setting response header to a constant value
Response.Headers.Add("location", "foo");
// BAD: redirect via location
Response.Headers.SetCommaSeparatedValues("location", value);
// BAD = redirect via setting location value from tainted source
Response.Headers.Append("location", value);
// BAD: redirect via setting location header from comma-separated values
Response.Headers.AppendCommaSeparatedValues("location", value);
// BAD: tainted redirect to Action
RedirectToActionPermanent("Error" + value);
}
// PUT: api/Some/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
RedirectToPage(value);
var headers = new ResponseHeaders(Response.Headers);
// BAD: redirect via header helper class
headers.Location = new Uri(value);
// BAD: response redirect
Response.Redirect(value);
// GOOD: whitelisted redirect
if(Url.IsLocalUrl(value))
Redirect(value);
}
}
}
// original-extractor-options: /r:netstandard.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Mvc.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Mvc.Core.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Http.Extensions.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Extensions.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Http.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Mvc.Abstractions.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Abstractions.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Http.Features.2.1.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Features.dll /r:${testdir}/../../../../../packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll /r:System.Private.Uri.dll

View File

@@ -0,0 +1,182 @@
namespace Microsoft
{
namespace AspNetCore
{
namespace Http
{
// Generated from `Microsoft.AspNetCore.Http.HeaderDictionaryExtensions` in `Microsoft.AspNetCore.Http.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
static public class HeaderDictionaryExtensions
{
public static void Append(this Microsoft.AspNetCore.Http.IHeaderDictionary headers, string key, Microsoft.Extensions.Primitives.StringValues value) => throw null;
public static void AppendCommaSeparatedValues(this Microsoft.AspNetCore.Http.IHeaderDictionary headers, string key, params string[] values) => throw null;
public static void SetCommaSeparatedValues(this Microsoft.AspNetCore.Http.IHeaderDictionary headers, string key, params string[] values) => throw null;
}
// Generated from `Microsoft.AspNetCore.Http.HttpResponse` in `Microsoft.AspNetCore.Http.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class HttpResponse
{
public abstract Microsoft.AspNetCore.Http.IHeaderDictionary Headers { get; }
public virtual void Redirect(string location) => throw null;
}
// Generated from `Microsoft.AspNetCore.Http.IHeaderDictionary` in `Microsoft.AspNetCore.Http.Features, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IHeaderDictionary : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,Microsoft.Extensions.Primitives.StringValues>>, System.Collections.Generic.IDictionary<string,Microsoft.Extensions.Primitives.StringValues>, System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string,Microsoft.Extensions.Primitives.StringValues>>
{
Microsoft.Extensions.Primitives.StringValues this[string key] { get; set; }
}
namespace Headers
{
// Generated from `Microsoft.AspNetCore.Http.Headers.ResponseHeaders` in `Microsoft.AspNetCore.Http.Extensions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class ResponseHeaders
{
public ResponseHeaders(Microsoft.AspNetCore.Http.IHeaderDictionary headers) => throw null;
public System.Uri Location { get => throw null; set => throw null; }
}
}
}
namespace Mvc
{
// Generated from `Microsoft.AspNetCore.Mvc.ActionResult` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class ActionResult : Microsoft.AspNetCore.Mvc.IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.ControllerBase` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class ControllerBase
{
public Microsoft.AspNetCore.Http.HttpResponse Response { get => throw null; }
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get => throw null; set => throw null; }
public virtual Microsoft.AspNetCore.Mvc.RedirectResult Redirect(string url) => throw null;
public virtual Microsoft.AspNetCore.Mvc.RedirectToActionResult RedirectToActionPermanent(string actionName) => throw null;
public virtual Microsoft.AspNetCore.Mvc.RedirectToPageResult RedirectToPage(string pageName) => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.FromBodyAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class FromBodyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata
{
public FromBodyAttribute() => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.HttpPostAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class HttpPostAttribute : Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute
{
public HttpPostAttribute() => throw null;
public HttpPostAttribute(string template) => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.HttpPutAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class HttpPutAttribute : Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute
{
public HttpPutAttribute() => throw null;
public HttpPutAttribute(string template) => throw null;
}
// Generated from `Microsoft.AspNetCore.Mvc.IActionResult` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.IUrlHelper` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IUrlHelper
{
bool IsLocalUrl(string url);
}
// Generated from `Microsoft.AspNetCore.Mvc.RedirectResult` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class RedirectResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult, Microsoft.AspNetCore.Mvc.IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.RedirectToActionResult` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class RedirectToActionResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult, Microsoft.AspNetCore.Mvc.IActionResult
{
}
// Generated from `Microsoft.AspNetCore.Mvc.RedirectToPageResult` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public class RedirectToPageResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult, Microsoft.AspNetCore.Mvc.IActionResult
{
}
namespace ModelBinding
{
// Generated from `Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata` in `Microsoft.AspNetCore.Mvc.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IBindingSourceMetadata
{
}
}
namespace Routing
{
// Generated from `Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
abstract public class HttpMethodAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IActionHttpMethodProvider
{
}
// Generated from `Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IRouteTemplateProvider
{
}
}
namespace ViewFeatures
{
// Generated from `Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult` in `Microsoft.AspNetCore.Mvc.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public interface IKeepTempDataResult : Microsoft.AspNetCore.Mvc.IActionResult
{
}
}
}
}
namespace Extensions
{
namespace Primitives
{
// Generated from `Microsoft.Extensions.Primitives.StringValues` in `Microsoft.Extensions.Primitives, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60`
public struct StringValues : System.IEquatable<string[]>, System.IEquatable<string>, System.IEquatable<Microsoft.Extensions.Primitives.StringValues>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList<string>, System.Collections.Generic.IReadOnlyCollection<string>, System.Collections.Generic.IList<string>, System.Collections.Generic.IEnumerable<string>, System.Collections.Generic.ICollection<string>
{
System.Collections.Generic.IEnumerator<string> System.Collections.Generic.IEnumerable<string>.GetEnumerator() => throw null;
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;
bool System.Collections.Generic.ICollection<string>.Contains(string item) => throw null;
bool System.Collections.Generic.ICollection<string>.IsReadOnly { get => throw null; }
bool System.Collections.Generic.ICollection<string>.Remove(string item) => throw null;
int System.Collections.Generic.IList<string>.IndexOf(string item) => throw null;
public bool Equals(Microsoft.Extensions.Primitives.StringValues other) => throw null;
public bool Equals(string other) => throw null;
public bool Equals(string[] other) => throw null;
public int Count { get => throw null; }
public override bool Equals(object obj) => throw null;
public override int GetHashCode() => throw null;
public override string ToString() => throw null;
public static implicit operator Microsoft.Extensions.Primitives.StringValues(string value) => throw null;
void System.Collections.Generic.ICollection<string>.Add(string item) => throw null;
void System.Collections.Generic.ICollection<string>.Clear() => throw null;
void System.Collections.Generic.ICollection<string>.CopyTo(string[] array, int arrayIndex) => throw null;
void System.Collections.Generic.IList<string>.Insert(int index, string item) => throw null;
void System.Collections.Generic.IList<string>.RemoveAt(int index) => throw null;
public string this[int i] { get => throw null; set => throw null; }
}
}
}
}
namespace System
{
// Generated from `System.Uri` in `System.Private.Uri, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`
public class Uri : System.Runtime.Serialization.ISerializable
{
public Uri(string uriString) => throw null;
public override bool Equals(object comparand) => throw null;
public override int GetHashCode() => throw null;
public override string ToString() => throw null;
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;
}
}