Question:
Dois-je utiliser la protection CSRF sur les points de terminaison de l'API Rest?
Conor Mancone
2017-08-03 23:41:43 UTC
view on stackexchange narkive permalink

Remarque rapide: il ne s’agit pas d’une copie de la protection CSRF avec en-têtes personnalisés (et sans jeton de validation) malgré certains chevauchements. Cet article explique comment effectuer la protection CSRF sur les points de terminaison Rest sans discuter si cela 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 points de terminaison REST contre les attaques CSRF, mais Après avoir longuement réfléchi au sujet, je suis convaincu que les jetons CSRF sur un point de terminaison REST n'accordent aucune protection supplémentaire. En tant que tel, l'activation de la protection CSRF sur un point de terminaison REST introduit simplement du code inutile dans votre application, et je pense qu'il devrait être ignoré. Il me manque peut-être quelque chose, 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 identifiants 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 retournent 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 contraire, l'attaquant doit simplement tromper le navigateur de la victime pour qu'il fasse une demande, et les informations d'identification pour authentifier la demande circuleront gratuitement.

Entrez une API REST

Les points de terminaison de l'API Rest présentent une différence très importante par rapport aux autres requêtes: ils sont spécifiquement sans état et ne doivent jamais accepter / utiliser les données d'un cookie ou d'une session. En conséquence, une API REST conforme à 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 à une API 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 autre) qui est envoyée dans l'en-tête quelque part ou éventuellement dans le corps de la requête lui-même.

Puisque l'authentification est spécifique à l'application, et comme 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 d'une manière ou d'une autre amené à visiter le point de terminaison de l'API. En conséquence, un point de terminaison REST sans cookie est complètement immunisé contre les attaques CSRF.

Ou est-ce que je manque quelque chose?

Certaines API REST limitent les appels par ip, ce qui peut être un cas limite où il pourrait être judicieux d'implémenter une protection csrf.
Merci pour l'entrée @Xavier59.Cela vous dérange-t-il de clarifier: pourquoi la limitation des taux nécessiterait-elle une protection CSRF?
Je ne suis donc pas convaincu que cela s'applique nécessairement à votre cas, mais disons que vous utilisez Google en tant que fournisseur oauth.Votre utilisateur se connecte à un site malveillant qui utilise également google en tant que fournisseur oauth.Le site malveillant pourrait utiliser le jeton de l'utilisateur (ish, selon les paramètres du client et autres) pour votre site.Voir ici pour en savoir plus: https://spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2
@ConorMancone Si le site `A` a une API REST limitant les appels par ip à 1 / seconde, un attaquant pourrait tromper Bob pour qu'il se rende sur le site attaquant` B` qui envoie des dizaines de requêtes par seconde.Cela pourrait entraîner l'interdiction de l'adresse IP de Bob de cette API REST ou l'empêcher d'utiliser correctement l'API REST.Je suis d'accord que c'est un peu tiré par les cheveux mais pas totalement impossible.
@Xavier59 C'est un peu l'équivalent d'essayer de DDoS un site Web en obtenant une balise img avec le site Web comme attribut source sur un site Web à fort trafic.Ce n'est pas nécessairement exagéré.Cela étant dit, je ne vois pas pourquoi les jetons CSRF feraient quoi que ce soit pour atténuer une telle attaque.
Merci @JesseKeilson.Je vais devoir digérer celui-là.Ce n'est pas parce qu'un vecteur d'attaque est sécurisé qu'il n'est pas dangereux!
@ConorMancone CSRF atténuerait ce problème en n'autorisant pas (et en comptant) la demande avec un jeton csrf non associé à la bonne adresse IP.Ainsi, Bob ip ne serait pas mis sur la liste noire de l'utilisation de l'API restante.J'espère que vous comprenez mon point.
@JesseKeilson Le lien en question était axé sur les attaques CSRF contre les serveurs de validation OAUTH.C'était une lecture intéressante.Le résumé général est quelque chose que j'ai appris auparavant: en termes de flux de travail général, OAuth2 est étonnamment peu sûr.Pour être clair, je fais référence spécifiquement au processus d'émission de jetons OAuth2.L'utilisation de ces jetons est une autre affaire et est généralement beaucoup plus simple.
Sept réponses:
Conor Mancone
2017-08-04 18:25:29 UTC
view on stackexchange narkive permalink

