如何避免潜在危险的Request.Form值?

时间:2013-12-03 02:00:14

标签: c# asp.net asp.net-mvc asp.net-mvc-4

首先,我知道有很多类似于我的问题,但我没有找到任何可以满足我的解决方案......

所以,我在这段代码上得到了上述异常:

var returnUrl = Request.Params["returnUrl"] ?? Request.RawUrl;

在我向我的网站提交帖子后,mvc开始准备响应页面,它在上面的代码中崩溃了。现在,这两个变量都不包含任何会导致此异常的代码。不知何故,MVC检测到我正在使用Request个对象,并在不查看我在做什么的情况下抛出错误。我不想禁用那些安全检查,但我不知道我还能做什么?

3 个答案:

答案 0 :(得分:5)

有同样的问题,只是找到了解决方案。当您从Request访问发布的值时,会重新验证这些值,并且由于某种原因,在此特定验证中忽略[AllowHtml](可能是在MVC 5中测试的错误)。经过一番搜索后,我偶然发现:

http://msdn.microsoft.com/en-us/library/hh882339(v=vs.110).aspx

向下翻页,在“MVC"”中的“#34;禁用请求验证”部分下,它提到了Request.Unvalidated。此属性在绕过验证时返回请求对象,以便您可以在不调用验证的情况下获取特定参数。

因此,不要使用Request.Params["returnUrl"],而是使用Request.Unvalidated["returnUrl"]

答案 1 :(得分:1)

如果要将请求绑定到模型,可以将AllowHtml属性添加到需要它的模型属性中。这使您可以保护模型的其余部分。

答案 2 :(得分:0)

我需要在ActionFilterAttribute中访问未经验证的Request.Params,并最终编写了此扩展方法,该方法可能会对其他人有所帮助。它应返回与Request.Params集合基本相同的数据,但未经验证。我正在返回字典,但是如果愿意,您可以轻松地将其更改为NameValueCollection。此扩展方法不在请求范围之内,因此我可以访问ServerVariables集合,因为该方法在UnvalidatedRequestValuesBase类中不可用,但通常包含在Params中。它还不支持NameValueCollection.Values,而仅返回一个与Params稍有不同的单个值。

public static IReadOnlyDictionary<string, string> UnvalidatedParams(this HttpRequestBase request)
{
    var dict = new Dictionary<string, string>();
    var unvalidated = request.Unvalidated;

    for (var i = 0; i < unvalidated.QueryString.Count; i++)
    {
        var name = unvalidated.QueryString.GetKey(i);
        if (string.IsNullOrWhiteSpace(name))
            continue;

        var value = unvalidated.QueryString.Get(i);
        dict[name] = value;
    }

    for (var i = 0; i < unvalidated.Form.Count; i++)
    {
        var name = unvalidated.Form.GetKey(i);
        if (string.IsNullOrWhiteSpace(name))
            continue;

        var value = unvalidated.Form.Get(i);
        dict[name] = value;
    }

    var cookieCount = unvalidated.Cookies.Count;
    for (var i = 0; i < cookieCount; i++)
    {
        var cookie = unvalidated.Cookies[i];
        if (string.IsNullOrWhiteSpace(cookie?.Name))
            continue;

        dict[cookie.Name] = cookie.Value;
    }

    for (var i = 0; i < request.ServerVariables.Count; i++)
    {
        var name = request.ServerVariables.GetKey(i);
        if (string.IsNullOrWhiteSpace(name))
            continue;

        var value = request.ServerVariables.Get(i);
        dict[name] = value;
    }

    return dict;
}