81 votes

rails - "AVERTISSEMENT: impossible de vérifier le jeton CSRF authenticité" json concevoir des demandes

savez-vous comment il est possible de correctement récupérer le jeton CSRF à passer avec un JSON demande?

Je sais que pour des raisons de sécurité maintenant Rails est l'application de CSRF vérifier sur tous les type de demande (y compris JSON/XML).

http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails

Je pourrais mettre dans mon contrôleur skip_before_filter :verify_authenticity_token ,mais je lâche le FSCC protection (pas conseillé :-) ).

Dans ce similaire (pas encore accepté) question

Rails/Concevoir - la Création de nouveaux utilisateurs via json demande

Il est suggéré d'

Retrieve the token with <%= form_authenticity_token %>

La question est de savoir comment? Ai-je besoin de faire un premier appel à l'une de mes pages retrive le jeton, puis faire de mon réel d'authentification avec les Concevoir? Ou c'est un one-off que je peux tirer de mon serveur, puis de les utiliser de façon cohérente (jusqu'à ce que j'modifier manuellement sur le serveur lui-même)?

127voto

Ryan Crews Points 1111

EDIT:

Dans les Rails 4 que j'utilise maintenant ce que @genkilabs l'indique dans le commentaire ci-dessous:

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }

Qui, au lieu d'éteindre complètement la sécurité intégrée, tue toute session qui peut exister quand quelque chose touche le serveur sans le jeton CSRF.

(edit2: mise à jour de cette par les commentaires d'utiliser uniquement le style moderne de hachage (auparavant, il avait à la fois foo: bar" le style et l' :foo => "bar" de style.)


skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }

Ce serait d'éteindre le CSRF vérifier json postes/met qui ont correctement été marqués comme tels.

Par exemple, dans iOS définissant les éléments suivants à votre NSURLRequest où "paramètres" vos paramètres:


        [request setHTTPMethod:@"POST"];

        [request setValue:@"application/json" 
       forHTTPHeaderField:@"content-type"];

        [request setValue:@"application/json" 
       forHTTPHeaderField:@"accept"];

        [request setHTTPBody:[NSData dataWithBytes:[parameters UTF8String] 
                                            length:[parameters length]]];

18voto

tasos Points 313

Vous pouvez envoyer le jeton CSRF, après avoir réussi à connecter, à l'aide d'un en-tête personnalisé.

E. g, mettre ceci dans votre sessions#créer :

response.headers['X-CSRF-Token'] = form_authenticity_token

Exemple de journal-en-tête de réponse de fournir le jeton CSRF:

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Connection: Keep-Alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Mon, 22 Oct 2012 11:39:04 GMT
Etag: "9d719d3b9aabd413c3603e04e8a3933d"
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12)
Set-Cookie: [cut for readability] 
X-Csrf-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
X-Request-Id: 178746992d7aca928c876818fcdd4c96
X-Runtime: 0.169792
X-Ua-Compatible: IE=Edge

Ce Jeton est valide jusqu'à ce que vous vous connectez à nouveau, ou (log-out si vous soutenez par votre API). Votre client peut extraire et de stocker le jeton de la log-en-têtes de réponse. Ensuite, chaque POST/PUT/DELETE demande doit définir le X-CSRF Token-tête avec la valeur reçue dans le journal-dans le temps.

Exemple de POST-têtes avec le jeton CSRF:

POST /api/report HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, compress
Content-Type: application/json; charset=utf-8
Cookie: [cut for readability]
Host: localhost:3000
User-Agent: HTTPie/0.3.0
X-CSRF-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=

Documentation: form_authenticity_token

18voto

En effet, de manière très simple. Ne vous embêtez pas à changer les en-têtes.

Assurez-vous d'avoir:

<%= csrf_meta_tag %> in your layouts/application.html.erb

Il suffit de faire une cachée champ de saisie comme suit:

<input name="authenticity_token" 
               type="hidden" 
               value="<%= form_authenticity_token %>"/>

Ou si vous voulez un jquery ajax post:

$.ajax({     
    type: 'POST',
    url: "<%= someregistration_path %>",
    data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },                                                                                  
    error: function( xhr ){ 
      alert("ERROR ON SUBMIT");
    },
    success: function( data ){ 
      //data response can contain what we want here...
      console.log("SUCCESS, data="+data);
    }
});

Fondamentalement, lorsque vous affichez les données json il suffit d'ajouter un valide authenticity_token champ pour les données de publication et l'avertissement doit s'en aller...

3voto

Ce qui est inquiétant, c'est que dans les Rails 3.2.3 nous disposons maintenant de la CSRF avertissement dans la production.journal, mais la poste ne manque pas! Je le veux à l'échec comme il me protège des attaques. Et vous pouvez ajouter le jeton csrf avec jquery avant de filtre btw:

http://jasoncodes.com/posts/rails-csrf-vulnerability

2voto

DaCart Points 31

J'ai utilisé le ci-dessous. À l'aide? donc, si le type de contenu application/json;charset=utf-8 alors qu'il est encore à travailler.

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.include? 'application/json' }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X