À l'origine, je ne visais pas une réponse personnelle, mais après avoir lu davantage, j'ai trouvé ce que je pense être une réponse complète qui explique également pourquoi certains pourraient encore être intéressés par la protection CSRF sur les points de terminaison REST.

Pas de cookies = Pas de CSRF

C'est vraiment aussi simple que cela. 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 que vous 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, en particulier 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 des attaques CSRF, vous êtes également vulnérable si vous utilisez HTTP / Basic authentification. Plus généralement, si le navigateur est capable de transmettre automatiquement les informations de connexion pour votre application, le CSRF est important. D'après mon expérience, les cookies sont la technologie la plus courante exploitée pour faire de la CSRF, mais il existe d'autres méthodes d'authentification qui sont utilisées qui peuvent entraîner la même vulnérabilité.

REST = Stateless

Si vous demandez à quelqu'un "qu'est-ce que REST", vous obtiendrez une variété de réponses qui traitent 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'il est sans état. L'application elle-même a un état bien sûr. Si vous ne pouvez pas stocker de données dans une base de données quelque part, votre application sera assez limitée. Dans ce cas cependant, l'état sans état a une signification très spécifique et importante: les applications REST ne suivent pas l'état de l'application côté client . Si vous utilisez des sessions, vous suivez (presque certainement) l'état côté client et vous n'êtes pas une application REST complète. Ainsi, une application qui utilise des sessions (en particulier pour les connexions) qui sont suivies via des cookies n'est pas une application REST-full (IMO), et est certainement vulnérable aux attaques CSRF, même si elle ressemble autrement à une application REST.

Je pense qu'il vaut la peine de noter rapidement qu'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 du paradigme REST. Tant que l'application suit l'état côté client, la mise en cache n'est pas possible.

Reste ≠ Cookieless

Pour ces raisons, j'ai d'abord supposé qu'un Une application REST entièrement conforme n'aurait jamais besoin de sessions, n'a jamais besoin de cookies et n'a donc jamais besoin 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.

