asp.net mvc 4 - Input sanitization with MVC Razor - how to be safe? -
if have standard signup form text field, , type script tags it, mvc sends error saying "a potentially dangerous request.form value detected client". debug error? users see on live site?
is there safe , easy way silently accept , encode/sanitize input field such mvc doesn't throw scary error, input rendered harmless?
obviously i'd want make sure output encoded, razor takes care of part, , i'm careful @html.raw. taking care of database inputs using parameterized queries, sql injection shouldn't threat.
the "a potentially dangerous request.form value detected client" exception not debug error , is error propagate on deployment server. users see error (or custom error page) on live server.
to allow un-sanitized html bound model may of following:
- decorate signup model properties
[allowhtml]attribute - decorate signup controller action
[validateinput( false )]attribute if you're using mvc v4.0 include following in web.config:
<location path="accounts/signup"> <system.web> <pages validaterequest="false" /> <httpruntime requestvalidationmode="2.0" /> </system.web> </location>
i repeat, of above allow un-sanitized html bound model. means there no "a potentially dangerous request.form value detected client" error input not sanitized , still contain potentially harmful tags.
to allow sanitized input bound model may adapt propertybindattribute implementation customizing property binding through attributes allow decorate model properties [allowsanitizedhtml] attribute functionality allow html input accepted after sanitization. sanitization, can use microsoft.security.application.encoder.encode() helper method (nuget package name: 'antixss')
firstly, attribute provide base class propery binding:
[attributeusage( attributetargets.property , allowmultiple = false )] public abstract class abstractpropertybinderattribute : attribute { public abstract bool bindproperty( controllercontext controllercontext , modelbindingcontext bindingcontext , propertydescriptor propertydescriptor ); } then, custom model binder knows of attribute model binding may handle special case of attribute property binding:
public class custommodelbinder : defaultmodelbinder { protected override void bindproperty( controllercontext controllercontext , modelbindingcontext bindingcontext , propertydescriptor propertydescriptor ) { if( propertydescriptor.attributes.oftype<abstractpropertybinderattribute>().any() ) { var modelbindattr = propertydescriptor.attributes.oftype<abstractpropertybinderattribute>().firstordefault(); if( modelbindattr.bindproperty( controllercontext , bindingcontext , propertydescriptor ) ) { return; } } base.bindproperty( controllercontext , bindingcontext , propertydescriptor ); } } don't forget add following code global.asax allow custommodelbinder used default:
system.web.mvc.modelbinders.binders.defaultbinder = new custommodelbinder(); finally, allowsanitizedhtmlattribute:
public class allowsanitizedhtmlattribute : abstractpropertybinderattribute , imetadataaware { public override bool bindproperty( controllercontext controllercontext , modelbindingcontext bindingcontext , propertydescriptor propertydescriptor ) { if( propertydescriptor.propertytype == typeof( string ) ) { var unvalidatedvalueprovider = bindingcontext.valueprovider iunvalidatedvalueprovider; var result = unvalidatedvalueprovider.getvalue( propertydescriptor.name , true ); if( result != null ) { propertydescriptor.setvalue( bindingcontext.model , encoder.htmlencode( result.attemptedvalue ) ); return true; } } return false; } #region imetadataaware members public void onmetadatacreated( modelmetadata metadata ) { if( metadata == null ) throw new argumentnullexception( "metadata" ); metadata.requestvalidationenabled = false; } #endregion } now can safetly decorate model properties require sanitization in signup form [allowsanitizedhtml] attributes. allow input model properties silently bound after being sanitized.
Comments
Post a Comment