Note rapide: ce n'est pas un doublon de protection CSRF avec des en-têtes personnalisés (et sans jeton de validation) malgré un certain chevauchement. Cet article explique comment effectuer la protection CSRF sur les points de terminaison Rest sans discuter si c'est réellement nécessaire. En effet, de nombreuses questions CSRF/Rest que j'ai lues sur ce site parlent de la sécurisation des points de terminaison via des jetons CSRF sans vraiment discuter de la nécessité ou non. D'où cette question.
La protection CSRF est-elle nécessaire pour les points de terminaison de l'API Rest?
J'ai vu beaucoup de discussions sur la sécurisation des REST endpoints contre les attaques CSRF, mais après avoir longuement réfléchi au sujet, je suis très certain que les jetons CSRF sur un REST endpoint n'accorde aucune protection supplémentaire. En tant que tel, l'activation de la protection CSRF sur un REST endpoint introduit simplement du code inutile dans votre application, et je pense qu'il devrait être ignoré. Il se peut que je manque quelque chose cependant, d'où cette question. Je pense que cela aidera à garder à l'esprit pourquoi la protection CSRF est nécessaire en premier lieu, et les vecteurs d'attaque contre lesquels elle protège:
Pourquoi CSRF?
Cela se résume vraiment à la capacité des navigateurs à présenter automatiquement les informations de connexion pour toute demande en envoyant des cookies. Si un identifiant de session est stocké dans un cookie, le navigateur l'enverra automatiquement avec toutes les demandes qui reviennent au site Web d'origine. Cela signifie qu'un attaquant n'a pas réellement besoin de connaître les détails d'authentification pour entreprendre une action en tant qu'utilisateur victime. Au lieu de cela, l'attaquant n'a qu'à tromper le navigateur des victimes pour qu'il fasse une demande, et les informations d'identification pour authentifier la demande circuleront gratuitement.
Entrez un REST API
Les points de terminaison de l'API Rest ont une différence très importante par rapport aux autres demandes: ils sont spécifiquement sans état et ne doivent jamais accepter/utiliser des données provenant d'un cookie ou d'une session. En conséquence, une API REST qui respecte la norme est automatiquement immunisée contre une telle attaque. Même si un cookie était envoyé par le navigateur, toutes les informations d'identification associées au cookie seraient complètement ignorées . L'authentification des appels à un REST se fait d'une manière complètement différente. La solution la plus courante consiste à avoir une sorte de clé d'authentification (un jeton OAuth ou similaire) qui est envoyé dans l'en-tête quelque part ou éventuellement dans le corps de la demande lui-même.
Étant donné que l'authentification est spécifique à l'application et que le navigateur lui-même ne sait pas ce qu'est le jeton d'authentification, il n'y a aucun moyen pour un navigateur de fournir automatiquement les informations d'authentification même s'il est en quelque sorte trompé pour visiter le point de terminaison de l'API. En conséquence, un point de terminaison sans cookie REST est complètement immunisé contre les attaques CSRF.
Ou est-ce que je manque quelque chose?
Je ne visais pas à l'origine une auto-réponse, mais après plus de lecture, j'ai trouvé ce que je pense être une réponse complète qui explique également pourquoi certains pourraient toujours être intéressés par la protection CSRF sur REST points de terminaison.
Pas de cookies = Pas de CSRF
C'est aussi simple que ça. Les navigateurs envoient des cookies avec toutes les demandes. Les attaques CSRF dépendent de ce comportement. Si vous n'utilisez pas de cookies et ne comptez pas sur les cookies pour l'authentification, il n'y a absolument aucune place pour les attaques CSRF, et aucune raison de mettre en protection CSRF. Si vous avez des cookies, surtout si vous les utilisez pour l'authentification, vous avez besoin d'une protection CSRF. Si tout ce que vous voulez savoir est "Ai-je besoin d'une protection CSRF pour mon point de terminaison API?" vous pouvez vous arrêter ici et repartir avec votre réponse. Sinon, le diable est dans les détails.
h/t à paj28: Bien que les cookies soient le principal vecteur d'attaque pour les attaques CSRF, vous êtes également vulnérable si vous utilisez l'authentification HTTP/Basic. Plus généralement, si le navigateur est capable de transmettre automatiquement les informations de connexion pour votre application, alors CSRF est important. D'après mon expérience, les cookies sont la technologie la plus couramment exploitée pour rendre CSRF possible, mais il existe d'autres méthodes d'authentification qui peuvent entraîner la même vulnérabilité.
REST = Apatride
Si vous demandez à quelqu'un "qu'est-ce que REST", vous obtiendrez une variété de réponses qui discuteront d'une variété de propriétés différentes. Vous pouvez le voir parce que quelqu'un a posé cette question sur le débordement de pile: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming
Une propriété de REST sur laquelle je me suis toujours appuyée est qu'elle est sans état. L'application elle-même a bien sûr un état. Si vous ne pouvez pas stocker de données dans une base de données quelque part, votre application va dans ce cas cependant, sans état a une signification très spécifique et importante: REST ne suivent pas l'état du côté client application. Si vous utilisez des sessions, vous êtes (presque certainement) en train de suivre l'état côté client, et vous n'êtes pas une application REST complète. Donc, une application qui utilise des sessions (en particulier pour les connexions) ) qui sont suivis via des cookies n'est pas une application REST (IMO) et est certainement vulnérable aux attaques CSRF, même si elle ressemble à une application REST.
Je pense qu'il vaut la peine de noter rapidement que l'une des raisons pour lesquelles l'apatridie côté client est importante pour les applications REST est que la capacité des intermédiaires à mettre en cache les réponses est également une partie souhaitable de la REST. Tant que l'application suit l'état côté client, la mise en cache n'est pas possible.
Repos ≠ Sans cookies
Pour ces raisons, j’ai initialement supposé qu’une application REST entièrement conforme n’aurait jamais besoin de sessions, ni de cookies, ni de sécurité CSRF. Cependant, il existe au moins un cas d’utilisation qui peut préférer les cookies de toute façon: les connexions persistantes.
Considérez une application Web côté client typique (dans ce cas, navigateur et non mobile). Vous commencez par vous connecter, qui utilise une API REST pour valider les informations d'identification de l'utilisateur et en retour reçoit un jeton pour autoriser les demandes futures. Pour les applications d'une seule page, vous pouvez simplement garder ce jeton en mémoire , mais cela entraînera la déconnexion de l'utilisateur s'il ferme la page. Par conséquent, il serait bon de conserver l'état quelque part qui peut durer plus longtemps qu'une seule session de navigateur. Le stockage local est une option, mais il est également vulnérable aux Attaques XSS: une attaque XSS réussie peut amener l'attaquant à saisir vos jetons de connexion et à les envoyer à l'attaquant pour les utiliser à sa discrétion.
Pour cette raison, j'ai vu certains suggérer d'utiliser des cookies pour stocker des jetons de connexion. Avec un cookie, vous pouvez définir l'indicateur http uniquement, ce qui empêche l'application de lire le cookie une fois qu'il est défini. Par conséquent, en cas d'attaque XSS, l'attaquant peut toujours passer des appels en votre nom, mais il ne peut pas repartir avec le jeton d'autorisation tous ensemble. Cette utilisation des cookies ne viole pas directement l'exigence d'apatridie de REST car le serveur ne suit toujours pas l'état côté client. Il recherche simplement les informations d'authentification dans un cookie, plutôt que le entête.
Je mentionne cela parce que c'est potentiellement une raison légitime d'utiliser des cookies avec une API REST, bien qu'il appartienne évidemment à une application donnée d'équilibrer les divers problèmes de sécurité et de convivialité. J'essaierais personnellement de évitez d'utiliser des cookies avec les API REST, mais il peut très bien y avoir des raisons de les utiliser de toute façon. De toute façon, la réponse globale est simple: si vous utilisez des cookies (ou d'autres méthodes d'authentification que le navigateur peut faire automatiquement), vous avez besoin d'une protection CSRF. Si vous n'utilisez pas de cookies, vous ne l'utilisez pas.
"il n'y a aucun moyen pour un navigateur de fournir automatiquement les informations d'authentification même s'il est en quelque sorte trompé pour visiter le point de terminaison de l'API"
Soyez prudent sur les réseaux privés utilisant l'authentification Windows/Kerberos intégrée. Dans ce scénario, le navigateur fournira automatiquement des informations d'identification (kerberos ou jeton NTLM) s'il est configuré pour le faire.
Donc - je crois que dans ce cas, le CSRF est requis.
La nécessité ou non d'une protection CSRF est basée sur 2 facteurs: -
La demande effectue-t-elle une action de changement d'état (différente de REST Apatridie API) - Les actions de changement d'état sont toute action qui changera l'état de l'application .. par exemple, supprimer quelque chose, ajouter quelque chose, mettre à jour quelque chose. Ce sont des actions à l'aide desquelles l'application changera l'état de sauvegarde de l'utilisateur. Toutes les demandes de publication et quelques demandes d'obtention entreront dans cette catégorie. REST = Les API peuvent avoir des actions de changement d'état.
L'authentification est-elle fournie par le navigateur (non limitée aux cookies) - CSRF se produit parce que les informations d'authentification sont incluses dans la demande par le navigateur, que la demande ait été lancée par l'utilisateur ou un autre onglet ouvert. Ainsi, tout type d'authentification dans lequel le navigateur peut auto-inclure des informations nécessite une protection CSRF. Cela inclut à la fois les sessions basées sur les cookies et l'authentification de base.
Pour toutes les demandes qui entrent dans les 2 catégories ci-dessus, une protection CSRF est nécessaire.
Les points de terminaison de l'API Rest ont une différence très importante par rapport aux autres demandes: ils sont spécifiquement sans état et ne doivent jamais accepter/utiliser des données provenant d'un cookie ou d'une session.
Si c'est ainsi que vous définissez "API REST", alors aucun CSRF n'est possible. CSRF, également appelé "session d'équitation" [ citation ], ne fonctionnera évidemment pas s'il n'y a pas de session à "rouler".
Une chose que j'ajouterais aux autres réponses est que la protection CSRF est nécessaire seulement dans le domaine et le chemin du cookie Dans la question. Ou en d'autres termes:
Autorisation! = Authentification
Cookies == Authentification
Jeton == Autorisation
Ceci est pertinent pour l'implémentation de connexions persistantes (votre 3ème point). Si vous apposez vos cookies sur login.example.com
, qui héberge votre interface utilisateur de connexion et votre /authorize
endpoint, vous pouvez alors exécuter un flux implicite OAuth toutes les quelques minutes sans nécessiter de nouvelle connexion (par exemple pas de boîte de dialogue de mot de passe). Le client peut continuer et envoyer le jeton d'accès ainsi acquis à api.example.com
sans CSRF, car aucun cookie ne sera envoyé à cet hôte.
Ainsi, vous pouvez toujours éviter de traiter CSRF en toute sécurité avec vos REST. Mais votre serveur de connexion/authentification devrait être à l'épreuve des balles (et protégé par CSRF).
Réponse : Si vous stockez le jeton dans le localStorage et l'ajoutez à vos demandes avec JS, il garantirait automatiquement la protection CSRF (par la nature de l'attaque) )
Addendum : Quant à savoir s'il est plus sûr d'utiliser des cookies uniquement http plutôt que localStorage (ce qui donne l'impression que cette façon d'avoir la protection CSRF créerait un problème en cas de XSS): ce n'est pas le cas. Cela rendrait les choses un peu plus difficiles pour l'attaquant qui contrôle JS sur votre site via un XSS exploité. @bobince a expliqué qu'avec de meilleurs mots: La définition de httponly empêche-t-elle de voler une session en utilisant XSS?
XSS est une vulnérabilité au niveau de l'application, mais ses effets peuvent être atténués en limitant la puissance du jeton grâce à l'utilisation de revendications (restreindre au minimum nécessaire)