2009-10-01 14 views
5

Tengo una aplicación ASP.NET MVC similar a un calendario. Según el ejemplo de NerdDinner, estoy actualizando los resultados de mi página de edición usando UpdateMethod()ASP.NET MVC UpdateModel vulnerable a la piratería?

En mi aplicación, ciertos eventos son totalmente personalizables y algunos solo son parcialmente personalizables. Aunque el formulario de edición para editar los eventos parcialmente personalizables solo tiene esos campos disponibles, obviamente alguien podría crear su propio formulario con los datos faltantes y publicar en mi sitio. Si lo hacen, ¿qué impedirá que alguien cambie alguno/todos los campos? Peor aún, ¿qué pasaría si intentaran cambiar la identificación (clave principal)?

Parece que UpdateModel() es vulnerable a la piratería muy básica. ¿Son legítimos mis temores o hay algo que me falta?

// POST: /MyEvents/Edit/2 
[AcceptVerbs(HttpVerbs.Post), Authorize] 
public ActionResult Edit(int id, FormCollection formValues) 
{ 
    MyEvent myevent = eventRepository.GetMyEvent(id); 

    try 
    { 
     UpdateModel(myevent); 
     eventRepository.Save(); 
     return RedirectToAction("Details", new { id = myevent.MyEventId }); 
    } 
    catch 
    { 
     ModelState.AddRuleViolations(myevent.GetRuleViolations()); 
     return View(new MyEventFormViewModel(myevent)); 
    } 
} 
+0

modo fácil/seguro = cree modelos de formulario (en), luego asigne esos a sus entidades a través de Automapper. – mxmissile

Respuesta

9

Falta la sección "Seguridad de encuadernación del modelo". Siempre debe incluir una lista blanca de propiedades que se puedan actualizar mediante cualquiera de sus métodos de entrada de usuario.

Por ejemplo, desde NerdDinner:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Include="Title, Address")] Dinner dinner) 
{ 

} 

o si está llamando UpdateModel, puede crear una matriz de cadenas de propiedades permitidas y hacer

UpdateModel(myObject, allowedProperties); 

Puede bloquear las clases ellos mismos para que solo ciertas propiedades sean actualizadas también.

[Bind(Include="MyProp1,MyProp2,MyProp3")] 
public partial class MyEntity { } 
+0

Excelente hasta que tenga 20 o 30 elementos en una pantalla de entrada de datos, entonces se convierte en un dolor =) –

+2

También puede usar una lista negra :) – womp

7

Sus miedos son correctos. Esto se llama asignación masiva. Puede proteger su código marcando su clase con BindAttribute y estableciendo Exclude/Include propiedades.

1

Hay sobrecargas de UpdateModel que toman una matriz de cadenas de propiedades para actualizar. Estas sobrecargas solo actualizarán las propiedades nombradas.

Puede haber otras formas más fáciles/más declarativas para lograr esto, no soy un experto en el enlace de datos MVC.

1

Puede marcar campos en su modelo que deben ser ignorados por la actualización o pasar una lista de campos incluidos/excluidos usando una de las otras sobrecargas UpdateModel.

4

Es perfectamente posible que una persona emprendedora/malicioso para asignar los campos a cualquiera de las propiedades del modelo. Hay algunas maneras de evitar esto

Lo más simple es utilizar las sobrecargas de propiedades de exclusión/inclusión de UpdateModel como se ha mencionado anteriormente. La desventaja de esto es que el método solo acepta una matriz de cadenas, lo que a veces puede significar que el código se desincroniza si lo renombra.

Otra forma es utilizar un DTO simple que contenga los campos enlazados, luego puede tomar el DTO y hacer lo que quiera con su objeto de evento, esto obviamente agrega otra clase y es mucho más manual pero le da mucho más Control

public ActionResult(int id, EditForm form) { 
    MyEvent event = _eventRepository.GetMyEvent(id); 
    event.Name = form.Name; //etc; 
    if (User.IsInRole("Organiser")) { 
     event.Date = form.Date; 
    } 
    return ... 
} 

Otra forma podría ser a través de un modelo de ligante al cliente para su clase MyEvent que sólo se une a su campo deseado, aunque algo excesivo.

Cuestiones relacionadas