0

这是一个视图:

@model ModelValidation.Models.Appointment
@{
    ViewBag.Title = "Make a Booking";
}
<h2>
    Book an Appointment</h2>
@using (Html.BeginForm())
{
    <p>
        @Html.LabelFor(m => m.ClientName, "Your name: ") @Html.EditorFor(m =>     m.ClientName)    
    </p>
    <p>
        @Html.LabelFor(m => m.Date, "Appointment Date: ") @Html.EditorFor(m => m.Date)        
    </p>
    <p>
        @Html.EditorFor(m => m.TermsAccepted) @Html.LabelFor(m => m.TermsAccepted, "I     accept the terms & conditions")
    </p>
    <input type="submit" value="Make Booking" />
}

这是约会类:

public class Appointment
{
    public string ClientName { get; set; }

    [DataType(DataType.Date)]
    public DateTime Date { get; set; }

    public bool TermsAccepted { get; set; }
}

如果我进入 ClientName 编辑器,如下所示:

<b>asdf</b>

按下“进行预订”按钮(提交)后,出现以下异常:

[HttpRequestValidationException (0x80004005): potentilly dangerous value of Request.Form has been received from the client (ClientName="<b>asdf</b>").]
   System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8755668
   Microsoft.Web.Infrastructure.DynamicValidationHelper.<>c__DisplayClass12.<ReplaceCollection>b__d(String value, String key) +79
   Microsoft.Web.Infrastructure.DynamicValidationHelper.LazilyEvaluatedNameObjectEntry.ValidateObject() +89
   Microsoft.Web.Infrastructure.DynamicValidationHelper.LazilyValidatingHashtable.get_Item(Object key) +54
   System.Collections.Specialized.NameObjectCollectionBase.FindEntry(String key) +20
   System.Collections.Specialized.NameValueCollection.GetValues(String name) +8
   System.Web.Mvc.ValueProviderResultPlaceholder.GetResultFromCollection(String key, NameValueCollection collection, CultureInfo culture) +20
   System.Web.Mvc.<>c__DisplayClass4.<.ctor>b__0() +16
   System.Lazy`1.CreateValue() +361
   System.Lazy`1.LazyInitValue() +9591042
   System.Lazy`1.get_Value() +89
   System.Web.Mvc.NameValueCollectionValueProvider.GetValue(String key, Boolean skipValidation) +68
   System.Web.Mvc.ValueProviderCollection.GetValueFromProvider(IValueProvider provider, String key, Boolean skipValidation) +55
   System.Web.Mvc.<>c__DisplayClass9.<GetValue>b__4(IValueProvider provider) +33
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +177
   System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +4187840
   System.Web.Mvc.ValueProviderCollection.GetValue(String key, Boolean skipValidation)     +272
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +385
   System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +17
   System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +399
   System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +93
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +53
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1367
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +449
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

据我所知,所有用户输入默认在剃刀视图引擎中进行编码。那我为什么会得到这个?

在调用目标 POST 操作方法之前引发异常。或者我错过了什么?

4

2 回答 2

4

编辑:

抱歉读错了。

默认情况下,MVC 框架会尝试保护您免受危险输入的影响,例如 html。如果您稍后重新渲染它,这可以用来攻击您的网站。请参阅跨站点脚本

如果您想像输入的名称一样接受 HTML,则必须明确告诉它不要验证该输入。

像:

[HttpPost]
[ValidateInput(false)]
public ActionResult Save()
{
    // ...method body
}

我当然会建议不要这样做,除非它是一个特定的要求。

于 2012-08-30T05:39:33.727 回答
2

将 HTML 存储在数据层中从技术上讲没有任何问题,但它可能会增加您对恶意 HTML/脚本的 xss(跨站点脚本)攻击。

使用

[允许HTML]
您的 ClientName 属性上的属性。然后在保存之前使用Microsoft WPL 或 Web 保护库中的 anti-xss 库并使用
Sanitizer.GetSafeHtmlFragment(clientName)
在保存到数据库之前对其进行消毒(而不是编码!)。

如果您想了解更多关于请求验证和 xss 攻击的扩展信息,请参阅我的复数视力.com hack proofing course。

于 2012-08-30T05:49:02.403 回答