Sie können Felder in benutzerdefinierten Modellbindern automatisch mit HTML kodieren. Meine Lösung ist etwas anders, ich setze den Fehler in ModelState und zeige die Fehlermeldung neben dem Feld an. Es ist einfach, diesen Code für die automatische Kodierung zu ändern
public class AppModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
try
{
return base.CreateModel(controllerContext, bindingContext, modelType);
}
catch (HttpRequestValidationException e)
{
HandleHttpRequestValidationException(bindingContext, e);
return null; // Encode here
}
}
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
try
{
return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
}
catch (HttpRequestValidationException e)
{
HandleHttpRequestValidationException(bindingContext, e);
return null; // Encode here
}
}
protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
{
var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
if (valueProviderCollection != null)
{
ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
}
string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
bindingContext.ModelMetadata.DisplayName);
bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
}
}
In Anwendung_Start:
ModelBinders.Binders.DefaultBinder = new AppModelBinder();
Beachten Sie, dass dies nur für Formularfelder funktioniert. Der gefährliche Wert wird nicht an das Controller-Modell übergeben, sondern in ModelState gespeichert und kann im Formular mit einer Fehlermeldung erneut angezeigt werden.
Gefährliche Zeichen in der URL können auf diese Weise behandelt werden:
private void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
HttpContext httpContext = HttpContext.Current;
HttpException httpException = exception as HttpException;
if (httpException != null)
{
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
var httpCode = httpException.GetHttpCode();
switch (httpCode)
{
case (int)HttpStatusCode.BadRequest /* 400 */:
if (httpException.Message.Contains("Request.Path"))
{
httpContext.Response.Clear();
RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
requestContext.RouteData.Values["action"] ="InvalidUrl";
requestContext.RouteData.Values["controller"] ="Error";
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
IController controller = factory.CreateController(requestContext, "Error");
controller.Execute(requestContext);
httpContext.Server.ClearError();
Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
}
break;
}
}
}
ErrorController:
public class ErrorController : Controller
{
public ActionResult InvalidUrl()
{
return View();
}
}
76 Stimmen
Beachten Sie, dass dieser Fehler auch auftreten kann, wenn Sie HTML-Entitätsnamen (&) oder Entitätsnummern (') in Ihrer Eingabe haben.
32 Stimmen
Nun, da es meine Frage ist, glaube ich, dass ich definieren kann, worum es eigentlich geht: einen ganzen Anwendungsprozess zum Absturz zu bringen und eine allgemeine Fehlermeldung auszugeben, weil jemand ein "<" eingegeben hat, ist übertrieben. Vor allem, weil man weiß, dass die meisten Leute einfach 'validateRequest=false' eingeben werden, um es loszuwerden, und damit die Schwachstelle wieder aufreißen
10 Stimmen
@DrewNoakes: Entitätsnamen (&) scheinen nach meinen Tests (getestet in .Net 4.0) kein Problem zu sein, obwohl Entitätsnummern (') die Validierung nicht bestehen (wie Sie sagten). Wenn Sie die Methode System.Web.CrossSiteScriptingValidation.IsDangerousString mit dem .Net Reflector zerlegen, werden Sie sehen, dass der Code speziell nach html-Tags (beginnend mit <) und Entity-Nummern (beginnend mit &#) sucht
9 Stimmen
Erstellen Sie eine neue Website in VS2014 unter Verwendung des Standard-MVC-Projekts und führen Sie sie aus. Klicken Sie auf den Registrierungslink, fügen Sie eine beliebige E-Mail hinzu und verwenden Sie "<P455-0r[!" als Kennwort. Derselbe Fehler aus der Box, nicht versuchen, etwas Bösartiges zu tun, wird das Passwort-Feld nicht angezeigt werden, so dass es nicht ein XSS-Angriff, aber der einzige Weg, um es zu beheben ist, vollständig zu entfernen Validierung mit der ValidateInput(false)? Der AllowHtml-Vorschlag funktioniert in dieser Situation nicht und führt immer noch zu demselben Fehler. Ein potenziell gefährlicher Request.Form-Wert wurde vom Client erkannt (Password="<P455-0r[!").
0 Stimmen
TL;DR setzen
<httpRuntime requestValidationMode="2.0" />
in web.config0 Stimmen
Siehe auch ASP.NET 4 Einschneidende Änderungen für einige Hintergrundinformationen.