2009-02-16 8 views
5

Sé cómo usar el atributo AntiForgeryToken de MVC y su asistente HTML asociado para ayudar a XSRF a proteger los formularios POST de mi aplicación.¿Cómo aseguro mis llamadas JSONResult GET?

¿Se puede hacer algo similar con JsonResults que implementa GET?

Por ejemplo, mi vista contiene una llamada onSubmit jQuery como tales:

$.getJSON("/allowActivity/YesOrNo/" + someFormValue, "{}", function(data) { 
    if(data.Allow) { 
    //Do something. 
    } 
}); 

quiero para asegurarse de que esta JsonResult sólo es exigible a partir de la página deseada.

EDIT:

He encontrado this post sobre una pregunta similar, sin una respuesta concreta.

¿Cuál es la forma más fácil de garantizar que mi URL GET (no destructiva) se consuma solo mediante una llamada AJAX desde mi propia página?

Respuesta

8

Puede usar el AntiForgeryToken combinado con alguna lógica personalizada. La creación del token AntiForgery en el servidor es la misma, pero por defecto el valor no está incluido en su XmlHttpRequest.

El valor de este token está en la cookie HTTP "__RequestVerificationToken" y también debe estar en los datos del formulario publicados en el servidor. Así incluir un par clave/valor en su XmlHttpRequest y utilizar el ValidateAntiForgeryToken - atributo en el controlador

EDIT:

Hoy he intentado usar el AntiForgeryToken para Ajax pide a mí mismo y funciona bien. Sólo tiene que utilizar el siguiente javascript:

$.post('my_url', $.getAntiForgeryTokenString(), function() { ... }); 

$.getAntiForgeryTokenString = function() { 
    return $(document.getElementsByName("__RequestVerificationToken")).fieldSerialize(); 
}; 

En el lado del servidor que no tiene que cambiar su código - sólo tiene que utilizar el atributo ValidateAntiForgeryToken- para su acción.

Esperanza esto ayuda

+0

¿Cómo se integrará el valor __RequestVerificationToken con el .getJSON $ o $ .ajax llamada? Recuerde, esta es una solicitud GET. –

+0

Lea "Divulgación de token en la URL" de http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet "Si se garantiza que las acciones confidenciales del lado del servidor solo responderán a las solicitudes POST, entonces no es necesario incluir el token en las solicitudes GET "La clave es asegurarse de que su GET no modifique los datos. De lo contrario, no necesita proteger las solicitudes GET –

0

Puede hacer algo similar a los métodos anti XSRF. Simplemente genere alguna ID, insértela en el javascript y cuando el usuario llame a su url JSON, haga que esa url incluya la ID generada y verifique si está allí.

Una defensa contra XSRF también utiliza el ID de sesión como clave, aunque esto no impide que el usuario lo ejecute desde otro sitio web para su propia cuenta.

Algún hash basado en la sesión y el tiempo podría hacer el truco. Por supuesto, si el usuario copia el valor de JS, aún puede ejecutarlo desde otra ubicación, pero puede hacer que ese valor expire cada x minutos. Otra opción es establecer una cookie con JS y leerla en el servidor.

Espero que esto te brinde algunas ideas para que comiences.

1

primer lugar por qué no usar $ .post (url, de datos, de devolución de llamada, 'json') en lugar de getJSON? Y como dijo kleolb02, es posible agregar valor de la cookie a los datos de envío utilizando cookie plugin - {__RequestVerificationToken: $ .cookie ('__ RequestVerificationToken')}

+0

Eso suena bien. Esperaba evitar el POST para una llamada ajax tan simple, pero ciertamente lo haré si es la única forma de protegerlo. –

+0

Debe usar la publicación para actualizar algunos datos en el servidor. Este es un escenario común. Y, por lo que recuerdo, AntiForgeryToken solo está trabajando con solicitudes de correos (solo buscan un valor en FormCollection). – zihotki

+0

Esto no es una actualización, es un simple "obtener". Simplemente me gustaría restringir el consumo de la URL a las llamadas AJAX de mi propia página. –

1

he utilizado un código similar en un proyecto ASP.NET MVC utilizar en la función de desenfoque de un elemento sin tener una forma Ajax. Este código proporciona llenar un campo de texto con datos del servidor cuando se produce un determinado evento de desenfoque del elemento HTML.

Espero que esto ayude también. Aquí está mi código:

Javascript: Código

var mytext = { 'myText': 'example text' }; 
$.post('/MyController/JsonResultMethod', AddAntiForgeryToken(myText), function (resultData) { 
     $('#htmlElement').val(resultData); 
}); 
AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

C-Sharp:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public JsonResult SeoString(string myText) 
    { 
     try 
     { 
      // do something here 
      return this.Json("result text"); 
     } 
     catch (Exception) 
     { return this.Json(string.Empty); } 
    } 
Cuestiones relacionadas