有没有办法在json发布到MVC操作的情况下从MVC手动调用XSS检测,例如从过滤器调用(例如jQuery中带有json内容的$ .ajax帖子)?
我们正在使用MVC 5并且没有用于捕获XSS的标准MVC机制(“检测到可能不安全的输入”),但是应用程序的一些部分使用$.ajax
来发布JSON(“application / json”)内容类型)到MVC动作。在这些情况下,我们注意到XSS检测不会运行并允许危险的表单输入。
在我们对类似问题的调查和研究中,我们发现默认模型绑定器中的JsonValueProviderFactory
对表单提交或查询字符串输入中存在的此XSS安全性没有相同的调用。
虽然很容易在客户端清理输入,但我们显然也需要服务器验证才能抛出5xx(可能我可以将其包含在过滤器中以共享可能受影响的操作)以强制执行此操作危险代码检测json提交的输入与默认模型绑定,如果可能的话,以避免重新发明轮子或将html编码的错误输入插入我们的数据库。
答案 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
如果有人有其他建议,我很乐意看到其他方法。