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

时间:2018-01-19 11:40:20

标签: .net asp.net-mvc-5

使用MVC5我在特定模型属性上使用java.net.ConnectException: Connection refused Exception. 以允许将HTML发布到服务器。

在代码的某些地方,我想访问请求参数,如下所示:

[AllowHtml]

但是,如果请求中包含任何HTML,则会失败string wlid = HttpContext.Current.Request.Params["wlid"]; ,即使模型属性使用HttpRequestValidationException进行修饰。

有没有办法在没有完全禁用请求验证的情况下访问[AllowHtml]

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

2 个答案:

答案 0 :(得分:0)

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

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

class_list <- list(
    list(prof = "Person 1", class = "Class A"),
    list(prof = "Person 2", class = "Class B"),
    list(prof = "Person 3", class = "Class C")
)

purrr::walk(class_list, function(class_info) {
    prof <- class_info$prof
    class <- class_info$class
    rmarkdown::render(
        input = "dummy_rmd.Rmd", 
        output_file = sprintf("output_%s_%s.html", prof, class),
        params = list(prof = prof, class = class)
        )
})

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

有关详细信息,请参阅MSDN for HttpRequestBase.Unvalidated

答案 1 :(得分:0)

Request.Unvalidated相当于Request.Params的未经验证的等效物。

所以不是

string wlid = HttpContext.Current.Request.Params["wlid"];

只需使用

string wlid = HttpContext.Current.Request.Unvalidated["wlid"];

或更好的方法(如注释中所建议),以避免与静态成员耦合:

string wlid = this.HttpContext.Request.Unvalidated["wlid"];

TL; DR

如果您在幕后看,Request.Params会组合以下数据(按此顺序):

  • QueryString
  • 表格
  • 饼干
  • ServerVariables

您可以在此处查看其源代码: 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);

您说对了,Request.Params访问HttpRequestValidationException失败,因为它读取了导致请求验证的底层集合。

Documentation

  

当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"],因为它有一个indexer可以从{{ 1}},FormCookiesQueryString集合。因此,它与ServerVariables相当接近(但未经验证!)。

请注意,绕过请求验证后,您将容易受到跨站点脚本的攻击,您必须手动验证数据以防可能的XSS攻击。