Why do I get HttpRequestValidationException submit

2019-08-20 10:20发布

This is a view:

@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" />
}

This is the Appointment class:

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

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

    public bool TermsAccepted { get; set; }
}

If I enter into the ClientName editor something like this:

<b>asdf</b>

after I press the "Make Booking" button (submit) I get the following exception:

[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

As far as I know all the user input is encoded by default in razor view engine. Then why am I getting this?

The exception is thrown before the target POST action method is invoked. Or what am I missing?

2条回答
做个烂人
2楼-- · 2019-08-20 10:35

There isn't technically anything wrong with storing HTML in your data layer but it can increase your with of xss (cross site scripting) attacks with malicious HTML/script.

Use the

[AllowHtml]
attribute on your ClientName property. Then prior to save use the anti-xss library from Microsoft WPL or Web Protection Library and use the
Sanitizer.GetSafeHtmlFragment(clientName)
to sanitize it (not encode!) before saving to your database.

If you want much more extended information on request validation and xss attacks see my pluralsight.com hack proofing course.

查看更多
贪生不怕死
3楼-- · 2019-08-20 10:46

Edit:

Sorry read that all wrong.

The MVC framework by default will try and protect you from dangerous input, such as html. This can be used to attack your site if you later re-render it. See Cross Site Scripting

If you want to accept HTML like the value you are entering for the name, you will have to explicitly tell it not to validate that input.

Like:

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

I would of course recommend against this unless it is a specific requirement.

查看更多
登录 后发表回答