Pensez à une application Web typique côté client (dans ce cas, navigateur, pas 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 à page unique, vous pouvez simplement conserver ce jeton en mémoire, mais cela déconnectera efficacement l'utilisateur s'il ferme la page. En conséquence, 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 qu'il les utilise à sa discrétion.

Pour cela 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, qui empêche l'application de lire le cookie une fois qu'il est défini. En conséquence, 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 de cookies ne viole pas directement l'exigence d'apatridie de REST car le serveur ne suit toujours pas l'état côté client. Il cherche simplement des informations d'authentification dans un cookie, plutôt que dans l'en-tête.

Je le mentionne car c'est potentiellement une raison légitime d'utiliser des cookies avec une API REST, même si cela dépend évidemment d'une application donnée pour équilibrer les divers problèmes de sécurité et d'utilisabilité. J'essaierais personnellement d'éviter d'utiliser des cookies avec les API REST, mais il peut très bien y avoir des raisons de les utiliser quand même. Quoi qu'il en soit, 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 le faites pas.

Vous êtes à peu près sur place.L'authentification de base HTTP peut être vulnérable à CSRF, tout comme l'authentification basée sur IP et d'autres.À l'inverse, les cookies peuvent être sûrs si ce n'est qu'un client sur mesure qui consomme le service, pas un navigateur.Cela n'affecte probablement pas vos décisions, mais cela vaut la peine d'être pris en compte.J'ai trouvé des gens qui essayaient de définir ce qui est «REST approprié» comme l'une des discussions les moins constructives en informatique.En termes pratiques, la plupart des services nécessitent une authentification et les sessions sont un moyen raisonnable de le faire.
Merci @paj28.L'authentification de base HTTP est un excellent point à mentionner.C'est beaucoup moins courant, je pense (c'est pourquoi j'ai oublié de le mentionner), mais il est bon de mentionner les exceptions lorsque vous essayez de trouver une réponse complète.
Je n'ai pas compris votre troisième point. Ai-je toujours besoin de la protection CSRF si je stocke le jeton dans un cookie de session?
@HFA Si vous utilisez des cookies, en particulier pour l'authentification, vous avez besoin d'une protection CSRF.Peu importe ce que vous stockez dans le cookie: si le contenu d'un cookie est utilisé pour authentifier vos utilisateurs avec votre application, CSRF est nécessaire car le navigateur attache automatiquement des cookies à toutes les demandes sur votre site.
Je stocke le jeton d'authentification dans un cookie avec la durée de vie de la session et j'utilise le contenu de ce cookie pour intercepter chaque requête http et ajouter un en-tête d'autorisation aux requêtes http, est-ce que cela compte aussi?;)
@HFA: Pour utiliser le contenu de ce cookie, vous devez rendre le cookie NON HttpOnly (c'est-à-dire accessible par JS).En faisant cela, vous vous exposez potentiellement à XSS, comme si vous utilisiez le stockage local.De plus, si votre serveur accepte le cookie comme moyen d'authentification, vous êtes également ouvert à CSRF.Alors utilisez simplement le stockage local et assurez-vous d'empêcher XSS, les cookies n'ont de sens que si votre serveur les accepte.
@BorisB.LocalStorage n'a pas de capacité de durée de vie de session, j'utilise donc un cookie de session défini par javascript dans la machine de l'utilisateur pour stocker le jeton.J'utilise un en-tête d'autorisation pour l'authentification et non un cookie.
salut ... comment si je suis déjà authentifié et que j'ai les `cookies`, faire quelque chose comme` Brute Force`?
HTTP est en fait un protocole sans état.Pourquoi on l'appelle ainsi parce que 2 demandes (connexions) différentes au serveur peuvent provenir d'endroits différents, mais si le contenu de la demande est le même, vous obtiendrez à peu près les mêmes données (si l'état du serveur ne change pas).C'est pourquoi HTTP est un excellent protocole pour REST.Les cookies HTTP sont également envoyés dans l'en-tête (le navigateur l'ajoute automatiquement), alors que la plupart des API REST l'attendent dans un autre en-tête comme l'autorisation.Que vous stockiez votre token dans des cookies, localStorage ou sessionStorage, un script XSS y aura accès, mais pas une simple attaque CSRF.
J'utilise localStorage pour enregistrer un jeton d'accès, est-ce vulnérable à CSRF?
@Shashidhara non.mais c'est maintenant un risque XSS plus élevé qu'un cookie httpOnly (c'est un compromis, ne pas dire que localStorage est mauvais, juste un modèle de menace différent)
Une petite précision: "Pas de cookies = Pas de CSRF" - Je le pensais aussi, mais avec la prise en charge native du navigateur Kerberos / NTLM, (SPNEGO) un jeton Kerberos est envoyé à un ensemble de domaines en liste blanche.Ces cas devraient également avoir une protection CSRF car c'est essentiellement la même chose qu'un cookie dans la manière dont "quelque chose qui envoie automatiquement quelque chose sur les demandes" donc je pense que si vous soumettez un formulaire avec la cible étant un point de terminaison API kerberisé, pendant que vous êtes dansle réseau interne, il y a là aussi un risque CSRF, non?
Oui, même selon OWASP, ce ne sont pas que des cookies, si vous avez NTLM / Kerberos, CSRF est également nécessaire.https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery
Un autre sur "Pas de cookies = Pas de CSRF" - si vous stockez le jeton de session dans l'URL (mauvaise idée, mais cela arrive), alors il est aussi facile de tromper l'utilisateur dans la soumission du formulaire qu'avec le jeton de session dans les cookies.Cela nécessiterait de connaître le jeton à l'avance (historique du navigateur / journaux du proxy / journaux du serveur), ce qui est un obstacle, mais c'est faisable dans certaines circonstances.Cas très spécifique, mais j'ai pensé qu'il valait la peine de le mentionner.
stuartm9999
2018-08-03 13:20:29 UTC
view on stackexchange narkive permalink

"il n'y a aucun moyen pour un navigateur de fournir automatiquement des informations d'authentification même s'il est en quelque sorte amené à visiter le point de terminaison de l'API"

Faites simplement attention sur les réseaux privés utilisant des authentification windows / kerberos. Dans ce scénario, le navigateur fournira automatiquement les informations d'identification (kerberos ou jeton NTLM) s'il est configuré pour le faire.

Donc - je crois que dans ce cas, CSRF est requis.

Oui.https://www.owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery "Autorise les demandes basées uniquement sur les informations d'identification qui sont automatiquement soumises, telles que le cookie de session si actuellement connecté à l'application, ou la fonctionnalité" Se souvenir de moi "si elle n'est pas connectéel'application, ** ou un jeton Kerberos ** si une partie d'un intranet participant à une connexion intégrée avec Active Directory est menacée. "
an0904
2019-04-23 00:15:17 UTC
view on stackexchange narkive permalink

La nécessité ou non de la protection CSRF dépend de 2 facteurs: -

La requête effectue-t-elle une action de changement d'état (différente de l'API REST Statelessness) - State les actions de changement 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 modifiera l'état sauvegardé de l'utilisateur. Toutes les demandes de publication et quelques demandes de Get appartiendront à cette catégorie. Les API REST 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 a été lancée par l'utilisateur ou par un autre onglet ouvert. Ainsi, tout type d'authentification dans lequel le navigateur peut 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 tombent dans les 2 catégories ci-dessus, une protection CSRF est nécessaire.

Charlie Reitzel
2019-09-25 01:06:33 UTC
view on stackexchange narkive permalink

Une chose que j'ajouterais aux autres réponses est que la protection CSRF est nécessaire uniquement dans le domaine et le chemin du cookie en question. Ou en d'autres termes:

Autorisation! = Authentification
Cookies == Authentification
Jeton == Autorisation

Ceci est pertinent pour la mise en œuvre des connexions persistantes (votre 3e point). Si vous apposez vos cookies sur login.example.com , qui héberge votre interface utilisateur de connexion et votre point de terminaison / authorize , vous pouvez exécuter un flux OAuth implicite toutes les quelques minutes sans nécessiter une nouvelle connexion (par exemple pas 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.

Donc, vous pouvez toujours évitez en toute sécurité de traiter CSRF sur vos API REST. Mais votre serveur de connexion / authentification a intérêt à être à l'épreuve des balles (et protégé par CSRF).

John Wu
2017-08-04 01:28:59 UTC
view on stackexchange narkive permalink

Les points de terminaison de l'API Rest ont une différence très importante par rapport aux autres requêtes: ils sont spécifiquement sans état et ne doivent jamais accepter / utiliser les données d'un cookie ou d'une session.

Si c'est ainsi que vous définissez "REST API", alors aucun CSRF n'est possible. Le CSRF, également appelé «session riding» [ citation], ne fonctionnera évidemment pas s'il n'y a pas de session à «ride».

Si vous n'êtes pas d'accord avec une partie de ma déclaration, je serais heureux de l'entendre.OMI, l'apatridie est un objectif central des API REST.Les sessions rendent définitivement une API avec état.Cookies ... techniquement, je suppose que vous pouvez utiliser des cookies et ne pas stocker du côté du serveur d'état, en fonction de la façon dont vous les utilisez.
Eh bien, je préfère répondre à la question que de chicaner sur la terminologie.Mais le S dans HATEOS et le S dans REST représentent tous deux l'état.Tant que l'état du client n'est pas conservé sur le serveur, je ne pense pas que vous ayez "violé" l'esprit de l'approche REST.
Je suis absolument d'accord avec vous.Ce n'était pas mon désir de chipoter sur la terminologie.Une partie du problème est que je n'étais pas assez clair dans ma question initiale: je parlais spécifiquement de l'état du client, pas de l'état de l'application.
Oui Transfert d'État, c'est le point important.L'état n'est pas stocké côté serveur.Le client informe le serveur de son état.Et CSRF n'a de sens que si l'API est accessible via les navigateurs Web classiques.Certaines méthodes http telles que DELETE, PUT / PATCH ne sont même pas prises en charge par les navigateurs actuels, ce qui rend l'API uniquement accessible aux clients http autonomes.
Raywell
2020-02-07 15:39:47 UTC
view on stackexchange narkive permalink

Réponse : Si vous stockez le jeton dans le localStorage et que vous l'ajoutez à vos requêtes avec JS, cela garantirait automatiquement la protection CSRF (par la nature de l'attaque)

Addendum : quant à savoir s'il est plus sûr d'utiliser des cookies http uniquement plutôt que localStorage (donner l'impression que cette façon d'avoir une protection CSRF créerait un problème en cas de XSS): ce n'est en fait pas . Cela rendrait juste un peu plus difficile pour l'attaquant qui contrôle JS sur votre site via un XSS exploité. @ Bobince a expliqué cela avec de meilleurs mots: Le paramètre httponly empêche-t-il 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)

Bienvenue.En tant que site de questions-réponses, nous sommes différents d'un site de discussion.Les réponses doivent être une réponse à la question et non un commentaire sur une autre réponse.
Merci @schroeder.Affiche de longue date pour la première fois, je voulais à l'origine commenter mais cela exigeait une réputation minimale.Cependant, ce commentaire m'a conduit à ma réponse originale à la question OP dans ma dernière phrase: "devrais-je utiliser la protection csrf" => Non si le jeton est stocké et ajouté à l'en-tête par JS
Tout ce que je peux dire, c'est: continuez à contribuer au site pour gagner suffisamment de représentants pour débloquer la possibilité de commenter.Vous avez fait le premier pas en sortant du «lurk».Continue :)
Je vous recommande de supprimer le commentaire de l'autre réponse et de vous assurer que cette réponse répond directement à la question.
Je peux, mais je pense que c'est assez important car cela fait toute la différence (le raisonnement menant à la réponse).Je vais clarifier la conclusion
J'ai reformulé la réponse, j'espère que cela ressemble moins à une discussion (le contenu est à peu près le même).J'attends ma réputation pour commenter la partie trompeuse de la réponse acceptée. En attendant, j'apprécie mon image de profil à croix gammée autogénérée
Dean Valentine
2020-08-13 09:20:55 UTC
view on stackexchange narkive permalink

Il y a une petite mise en garde spécifique aux réponses existantes que j'aimerais ajouter. Bien que Conor ait raison de dire que les cookies sont la seule forme de données d'authentification stockées localement envoyées avec toutes les demandes, ils ne sont pas la seule forme de données d'authentification stockées localement utilisées par les sites Web. Cela signifie que si un site décide de conserver ses jetons JWT / Session dans quelque chose comme LocalStorage ou SessionStorage, ceux-ci peuvent encore parfois être automatiquement retirés via javascript, puis utilisés sans interaction de l'utilisateur. Cela signifie qu'il est parfois encore possible d'effectuer des attaques CSRF "une fois supprimées" en redirigeant un utilisateur vers un URI frontal correspondant au domaine qui puis envoie les creds. Cela peut être accompli d'une manière plus directe si vous avez reflété XSS, mais il y a des cas où cela n'est pas nécessaire et de telles pages + scripts existent déjà.

Dans ces cas, le problème n'est pas le manque de Jetons CSRF sur l'API REST; c'est le manque de jetons sur les points de terminaison de n'importe quel frontend qui interagit avec lui.

Wow, c'est génial!Si trivial, si un JS pouvait être injecté d'une manière ou d'une autre dans le site cible, n'importe quelle session pourrait être volée.
@peterh-ReinstateMonica Mignon, mais comme je l'ai dit dans le post, ce n'est pas ce que je voulais dire.Il n'est pas rare que vous ayez un frontend assis devant le reste de l'API avec des points de terminaison qui effectuent déjà des actions mutatives lors du chargement, sans vous obliger à y injecter du code.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...