2012-05-23 28 views
5

Estoy interesado en la protección de mi aplicación web mediante el uso de generación de un token csrf. Mi pregunta es ¿cómo debo enviar ese token nuevamente a un servidor: usando query param o http header x-csrf-token?token csrf usando

y cuál es la diferencia

Respuesta

9

Dado que está utilizando Express, puede utilizar su middleware CSRF (Conéctate): http://www.senchalabs.org/connect/csrf.html

Puedes retirar la fuente comentado aquí: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js

Todos lo que debe hacer es incluir ese middleware y luego en sus formularios POST (o PUT, etc., cualquiera que sea la solicitud que mute el estado) configure la variable _csrf para que tenga el valor req.session._csrf.

Comprobar ejemplo aquí: https://github.com/senchalabs/connect/blob/master/examples/csrf.js

ACTUALIZACIÓN

Desde Conectar 2.9.0 debe utilizar en lugar de req.csrfToken()req.session._csrf

ejemplo completo: https://github.com/senchalabs/connect/blob/master/examples/csrf.js

Commit: https://github.com/senchalabs/connect/commit/70973b24eb1abe13b2da4f45c1edbb78c611d250

Update2

El middleware de conexión se divide en diferentes módulos (y repos asociado), se puede encontrar a todos ellos (incluyendo el CSRF uno) aquí: https://github.com/senchalabs/connect#middleware

+0

Sí lo sé, pero yo quiero saber lo que es mejor usar: un campo de cabecera X-CSRF token u oculto? – Erik

+0

Como puede ver aquí: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js # L69 Express comprueba primero el valor POST, luego el valor de la cadena de consulta y luego el encabezado x-csrf-token, por lo que lo mejor sería pasar un campo _csrf oculto con el valor. – alessioalex

+0

Quiero usar csrf-token en solicitudes ajax ¿cuál es el enfoque que debo usar entonces? – Erik

3

Desde mi punto de vista, se debe utilizar el parámetro POST csrf al enviar formularios, en un campo oculto. Este es el único camino a seguir.

Pero en el caso de las solicitudes AJAX, le recomendaría utilizar el encabezado X-CSRF-Token. Principalmente porque, si se realiza correctamente, le ahorrará la molestia de recordar agregar el token para cada solicitud POST. O, al usar bibliotecas como jQuery Form, agregar parámetros POST adicionales en el momento del envío puede convertirse en un hackeo.

Por ejemplo, si utiliza jQuery para sus solicitudes AJAX, le proporciona a hook que puede usar para configurar el X-CSRF-Token de forma automática y transparente antes de realizar la solicitud. Por lo tanto, se requiere muy poca modificación del código del lado del cliente. Y disparas la genialidad de tu código.

-

un ejemplo de implementación, que utilizo con éxito en prácticamente todos mis proyectos, basado en Django de uno, sería:

jQuery(document).ajaxSend(function(event, xhr, settings) { 

    function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie != '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
     var cookie = jQuery.trim(cookies[i]); 
     // Does this cookie string begin with the name we want? 
     if (cookie.substring(0, name.length + 1) == (name + '=')) { 
      cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
      break; 
     } 
     } 
    } 
    return cookieValue; 
    } 

    function sameOrigin(url) { 
    // url could be relative or scheme relative or absolute 
    var host = document.location.host; // host + port 
    var protocol = document.location.protocol; 
    var sr_origin = '//' + host; 
    var origin = protocol + sr_origin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 
      // or any other URL that isn't scheme relative or absolute i.e relative. 
      !(/^(\/\/|http:|https:).*/.test(url)); 
    } 

    function safeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) { 
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrf.token')); 
    } 
}); 

En el lado del servidor, que acababa de necesita establecer una cookie que contenga el token CSRF para que sea fácil para el cliente obtener el token. He sustituido el app.use(express.csrf()) con:

app.use((function(options) { 

    var csrf = express.csrf(options); 

    return function(req, res, next) { 

    function onCsrfCalled() { 
     var token = req.session._csrf; 
     var cookie = req.cookies['csrf.token']; 

     // Define a cookie if not present 
     if(token && cookie !== token) { 
     res.cookie('csrf.token', token); 
     } 

     // Define vary header 
     res.header('Vary', 'Cookie'); 

     next(); 
    } 

    csrf(req, res, onCsrfCalled); 
    } 
})()); 
Cuestiones relacionadas