Pourquoi la Politique de même origine n'est-elle pas suffisante pour prévenir les attaques CSRF?

tout d'abord, je suppose un backend qui contrôle les entrées pour prévenir les vulnérabilités XSS.

In this answer @les Hazlewood expliquer comment protéger le JWT côté client.

supposant 100% TLS pour toutes les communications-pendant et en tout temps après la connexion-authentification avec nom d'utilisateur / mot de passe via basic l'authentification et la réception D'une JWT en échange est un cas d'utilisation valide. C'est presque exactement comme l'un des flux de OAuth 2 ('password grant')) travail. [...]

vous venez de définir l'en-tête D'autorisation:

Authorization: Bearer <JWT value here>

mais, cela étant dit, si votre client REST est "non digne de confiance" (par ex. JavaScript), Je ne le ferais même pas: toute valeur dans le Réponse HTTP accessible via JavaScript-essentiellement n'importe quel en-tête valeur ou valeur du corps de réponse - peut être reniflé et intercepté via MITM XSS attacks.

il est préférable de stocker la valeur JWT dans un cookie sécurisé, http seulement (cookie config: setSecure(vrai), setHttpOnly(true)). Cela garantit que le navigateur:

  1. ne jamais transmettre le cookie sur une connexion TLS et,
  2. ne jamais rendre la valeur du cookie disponible pour le code JavaScript.

Cette approche est presque tout ce que vous devez faire pour les meilleures pratiques sécurité. la dernière chose est de s'assurer que vous avez la protection CSRF sur chaque requête HTTP pour s'assurer que les domaines externes lançant des requêtes votre site ne peut pas fonctionner.

la façon la plus simple de faire cela est de définir un seul http sécurisé (mais pas uniquement http).) cookie avec une valeur aléatoire, par exemple UUID.

Je ne comprends pas pourquoi nous avons besoin du cookie avec la valeur aléatoire pour s'assurer que les domaines externes initient les requêtes sur votre site ne peuvent pas fonctionner. Ce n'est pas gratuit avec la même politique d'origine?

de OWASP :

Vérification De L'En-Tête D'Origine

la norme D'en-tête HTTP Origin a été introduite comme méthode défense contre CSRF et autres attaques de domaines croisés. Contrairement à l' referer, l'origine sera présente dans la requête HTTP qui provient à partir d'une url HTTPS.

si l'en-tête origin est présent, alors il faut le vérifier cohérence.

je sais que la recommandation générale de L'OWASP elle-même est le motif de jeton Synchronizer, mais je ne vois pas quelles sont les vulnérabilités qui restent dans:

  • TLS + JWT dans la sécurisation des cookies httpOnly + same-origin policy + Pas de failles XSS.

mise à JOUR 1: Le la Politique de même origine ne s'applique qu'à XMLHTTPRequest , de sorte qu'un site maléfique peut faire une demande de formulaire POST facilement et cela brisera ma sécurité. Explicite de l'en-tête d'origine vérification est nécessaire. L'équation serait:

  • TLS + JWT dans la sécurisation des cookies httpOnly + en-Tête d'Origine case + Pas de failles XSS.
27
demandé sur Community 2015-10-21 16:54:15

3 réponses

résumé

j'avais un concept mal compris sur la Politique de la même origine et les CORS que @Bergi, @Neil McGuigan et @SilverlightFox m'ont aidé à clarifier.

tout d'abord, ce que @Bergi dit à propos de

SOP n'empêche pas l'envoi de requêtes. Il empêche une page de accès aux résultats des demandes transdomaines.

est un concept important. Je pensais qu'un navigateur ne fait pas la requête au domaine croisé en fonction de la restriction SOP mais cela est seulement vrai pour ce que Monsur Hossain appelle des "requêtes pas si simples" dans ce "tutoriel excellent .

les demandes D'origine croisée ont deux saveurs:

  • de simples demandes
  • "n'est pas si simple demande" (un terme que je viens de faire)

Simple les demandes sont des demandes qui répondent aux critères suivants:

  • correspond à la méthode HTTP (sensible à la casse) :
    • HEAD
    • GET
    • POST
  • correspondances D'en-têtes HTTP (insensible à la casse)):
    • Accepter
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type, mais seulement si la valeur est l'une des:
      • application / x-www-form-urlencoded
      • multipart / form-data
      • text / plain

ainsi, un message avec le type de contenu application / x-www-form-urlencoded s'affichera sur le serveur (cela signifie CSRF), mais le navigateur ne rendra pas accessibles les résultats de cette demande. Un message avec application de type de contenu / json est une "requête pas-si-simple" de sorte que le navigateur va faire une requête de prefligth comme ceci

OPTIONS / endpoint HTTP / 1.1

Animateur: https://server.com

Connexion: maintenir en vie

Contrôle d'accès-Demande-méthode: POST

Origine: https://evilsite.com

Contrôle d'accès-en-têtes de demande: contenu-type

Accept: * / *

Accept-Encoding: gzip, deflate, sdch

Accept-Language: es-ES, es;q=0.8

si le serveur répond par exemple:

contrôle D'accès-Allow-Origin: http://trustedsite.com

Méthodes: GET, POST, PUT

Contrôle d'accès-en-tête Allow: content-type

Content-Type: text / html; charset=utf-8

le navigateur ne fera pas la demande du tout, parce que""

