Go to Hackademy website

L'authenticity token dans ruby on rails

Martin Catty

Posté par Martin Catty dans les catégories back

Ruby on Rails nous offre tellement de mécanismes d’abstraction qu’on en oublie parfois les bases.

Dans l’idée de notre article sur le fonctionnement des sessions, découvrons aujourd’hui pourquoi et comment fonctionne l’authenticity token.

Pourquoi un mécanisme de token ?

L’objectif est de prévenir les attaques de type Cross site request forgery.

Le fonctionnement est simple, vous vous authentifiez sur votre application A.

Sur une autre application B vous utilisez un formulaire ou un lien qui pointe en fait vers une action de l’application A sans que vous le sachiez.

En l’absence de mécanisme de contrôle vous pouvez modifier voire supprimer des resources sur l’application A sans même vous en rendre compte.

En tant qu’utilisateur il y a un premier de niveau de sécurité à apporter ; il s’agit d’éviter de rester connecter sur des services qu’on n’est pas entrain d’utiliser.

En somme dès que j’arrête d’utiliser un service je me déconnecte.

Côté développeur il faut absolument éviter de proposer des actions suceptibles de modifier des ressources sous forme de lien ou de form en GET, car dans ce cas les token ne vous protégeront pas comme nous le verrons ci dessous.

Au delà du GET on a déjà un premier volet de sécurité concernant la politique de sécurité des navigateurs pour les appels en AJAX depuis un autre domaine.

Voir à ce sujet les commentaires de l’article sur rails 4 à propos de CORS.

Comment le token peut parer à ça ?

Quand une vue avec un formulaire est rendue, Rails y ajoute un token aléatoire dans un champ caché, et dans la session de l’utilisateur.

À la soumission du formulaire, un contrôle sera fait pour s’assurer que le token est soumis et que sa valeur correspond à celle de la session.

Concrètement ça fonctionne comment ?

Le code de génération du token est très simple, il se trouve dans ActionPack:

# Sets the token value for the current session.
def form_authenticity_token
  session[:_csrf_token] ||= SecureRandom.base64(32)
end

La vérification de la requête est elle aussi basique, Rails va juste vérifier qu’il ne s’agit pas d’une requête GET, HEAD, que la protection est activée et que le token est présent dans les params ou dans les headers, dans le cas d’une requête venant d’un autre domaine.

def verified_request?
  !protect_against_forgery? || request.get? || request.head? ||
    form_authenticity_token == params[request_forgery_protection_token] ||
    form_authenticity_token == request.headers['X-CSRF-Token']
end

Voilà tout pour cet article sur le fonctionnement des tokens.

On trouve trop souvent des articles ou des fils de discussion qui recommandent de désactiver la protection au moindre souci (souvent dans le cas d’utilisation conjointe avec AJAX).

Ne faites pas ça, creusez vous la tête et fixez le problème plutôt que d’ouvrir des brèches de sécurité.

L’équipe Synbioz.

Libres d’être ensemble.

Articles connexes

Une brève histoire d'Elixir et Erlang/OTP

31/01/2019

Je développe depuis plusieurs années en Ruby. Depuis mon arrivée chez Synbioz, j’expérimente en plus avec Elixir de façon assez naturelle. En quoi Elixir est-il différent, me demanderez-vous ? Pour...

Écrire une thread pool en Ruby

10/01/2019

Pouvoir exécuter plusieurs tâches en parallèle, que ce soit dans un script ou une application, peut être vraiment très utile, surtout dans le cas où le traitement de ces tâches peut être très long....

Translation temporelle

31/05/2018

Cette semaine, je me suis essayé à un nouveau format d’article qui se présente sous la forme d’une nouvelle de Science-Fiction. Je tiens en passant à remercier Valentin pour ses illustrations....

Authentifier l'accès à vos ressources avec Dragonfly

11/05/2017

Pour ceux qui ne connaissent pas Dragonfly, c’est une application Rack qui peut être utilisée seule ou via un middleware. Le fait que ce soit une application Rack la rend compatible avec toutes les...