9
votes

Comment est-il possible pour un utilisateur légitime de soumettre un jeton CSRF non valide dans les rails?

Nos journaux d'erreur contiennent occasionnellement des soumissions de formulaire légitime causant ActionController :: InvalidAuthentiCityToken Erreurs.

Mon hypothèse est que le jeton CSRF stocké dans le cookie de session de l'utilisateur a changé à un moment donné après le chargement du formulaire mais avant d'être soumis. Cela provoque une inadéquation entre le jeton posté et le jeton dans le cookie, conduisant à cette erreur.

Étant donné qu'un cookie de session Rails n'expire que lorsque la session de navigation se termine (c'est-à-dire lorsque le navigateur Web est fermé), quelles sont les façons dont ce cookie (et le jeton CSRF contient-il) peuvent être changés sans fermer le navigateur?

Nous utilisons des cookies pour stocker des données de session, ce qui est le comportement par défaut des rails.


0 commentaires

5 Réponses :


0
votes

Si le navigateur de fermeture n'est pas une option. Ensuite, vous devez vous déconnecter de l'utilisateur. Pour atteindre cet endroit, le code suivant dans ApplicationController.

Rescue_from ActionController :: InvalidAuthenticityToken do | Exception |

signe signe_out_user # exemple de méthode qui détruira les cookies utilisateur

fin

PS: ci-dessus vient de http: // guides. rubyonrails.org/security.html#cross-site-request-forgery-csrf Ainsi, référez-le pour plus d'informations.


3 commentaires

Merci. Le chemin en question concerne uniquement les utilisateurs authentifiés, donc je ne pense pas qu'ils se sont déconnectés avant l'exception CSRF.


Vrai. Ainsi, lorsque le CSRF est changé pour des raisons inconnues. Ils devaient être déconnectés. Pouvez-vous exclure la possibilité que les utilisateurs dans ce cas soient modifiés de la CSRF intentionnellement?


Pas avec une certitude absolue, mais c'est très peu probable. Donc, à votre avis, il n'y a pas d'autre moyen que le jeton puisse devenir invalide?



8
votes

L'utilisateur aurait pu être déconnecté et de retour dans, mais avait un onglet avec un formulaire ouvert de l'ancienne session. Cela enverrait le vieux jeton.


1 commentaires

Salut, merci pour cette réponse. Y a-t-il une autre façon que cela pourrait arriver?



1
votes

Utilisez-vous un formulaire AJAX pour soumettre la demande? Votre page a-t-elle plusieurs formulaires? Si tel est le cas, vérifiez votre code si le jeton CSRF correct est soumis avec la demande. Nous avions un problème similaire que la page est rendue avec un jeton CSRF et nous avons utilisé ce jeton pour soumettre un formulaire un et nous aurions un nouveau jeton CSRF, mais la seconde envoie un ancien jeton CSRF qui entraîne une erreur. Je ne sais pas comment cela est utile, mais je veux partager un problème similaire confronté à moi


2 commentaires

Merci d'avoir répondu! Non aux deux, désolé.


C'est exactement là que mon problème était: Rendu de multiples formes, en particulier avec Render_ASync, rend cette chose facile à trébucher pour



1
votes

Vous avez écrit: Étant donné qu'un cookie de session Rails expire uniquement lorsque la session se termine de navigation (lorsque le navigateur est fermé), quelles sont les façons dont ce cookie (et le CSRF jeton qu'il comprend) peuvent être modifiés sans fermer le navigateur?


Tout d'abord, votre hypothèse est valable. Comment vous y êtes arrivé peut-être utile d'envisager, cependant.

La présomption que vous les besoins actuels se concentrer sur deux niveaux.

One: un cookie stocké ne soit pas effacé lorsque la navigation sur le Web fin de la session, à moins que quelque chose a été codé de cette façon; le cookie est probablement persistant jusqu'à ce qu'il cookie délai d'attente, il est donc probable que l'accès suivant de la page utilisera l'ancien jeton, mais parce que les développeurs permettent généralement la « nouvelle connexion » pour actualiser la page, ils sont susceptibles de rafraîchir aussi le jeton à cet instant. Voir @ réponse Shikhar-Mann pour mieux comprendre le sign_out_user.

