【问题标题】:ASP.Net RequestValidation for json POST to match Form RequestValidation用于 json POST 的 ASP.Net RequestValidation 以匹配表单 RequestValidation
【发布时间】:2017-11-06 14:23:23
【问题描述】:

我希望能够以与表单验证(“application/x-www-form-urlencoded”)一致的方式对内容类型“application/json”进行 RequestValidation。

我读过https://msdn.microsoft.com/en-us/library/system.web.util.requestvalidator(v=vs.110).aspx,但并没有太大帮助。

我正在考虑尝试实现一个自定义请求验证器来替换默认的 System.Web.Util.RequestValidator。

我也看过https://msdn.microsoft.com/en-us/library/system.web.util.requestvalidator(v=vs.110).aspx

如果我不能让输入得到一致的验证,我可能会删除将 json 发送到控制器并强制所有内容通过表单的能力 - 这并不理想,因为我希望一些方法可以接受 json。

我已经对输出进行了编码(在可能的情况下),但我仍然希望通过验证输入来进行深度防御,最好是对表单和 json 保持一致。

不幸的是,很多关于这方面的 MSDN 文档已经严重过时,现在已经无关紧要了。

我使用 .net 4.6.1 作为参考。

尝试以这种方式验证请求是否明智?

【问题讨论】:

标签: c# asp.net json request-validation


【解决方案1】:

最后我实现了一个自定义 ModelBinder...这是阅读此https://weblogs.asp.net/imranbaloch/security-issue-in-asp-net-mvc3-jsonvalueproviderfactory 和此https://gist.github.com/jamescrowley/b8c0c006e7b00e28cbbf 的组合

它会修改请求的来源 (RequestValidationSource.Form) 以使其看起来像一个表单,以便可以在同一管道中对其进行验证。

public class JsonValidatingModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = base.BindModel(controllerContext, bindingContext);
        if (!IsJsonRequest(controllerContext))
        {
            return result;
        }
        if (!bindingContext.ModelMetadata.RequestValidationEnabled)
        {
            return result;
        }
        if (result != null)
        {
            EnsureRequestFieldIsValid(controllerContext, result);
        }
        return result;
    }

    static void EnsureRequestFieldIsValid(ControllerContext controllerContext, object result)
    {
        int index;
        // abusing RequestValidationSource enum
        if (!RequestValidator.Current.InvokeIsValidRequestString(
            controllerContext.HttpContext.ApplicationInstance.Context,
            result.ToString(), RequestValidationSource.Form, null, out index))
        {
            throw new HttpRequestValidationException(
                "A potentially dangerous value was detected from the client ");
        }
    }

    static bool IsJsonRequest(ControllerContext controllerContext)
    {
        return controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase);
    }

在 Global.asax...

    protected void Application_Start()
    {
        System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new JsonValidatingModelBinder();

    }

【讨论】:

    猜你喜欢
    • 2012-04-01
    • 2012-03-30
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    相关资源
    最近更新 更多