Il s'agit d'une question sur la génération de jetons CSRF.
En général, j'aimerais générer un jeton à partir d'un élément unique de données associé à la session de l'utilisateur, et haché et salé avec une clé secrète.
Ma question concerne la génération de jetons lorsqu'il n'y a PAS de données utilisateur uniques à utiliser. Aucune session n'est disponible, les cookies ne sont pas une option, l'adresse IP et les choses de cette nature ne sont pas fiables.
Y a-t-il une raison pour laquelle je ne peux pas inclure la chaîne à hacher dans la demande également ? Exemple de pseudocode pour générer le jeton et l'intégrer :
var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
<a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a>
Exemple de validation côté serveur du jeton CSRF
var $stringToHash = request.get('key')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get('csrfToken')
La chaîne utilisée dans le hachage serait différente à chaque demande. Tant qu'elle était incluse dans chaque requête, la validation du jeton CSRF pouvait se faire. Étant donné qu'elle est nouvelle à chaque demande et qu'elle est uniquement intégrée à la page, un accès extérieur au jeton ne serait pas possible. La sécurité du jeton repose alors sur le fait que la $mySecretKey n'est connue que de moi.
S'agit-il d'une approche naïve ? Ai-je oublié une raison pour laquelle cela ne peut pas fonctionner ?
Gracias
12 votes
La solution proposée est vulnérable aux attaques par rejeu. La même combinaison de jeton et de clé fonctionnera indéfiniment.
0 votes
Bon point, @Matthew. Mais comment pouvons-nous être défendus dans le cas où le jeton a été généré par le serveur, mais que l'utilisateur n'est pas revenu sur notre serveur et que cela a été fait par un pirate avec le même sessionId+hash ? Ou est-ce impossible (sans comparer l'adresse IP, l'agent d'utilisateur, etc.) ?