来自JSON ajax post

时间:2017-08-23 18:02:56

标签: c# asp.net-mvc xss

有没有办法在json发布到MVC操作的情况下从MVC手动调用XSS检测,例如从过滤器调用(例如jQuery中带有json内容的$ .ajax帖子)?

我们正在使用MVC 5并且没有用于捕获XSS的标准MVC机制(“检测到可能不安全的输入”),但是应用程序的一些部分使用$.ajax来发布JSON(“application / json”)内容类型)到MVC动作。在这些情况下,我们注意到XSS检测不会运行并允许危险的表单输入。

在我们对类似问题的调查和研究中,我们发现默认模型绑定器中的JsonValueProviderFactory对表单提交或查询字符串输入中存在的此XSS安全性没有相同的调用。

虽然很容易在客户端清理输入,但我们显然也需要服务器验证才能抛出5xx(可能我可以将其包含在过滤器中以共享可能受影响的操作)以强制执行此操作危险代码检测json提交的输入与默认模型绑定,如果可能的话,以避免重新发明轮子或将html编码的错误输入插入我们的数据库。

1 个答案:

答案 0 :(得分:9)

我找到了适合我情况的解决方案。在这种情况下,我们使用$.ajax使用JQuery将JSON发布到MVC操作。默认模型绑定程序不验证发布的JSON,允许根据我们的操作发布不安全的XSS。

为了解决这个问题,我发现RequestValidator有一个静态方法InvokeIsValidRequestString,它允许验证一个特定的字符串来检测XSS(因为我找到的每个解决方案,直到现在在这里重新发明轮子并且拥有自己的XSS检查白/黑名单)。然后,只需将操作限制为适当的方案,获取已发布的JSON,并在检测到XSS时抛出验证错误。

public class ValidateJsonXssAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext?.Request;
        if (request != null && "application/json".Equals(request.ContentType, StringComparison.OrdinalIgnoreCase))
        {
            if (request.ContentLength > 0 && request.Form.Count == 0) // 
            {
                if (request.InputStream.Position > 0)
                    request.InputStream.Position = 0; // InputStream has already been read once from "ProcessRequest"
                using (var reader = new StreamReader(request.InputStream))
                {
                    var postedContent = reader.ReadToEnd(); // Get posted JSON content
                    var isValid = RequestValidator.Current.InvokeIsValidRequestString(HttpContext.Current, postedContent,
                        RequestValidationSource.Form, "postedJson", out var failureIndex); // Invoke XSS validation
                    if (!isValid) // Not valid, so throw request validation exception
                        throw new HttpRequestValidationException("Potentially unsafe input detected");
                }
            }
        }
    }
}

然后,我可以装饰相关的MVC操作,期望可能绕过标准XSS预防的JSON发布数据:

[HttpPost]
[ValidateJsonXss]
public ActionResult PublishRecord(RecordViewModel vm) { ... }

我很幸运地发现了OWASP .NET的建议,其中建议扩展RequestValidator对象,该对象公开由MVC自动使用的ValidateInput完成的字符串验证,用于查询字符串,表单集合的其他场景,和cookie值。

了解更多信息:https://www.owasp.org/index.php/ASP.NET_Request_Validation

如果有人有其他建议,我很乐意看到其他方法。