ruby-on-rails authenticity - Comprendre le jeton d'authenticité Rails




token session (9)

Le Authenticity Token est la méthode des rails pour prevent les attaques par falsification de requête inter-site (CSRF ou XSRF) .

Pour faire simple, il s'assure que les requêtes PUT / POST / DELETE (méthodes pouvant modifier le contenu) de votre application web proviennent du navigateur du client et non d'un tiers (un attaquant) ayant accès à un cookie créé du côté client.

Je suis confronté à quelques problèmes concernant Authenticity Token in Rails, comme je l'ai plusieurs fois maintenant.

Mais je ne veux vraiment pas résoudre ce problème et continuer. J'aimerais vraiment comprendre le jeton Authenticité. Eh bien, ma question est, avez-vous une source complète d'informations sur ce sujet ou souhaitez-vous passer votre temps à expliquer dans les détails ici?


Le jeton d'authenticité est conçu pour que vous sachiez que votre formulaire est envoyé depuis votre site Web. Il est généré à partir de la machine sur laquelle il s'exécute avec un identifiant unique que seule votre machine peut connaître, ce qui permet d'éviter les attaques de falsification de requêtes intersites.

Si vous avez simplement des difficultés avec les rails qui refusent l'accès au script AJAX, vous pouvez utiliser

<%= form_authenticity_token %>

pour générer le jeton correct lorsque vous créez votre formulaire.

Vous pouvez en lire plus à ce sujet dans la documentation .


Attention, le mécanisme de jeton d'authenticité peut entraîner des conditions de concurrence si vous avez plusieurs demandes simultanées provenant du même client. Dans cette situation, votre serveur peut générer plusieurs jetons d'authenticité alors qu'il ne devrait y en avoir qu'un, et le client recevant le jeton précédent dans un formulaire échouera lors de la prochaine requête car le jeton de cookie de session a été remplacé. Il y a une note sur ce problème et une solution pas entièrement triviale ici: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/


Le jeton d'authenticité est utilisé pour empêcher les attaques CSFF (Cross-Site Request Forgery). Pour comprendre le jeton d'authenticité, vous devez d'abord comprendre les attaques CSRF.

CSRF

Supposons que vous êtes l'auteur de bank.com . Vous avez un formulaire sur votre site qui est utilisé pour transférer de l'argent sur un autre compte avec une requête GET:

Un hacker pourrait simplement envoyer une requête HTTP au serveur en disant GET /transfer?amount=$1000000&account-to=999999 , non?

Faux. L'attaque des pirates ne fonctionnera pas. Le serveur pensera fondamentalement?

Huh? Qui est ce type qui essaie d'initier un transfert? Ce n'est pas le propriétaire du compte, c'est certain.

Comment le serveur le sait-il? Parce qu'il n'y a pas de cookie session_id authentifiant le demandeur.

Lorsque vous vous connectez avec votre nom d'utilisateur et votre mot de passe, le serveur définit un cookie session_id sur votre navigateur. De cette façon, vous n'avez pas à authentifier chaque demande avec votre nom d'utilisateur et votre mot de passe. Lorsque votre navigateur envoie le cookie session_id , le serveur connaît:

Oh, c'est John Doe. Il s'est connecté avec succès il y a 2.5 minutes. Il est bon d'y aller.

Un pirate pourrait penser:

Hmm. Une requête HTTP normale ne fonctionnera pas, mais si je pouvais obtenir ma main sur ce cookie session_id , je serais en or.

Le navigateur des utilisateurs contient un ensemble de cookies pour le domaine bank.com . Chaque fois que l'utilisateur fait une demande au domaine bank.com , tous les cookies sont envoyés. Y compris le cookie session_id .

Donc, si un hacker peut vous amener à faire la demande GET qui transfère de l'argent sur son compte, il aura du succès. Comment pourrait-il vous tromper pour le faire? Avec Cross Site Request Forgery.

C'est assez simple, en fait. Le hacker pourrait juste vous amener à visiter son site Web. Sur son site Web, il pourrait avoir la balise d'image suivante:

<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">

Lorsque le navigateur des utilisateurs rencontre cette balise d'image, une requête GET est envoyée à cette URL. Et puisque la requête vient de son navigateur, elle enverra avec elle tous les cookies associés à bank.com . Si l'utilisateur s'est récemment connecté à bank.com ... le cookie session_id sera défini, et le serveur pensera que l'utilisateur a l'intention de transférer $ 1,000,000 au compte 999999!

Eh bien, ne visitez pas les sites dangereux et tout ira bien.

Cela ne suffit pas. Que se passe-t-il si quelqu'un publie cette image sur Facebook et qu'elle apparaît sur votre mur? Que se passe-t-il s'il est injecté dans un site lors d'une attaque XSS?

Ce n'est pas si grave. Seules les requêtes GET sont vulnérables.