XMLHttpRequest ne peut pas charger http://server.com/endpoint . Réponse à la demande avant le vol ne passe pas le contrôle d'accès vérifier: La L'en-tête 'Access-Control-Allow-Origin' contient la valeur non valide "trustedsite.com". Origine "evilsite.com" n'est donc pas autorisé à y accéder.

donc je pense que Neil parlait de cela quand il a souligné que:

la Politique de même origine s'applique seulement à la lecture des données et non en l'écrivant.

cependant, avec le contrôle explicite de l'en-tête d'origine que J'ai proposé à Bergi I pense est assez à l'égard de cette question.

en ce qui concerne ma réponse à Neil, Je ne voulais pas dire que cette réponse était la seule à ma question, mais elle m'a rappelé une autre question importante au sujet de SOP et c'est que la politique ne s'applique qu'aux XMLHTTPRequest.

en conclusion, je pense que l'équation

  • TLS + JWT dans la sécurisation des cookies httpOnly + en-Tête d'Origine case + Pas de failles XSS.

est une bonne alternative si L'API est dans un autre domaine comme SilverlightFox dit. Si le client est dans le même domaine que le client, j'aurai des problèmes avec les requêtes qui n'incluent pas l'en-tête Origin. Encore une fois du cors tutoriel :

La présence de l'en-tête d'Origine ne signifie pas nécessairement que l' s'agit d'une demande de la croix-origine de la demande. Alors que toutes les requêtes d'origine contiendra une Origine en-tête, certaines requêtes de même origine peuvent avoir un ainsi. Par exemple, Firefox n'inclut pas D'en-tête D'origine sur de même l'origine des demandes. Mais Chrome et Safari incluent un en-tête Origin sur même origine POST/PUT / DELETE requests (same-origin GET requests will pas un en-tête d'Origine).

Silverlight pointu ce .

le seul risque qui subsiste est qu'un client puisse mystifier l'en-tête origin pour correspondre à l'origine autorisée, donc la réponse que je cherchais était en fait ce

mise à JOUR: pour ceux qui suivent ce post, j'ai "15191410920 de" doutes si l'en-tête d'origine est nécessaire à tous à l'aide de JWT.

l'équation serait:

  • TLS + JWT stockés dans un cookie sécurisé + JWT dans l'en-tête de la requête + aucune vulnérabilité XSS.

en outre, l'équation précédente a httpOnly cookie mais cela ne fonctionnera pas si vous avez le client et le serveur dans des domaines différents (comme de nombreuses applications SPA aujourd'hui) parce que le cookie ne serait pas envoyé avec chaque demande au serveur. Vous devez donc accéder au token JWT stocké dans le cookie et l'envoyer dans un en-tête.

10
répondu gabrielgiussi 2017-05-23 12:34:21

pourquoi la Politique de la même origine n'est-elle pas suffisante pour prévenir les attaques CSRF?

parce que la Politique de même origine ne s'applique qu'à la lecture des données et non à leur écriture.

vous voulez éviter http://compromised.com de faire une demande comme celle-ci (à partir du navigateur de l'utilisateur):

POST http://example.com/transfer-funds
fromAccountId:1
toAccountId:666

une requête légitime ressemblerait à ceci:

POST https://example.com/transfer-funds
fromAccountId: 1
toAccountId: 666
csrfToken: 249f3c20-649b-44de-9866-4ed72170d985

vous le faites en exigeant une valeur (le CSRF token) qui ne peut pas être lu à partir d'un site externe, c'est-à-dire dans un en-tête D'entrée ou de réponse HTML.

en ce qui concerne L'en-tête Origin, les navigateurs plus anciens ne le prennent pas en charge, et Flash présentait certaines vulnérabilités qui permettaient au client de le modifier. En gros, tu ferais confiance à Adobe pour ne rien gâcher dans le futur.

assurez - vous d'avoir une protection CSRF sur chaque requête HTTP

vous n'avez besoin que D'une protection CSRF sur les demandes ayant des effets secondaires, comme changer d'état ou envoyer un message.

9
répondu Neil McGuigan 2015-10-21 17:35:44

je veux juste résumer les réponses.

  1. comme toute autre PON mentionnée ne s'applique qu'aux requêtes XMLHTTP. Cela signifie que par Spécification les navigateurs doivent envoyer l'en-tête ORIGIN avec les requêtes qui ont été faites au moyen de XmlHttpRequests.
  2. si vous cochez Chromium , vous envoyez origin lorsque vous soumettez le formulaire. Cependant, cela ne signifie pas que d'autres navigateurs le font. L'image ci-dessous illustre deux requêtes post faites dans Firefox. Un est fait par soumettre un formulaire et un second en utilisant XHR . Les deux demandes ont été faites de http://hack:3002/changePassword à http://bank:3001/chanePassword .
  3. Le navigateur
  4. est autorisé à ne pas envoyer l'en-tête origin si la demande a été faite à partir du même domaine. Ainsi, le serveur ne devrait vérifier la Politique d'origine que lorsque l'en-tête d'origine est défini.

la conclusion est: si vous utilisez des cookies et une demande vient à serveur sans En-tête origin , vous ne pouvez pas différencier si elle a été faite en soumettant un formulaire d'un autre domaine ou par XHR dans le même domaine. C'est pourquoi vous devez vérifier avec le CSRF.

enter image description here

0
répondu deathangel908 2017-06-13 08:47:13