禁用 HttpContext.Current.Request.Params 的请求验证

Mr.*_*ble 5 .net asp.net-mvc-5

使用 MVC5 我[AllowHtml]在特定模型属性上使用以允许将 HTML 发布到服务器。

在代码的某些地方,我想像这样访问请求参数:

string wlid = HttpContext.Current.Request.Params["wlid"];
Run Code Online (Sandbox Code Playgroud)

但这会失败,HttpRequestValidationException如果请求中包含任何 HTML,即使模型属性用[AllowHtml].

有没有办法在HttpContext.Current.Request.Params["wlid"]不完全禁用请求验证的情况下访问?

也许禁用请求验证,访问 Request.Params 然后立即再次启用它?

pit*_*ity 5

Request.Unvalidated作为 的未经验证的等效项工作Request.Params

所以而不是

string wlid = HttpContext.Current.Request.Params["wlid"];
Run Code Online (Sandbox Code Playgroud)

只需使用

string wlid = HttpContext.Current.Request.Unvalidated["wlid"];
Run Code Online (Sandbox Code Playgroud)

或更好(如评论中所建议)以避免与静态成员耦合:

string wlid = this.HttpContext.Request.Unvalidated["wlid"];
Run Code Online (Sandbox Code Playgroud)

长话短说

如果您查看幕后,Request.Params请结合以下数据(按此顺序):

  • 请求参数
  • 形式
  • 饼干
  • 服务器变量

您可以在此处查看其源代码: https://github.com/microsoft/referencesource/blob/master/System.Web/HttpRequest.cs

关键部分是:

_params.Add(this.QueryString);
_params.Add(this.Form);
_params.Add(this.Cookies);
_params.Add(this.ServerVariables);
Run Code Online (Sandbox Code Playgroud)

您是对的,访问Request.Params失败,HttpRequestValidationException因为它读取导致请求验证的下面的集合。

文档

当 ASP.NET 读取 HTTP 请求集合(例如 Form、QueryString 和 Cookies 集合)中的值时,它会执行请求验证。在请求验证期间,ASP.NET 检查发布的值并确定它们是否包含标记、脚本或保留字符。默认情况下,如果 ASP.NET 检测到任何这些类型的输入,它将引发 HttpRequestValidationException 异常。这有助于防止对您网站的恶意脚本注入攻击。

所以这按设计工作。如果您想绕过 ASP.NET 请求验证,可以使用不同的对象。它被调用Request.Unvalidated并以属性的形式包含查询字符串参数、表单变量和cookie:

  • Request.Unvalidated.QueryString
  • Request.Unvalidated.Form
  • Request.Unvalidated.Cookies

读取这些属性不会触发请求验证,因此您可以在您的情况下使用它们。如果您不知道上述哪个属性包含您的数据,您可以使用 的Request.Unvalidated形式,Request.Unvalidated["somekey"]因为它有一个索引器,可以从FormCookiesQueryStringServerVariables集合中检索数据。所以它非常接近(但未经验证!)相当于Request.Params.

请注意,绕过请求验证后,您将容易受到跨站点脚本攻击,并且必须手动验证数据是否存在潜在的 XSS 攻击。


Sen*_*Sen 2

每当访问 Params 集合时都会触发验证。

我能够用它来获得我们需要的价值

Request.Unvalidated.QueryString["key"]
Run Code Online (Sandbox Code Playgroud)

注意:QueryString 与 Params 并不完全相同,但对于我们的情况,我们需要的数据位于查询字符串中,因此这是有效的。

有关详细信息,请参阅MSDN 中的 HttpRequestBase.Unvalidated 。