Pas vrai. Un formulaire qui envoie une requête POST peut être généré dynamiquement. Voici l'exemple du Guide Rails sur la sécurité :

<a href="http://www.harmless.com/" onclick="
  var f = document.createElement('form');
  f.style.display = 'none';
  this.parentNode.appendChild(f);
  f.method = 'POST';
  f.action = 'http://www.example.com/account/destroy';
  f.submit();
  return false;">To the harmless survey</a>

Jeton d'authenticité

Lorsque votre ApplicationController a ceci:

protect_from_forgery with: :exception

Ce:

<%= form_tag do %>
  Form contents
<% end %>

Est compilé dans ceci:

<form accept-charset="UTF-8" action="/" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
  Form contents
</form>

En particulier, ce qui suit est généré:

<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />

Pour se protéger contre les attaques CSRF, si Rails ne voit pas le jeton d'authenticité envoyé avec une requête, il ne considérera pas la demande comme sûre.

Comment un attaquant est-il supposé savoir ce qu'est ce jeton? Une valeur différente est générée aléatoirement chaque fois que le formulaire est généré:

Une attaque XSS (Cross Site Scripting) - voilà comment. Mais c'est une vulnérabilité différente pour un jour différent.


Qu'est-ce qu'un authentication_token?

Il s'agit d'une chaîne aléatoire utilisée par l'application Rails pour s'assurer que l'utilisateur demande ou exécute une action depuis la page de l'application, et non depuis une autre application ou un autre site.

Pourquoi un authentication_token est-il nécessaire?

Pour protéger votre application ou votre site contre les falsifications de requêtes intersites.

Comment ajouter un authentication_token à un formulaire?

Si vous générez un formulaire en utilisant form_for tag, un identificateur authentication_token est automatiquement ajouté sinon vous pouvez utiliser <%= csrf_meta_tag %> .


Méthodes où authenticity_token est requis

authenticity_token est requis dans le cas de méthodes idempotentes comme post, put et delete, car les méthodes Idempotent affectent les données.

Pourquoi est-il nécessaire

Il est nécessaire d'empêcher les mauvaises actions. authenticity_token est stocké en session, chaque fois qu'un formulaire est créé sur des pages web pour créer ou mettre à jour des ressources puis qu'un jeton d'authenticité est stocké dans un champ caché et qu'il est envoyé avec le formulaire sur le serveur. Avant d'exécuter l'action, l'utilisateur envoyé authenticity_token est contre-vérifié avec authenticity_token stocké en session. Si authenticity_token est identique, le processus se poursuit sinon il n'effectue pas d'actions.


puisque Authenticity Token est si important, et dans Rails 3.0+, vous pouvez utiliser

 <%= token_tag nil %>

créer

<input name="authenticity_token" type="hidden" value="token_value">

nulle part


Qu'est-ce que CSRF?

Le jeton d'authenticité est une contre-mesure à la contrefaçon de demande inter-site (CSRF). Qu'est-ce que CSRF, demandez-vous?

C'est un moyen qu'un pirate peut potentiellement pirater des sessions sans même connaître les jetons de session.

Scénario

  • Visitez le site de votre banque, connectez-vous.
  • Ensuite, visitez le site de l'attaquant (par exemple, une annonce sponsorisée provenant d'une organisation non approuvée).
  • La page de l'attaquant inclut un formulaire avec les mêmes champs que le formulaire "Transfert de fonds" de la banque.
  • L'attaquant connaît vos informations de compte et a pré-rempli les champs de formulaire pour transférer de l'argent de votre compte vers le compte de l'attaquant.
  • La page de l'attaquant inclut Javascript qui soumet le formulaire à votre banque.
  • Lorsque le formulaire est envoyé, le navigateur inclut vos cookies pour le site de la banque, y compris le jeton de session.
  • La banque transfère de l'argent au compte de l'attaquant.
  • Le formulaire peut être dans un iframe invisible, donc vous ne savez jamais que l'attaque s'est produite.
  • C'est ce qu'on appelle Cross-Site Request Forgery (CSRF).

Solution CSRF :

  • Le serveur peut marquer des formulaires provenant du serveur lui-même
  • Chaque formulaire doit contenir un jeton d'authentification supplémentaire en tant que champ masqué.
  • Le jeton doit être imprévisible (l'attaquant ne peut pas le deviner).
  • Le serveur fournit un jeton valide dans les formulaires de ses pages.
  • Le serveur vérifie le jeton lorsqu'il est posté, rejette les formulaires sans jeton approprié.
  • Exemple de jeton: identifiant de session chiffré avec la clé secrète du serveur.
  • Rails génère automatiquement de tels jetons: consultez le champ de saisie authenticity_token sous chaque forme.

http://railsforzombies.org/ est un bon. Présentation d'une toute nouvelle façon d'apprendre Ruby on Rails dans le navigateur sans configuration supplémentaire nécessaire.





ruby-on-rails ruby authenticity-token