Deux: le cookie ne doit pas être changé pour ce problème, il est l'inadéquation de l'CSRF jeton qui est la question.

La question de la racine doit être: quels sont les moyens que nous pouvons avoir un jeton CSRF ne correspondent pas, ce qui serait plus facile de répondre: les anciennes données sur le client en raison d'une longue attente, ce qui provoque un délai d'attente sur le serveur, qui Invalide le jeton CSRF pendant le délai. Si la page Web n'est pas configuré / créé aussi le temps et redirection, le client / utilisateur ne connaîtrait jamais.

En outre, pourrais-je suggérer que le CSRF sont pas conservées? Il est vraiment pas utile de le faire si vous pouvez accéder à des données de formulaire; En général, je crée un champ caché avec les données CSRF et l'utiliser pour republier à la place. CSRF ne vit pas très longtemps, et les données de session est fait persister.


5 commentaires

Merci pour cette réponse détaillée. Il semble qu'il semble impossible pour le jeton CSRF expirer en raison du passage du temps, car il est configuré d'expirer uniquement à la fin de la session.


Ce n'est pas vraiment la façon dont le CSRF fonctionne. Il expirera après un certain temps car le serveur l'expirera - à la fin de la session latérale du serveur.


Vous pouvez avoir raison! Dans les rails, cependant, la session est stockée dans le cookie, pas sur le serveur.


Valider que le cookie n'a pas de délai d'attente. Si c'est le cas, cela pourrait être la source de votre douleur. Comme vous avez attiré des séances de rails, vous ne comprenez pas généralement (!), Et cela ressemble à des rails 4 est confirmé à pas.


Bonne idée. Malheureusement, ça ne tente pas!



4
votes

Voici ce que nous savons:

  • Les soumissions de formulaire légitime qui provoquent un InvalidAuthenticityToken ont perdu leur jeton CSRF d'origine.
  • Le jeton est conservé dans la session, qui est conservé dans un cookie crypté. Donc, cette erreur signifie que leur cookie de session a changé depuis la création du formulaire.
  • Le cookie de session n'expire pas à moins que la fenêtre du navigateur de l'utilisateur soit fermée.

    Je crois maintenant qu'il existe deux manières que des jetons CSRF non valides peuvent être soumis par des utilisateurs légitimes.

    Notez que ceux-ci s'appliquent spécifiquement aux rails 4.2. Si je comprends bien, la fonctionnalité "jetons CSRF par formulaire" dans les rails 5 peut les atténuer.

    1. Changement de session dans un autre onglet

    Selon @ Réponse de Crazymykl , l'utilisateur pourrait ouvrir le formulaire, puis vous déconnecter dans un autre onglet. Cela causerait que le cookie de session stocké dans le navigateur de l'utilisateur change. Quand ils sont revenus à l'onglet d'origine et ont soumis le formulaire, le jeton de la forme ne correspondrait pas au jeton de la session et que l'erreur se déroulerait.

    2. Caching

    Selon Ce bogue de rails , Safari se comporte étrangement à la mise en cache dans certaines circonstances. Dites-lui de rouvrir avec les mêmes fenêtres que la dernière fois (via Safari> Préférences> Général ), ouvrant le formulaire et quitter les résultats de safari dans le formulaire étant réaffiche.

    Soumettre que la forme mise en cache provoque une erreur CSRF. Comme l'ouvrant du bogue se termine, il semble que Safari met en cache la page, mais goutte le cookie de session. D'où l'inadéquation.

    La solution à ce problème consiste à définir un en-tête de contrôle cache-cache avec la directive no-store . (Différence entre no-cache et no-store expliqué ici ).

    Exemples supplémentaires Bienvenue :).


0 commentaires