2009-08-28 25 views
8

Actualmente estoy desarrollando una aplicación MVC en ASP.net. Estoy usando AJAX.ActionLink para proporcionar un enlace de eliminación en una lista de registros, sin embargo, esto es muy inseguro. He puesto esto:ASP.net MVC AntiForgeryToken sobre AJAX

<AcceptVerbs(HttpVerbs.Post)> 

Durante la función de hacer el borrado, lo que detiene la función que se llama simplemente mediante una dirección URL. Sin embargo, el otro agujero de seguridad que todavía existe es que si tuviera que hacer una página HTML básico con este contenido:

<form action="http://foo.com/user/delete/260" method="post"> 
<input type="submit" /> 
</form> 

todavía sería perfoming un puesto, pero desde un lugar diferente.

¿Es posible utilizar AntiForgeryToken con AJAX ActionLink? Si es así, ¿es este un enfoque seguro? ¿Hay más agujeros de seguridad que no me he dado cuenta?

Respuesta

2

No conozco específicamente el AJAX ActionLink, pero es posible desde una página de WebForms publicar en una acción MVC con los atributos [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken].

Puede utilizar la reflexión para llegar a los métodos utilizados para MVC ajustar la entrada de galletas y forma coincidente utilizado para la validación MVC.

Ver esta respuesta: Using an MVC HtmlHelper from a WebForm

9

Echa un vistazo a este blog post.

Digamos que tiene un método de acción como esto:

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] public ActionResult DeleteAccount(int accountId) { // delete stuff }

Y llamarlo a través de:

$.post('/home/DeleteAccount', { accountId: 1000 }, function() { alert('Account Deleted.'); });

Desde el POST no incluye el AntiForgeryToken, fallará

Afortunadamente, no se requiere mucho cerebro para solucionarlo. Todo el cliente componente lateral de AntiForgeryToken hace es poner el token en un campo oculto básico . Por lo tanto, solo necesita extraer esos datos e incluirlos en su llamada AJAX.

var token = $('input[name=__RequestVerificationToken]').val();

$.post('/home/DeleteAccount', { accountId: 1000, '__RequestVerificationToken': token }, function() { alert('Account Deleted.'); });

Ten en cuenta que si tiene varios formularios de la página con múltiples AntiForgeryTokens, tendrá que especificar cuál de ellos desea en su selector de jQuery . Otra Gotcha es si está utilizando serializeArray() función de jQuery, tendrá añadir un poco diferente:

var formData = $('#myForm').serializeArray(); var token = $('input[name=__RequestVerificationToken]').val(); formData.push({ name: '__RequestVerificationToken', value: token });

$.post('/home/DeleteAccount', formData, function() { alert('Account Deleted.'); });

Actualización: El enlace se ha fijado.

+1

de ese vínculo roto – Keith

+0

No es necesario formData.push ({nombre: '__RequestVerificationToken', valor: token}); ya que serializeArray() devolverá todas las entradas en el formulario, que incluyen el campo oculto __RequestVerificationToken. –

+0

Sí, sí necesita esto en publicaciones AJAX (utilizando MVC 4 actual y MS discreto AJAX = jQuery) !!! –

0

No he usado ayudantes de AJAX, pero no veo ningún motivo por el que no pueda usar un enlace. Personalmente, utilizaría un controlador de eventos onload para crear discretamente un enlace desde el formulario mismo y luego eliminar el formulario.

6

Puede utilizar AntiForgeryToken con Ajax.ActionLink pero hay que insertar manualmente la AntiForgeryToken en la cabecera de la solicitud de esta manera:

function GetAntiForgeryToken(){ 
    var tokenWindow = window; 
    var tokenName = "__RequestVerificationToken"; 
    var tokenField = $(tokenWindow.document).find("input[type='hidden'][name='" +  tokenName + "']"); 
    if (tokenField.length == 0) {return null;} 
    else { 
     return { 
     name: tokenName, 
     value: tokenField.val() 
     }; 
    } 
}; 

Entonces, podemos utilizar $ .ajaxPrefilter para insertarlo en el encabezado:

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) { 
     var token = GetAntiForgeryToken(); 
     jqXHR.setRequestHeader(token.name, token.value); 
    } 
); 

escribí un post sobre ello here. ¡Espero que esto ayude!

+0

Esto envía el token en el encabezado, pero el filtro [ValidateAntiForgeryToken] requiere esto en los datos del formulario ... – iGanja

6

Uso AntiForgeryToken con Ajax.ActionLink

Además de jjwhite01 respuesta; para insertar el token de datos de formulario, utilice option.data en prefiltro

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) { 
     if (options.type !== "GET") { 
      var token = GetAntiForgeryToken(); 
      if (token !== null) { 
       if (options.data.indexOf("X-Requested-With") === -1) { 
        options.data = "X-Requested-With=XMLHttpRequest" + (options.data === "") ? "" : "&" + options.data; 
       } 
       options.data = options.data + "&" + token.name + '=' + token.value; 
      } 
     } 
    } 
); 
+1

El script ajax no intrusivo en MVC 4 incluye - options.data.push ({name: "X-Requested-With") ", value:" XMLHttpRequest "}) - por lo que ahora es innecesario verificar y agregar esto – Brent

Cuestiones relacionadas