web-dev-qa-db-fra.com

Les problèmes de sécurité liés à l'envoi d'un mot de passe via une requête GET via https sont-ils valides?

Nous avons une page Web qui utilise le cadre sapui5 - pour construire un spa . La communication entre le navigateur et le serveur utilise https . L'interaction pour se connecter à la page est la suivante:

  1. L'utilisateur ouvre le site en entrant https://myserver.com dans le navigateur.
  2. Un dialogue de connexion avec deux champs de formulaire pour unsername et mot de passe est affiché. 
  3. Après avoir entré username et password et appuyé sur le login-button 
  4. une demande ajax est envoyée en utilisant GET à l'URL: https://myusername:[email protected]/foo/bar/metadata 

Selon ma compréhension, utiliser GET pour envoyer des données sensibles n’est jamais une bonne idée. Mais cette réponse à HTTPS est la chaîne d'URL sécurisée dit ce qui suit

HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.

Un dans une autre réponse dans le même fil:

These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging 
process by the browser and are included in the encrypted data block.

The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.

Mais il semble qu'il y ait toujours des problèmes de sécurité en utilisant get :

Est-ce le cas pour les URL comme?

    https://myusername:[email protected]/foo/bar/metadata
    // or 
    https://myserver.com/?user=myUsername&pass=MyPasswort

Questions supplémentaires sur ce sujet:

Sur security.stackexchange sont des informations supplémentaires:

Mais à mon avis, certains aspects ne sont toujours pas résolus

Question

À mon avis, les points mentionnés sont des objections valables à ne pas utiliser get. Est le cas; utiliser get pour envoyer des mots de passe est-il une mauvaise idée?

Sont-ce les options d'attaque, y a-t-il plus?

  • historique du navigateur 
  • les journaux du serveur (en supposant que l'URL soit stockée dans les journaux non chiffrés ou chiffrés)
  • informations de référence (si c'est vraiment le cas)

Quelles options d'attaque existent lors de l'envoi de données sensibles (mot de passe) via https avec get?

Merci

21
surfmuggle

Ces deux approches sont fondamentalement différentes:

  • https://myusername:[email protected]/foo/bar/metadata
  • https://myserver.com/?user=myUsername&pass=MyPasswort

myusername:myPassword@ est le "Informations utilisateur" (ce formulaire est obsolète dans le dernier RFC URI), alors que ?user=myUsername&pass=MyPasswort fait partie de la requête.

Si vous regardez cet exemple de RFC 3986:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

myusername:myPassword@ fait partie de la autorité. En pratique, les en-têtes d'authentification HTTP (Basic) seront généralement utilisés pour transmettre ces informations. Du côté du serveur, les en-têtes ne sont généralement pas consignés (et s'ils le sont, le fait que le client les ait entrés dans leur barre d’emplacement ou via une boîte de dialogue de saisie ne changerait rien). En général (bien que cela dépende de la mise en œuvre), les navigateurs ne le stockent pas dans la barre d’emplacement ou du moins, ils suppriment le mot de passe. Il semble que Firefox conserve les informations sur l'utilisateur dans l'historique du navigateur, alors que Chrome ne le fait pas (et IE ne les prend pas en charge sans solution de contournement )

En revanche, ?user=myUsername&pass=MyPasswort est le query, une partie beaucoup plus intégrée de l'URI, et il est envoyé en tant que HTTP Request-URI . Ce sera dans l'historique du navigateur et les journaux du serveur. Cela sera également passé dans le référent.

Pour le dire simplement, myusername:myPassword@ est clairement conçu pour transmettre des informations potentiellement sensibles, et les navigateurs sont généralement conçus pour gérer cela de manière appropriée, alors que les navigateurs ne peuvent pas deviner quelle partie de la requête est sensible ou non: attendez-vous à une fuite d'informations.


De plus, les informations sur le référent ne seront généralement pas divulguées à des tiers, car l'en-tête Referer provenant d'une page HTTPS est normalement envoyé avec une autre demande sur HTTPS au même hôte. (Bien sûr, si vous avez utilisé https://myserver.com/?user=myUsername&pass=MyPasswort, ce sera dans les journaux de ce même hôte, mais vous ne le valez pas beaucoup car il reste dans les mêmes journaux de serveur.)

Ceci est spécifié dans la spécification HTTP (Section 15.1.3) :

Les clients NE DEVRAIENT PAS inclure de champ d’en-tête de référent dans une requête HTTP (non sécurisée) si la page de renvoi a été transférée avec un protocole sécurisé. 

Bien qu’il s’agisse d’un "NE DEVRAIT PAS", Internet Explorer, Chrome et Firefox semblent l’appliquer de cette façon. Que cela s'applique aux demandes HTTPS d'un hôte à un autre dépend du navigateur et de sa version.

Il est maintenant possible de remplacer ce comportement, comme décrit dans cette question et ce projet de spécification , en utilisant un en-tête <meta>, mais vous ne le feriez pas sur une page sensible qui utilise de toute façon ?user=myUsername&pass=MyPasswort.

Notez que le reste de spécification HTTP (Section 15.1.3) est également pertinent:

Les auteurs de services qui utilisent le protocole HTTP NE DEVRAIENT PAS utiliser de formulaires basés sur GET pour la soumission de données sensibles, car cela entraînerait le codage de ces données dans l'URI de demande. De nombreux serveurs, mandataires et agents d'utilisateur existants consignent l'URI de la demande à un endroit où il pourrait être visible par des tiers. Les serveurs peuvent utiliser plutôt la soumission de formulaire basée sur POST 

Utiliser ?user=myUsername&pass=MyPasswort équivaut exactement à utiliser un formulaire basé sur GET et, même si le problème du référent peut être maîtrisé, les problèmes relatifs aux journaux et à l'historique demeurent.

17
Bruno

L'envoi de tout type de données sensibles via GET est dangereux, même s'il s'agit de HTTPS. Ces données peuvent se retrouver dans des fichiers journaux sur le serveur et seront incluses dans l'en-tête du référent dans des liens vers ou à partir d'autres côtés. Ils seront également enregistrés dans l'historique du navigateur afin qu'un attaquant puisse essayer de deviner et de vérifier le contenu d'origine du lien avec une attaque contre l'historique.

En dehors de cela, vous feriez mieux de poser ce genre de questions à security.stackexchange.com.

24
Steffen Ullrich

Supposons que l'utilisateur ait cliqué sur un bouton et sur la demande suivante générée par le navigateur client.

https://www.site.com/?username=alice&password=b0b123 !

HTTPS

Commençons par le commencement. HTTPS n'est pas lié à ce sujet. L'utilisation de POST ou de GET n'a pas d'importance du point de vue de l'attaquant. Les attaquants peuvent facilement récupérer des données sensibles dans une chaîne de requête ou directement dans le corps de la requête POST lorsque le trafic est HTTP. Par conséquent, cela ne fait aucune différence.

Journaux du serveur

Nous savons qu'Apache, Nginx ou d'autres services enregistrent chaque demande HTTP dans un fichier journal. Ce qui signifie que la chaîne de requête (? Username = alice & password = b0b123!) Va être écrite dans les fichiers journaux. Cela peut être dangereux car votre administrateur système peut également accéder à ces données et récupérer toutes les informations d'identification de l'utilisateur. Un autre cas peut également se produire lorsque votre serveur d'application est compromis. Je crois que vous stockez le mot de passe comme hashed. Si vous utilisez un algorithme de hachage puissant tel que SHA256, le mot de passe de votre client sera plus sécurisé contre les pirates. Mais les pirates informatiques peuvent accéder aux fichiers journaux directement en obtenant des mots de passe sous forme de texte brut avec des scripts Shell très élémentaires. 

Informations sur le référant 

Nous avons supposé que le client ouvrait le lien ci-dessus. Lorsque le navigateur client récupère le contenu HTML et tente de l’analyser, il voit la balise image. Ces images peuvent être hébergées hors de votre domaine (services postimage ou similaires, ou directement dans un domaine sous le contrôle du pirate informatique). Le navigateur fait une requête HTTP afin d’obtenir une image. Mais l'URL actuelle est https://www.site.com/?username=alice&password=b0b123 ! qui va être une information de référence!

Cela signifie que Alice et son mot de passe seront transmis à un autre domaine et peuvent être accessibles directement à partir des journaux Web. C'est un problème de sécurité très important. 

Cette rubrique me rappelle les vulnérabilités de réparation de session. Veuillez lire l'article suivant de OWASP pour une faille de sécurité presque identique avec les sessions. ( https://www.owasp.org/index.php/Session_fixation ) Cela vaut la peine de le lire.

0
Mehmet Ince

La communauté a donné un large aperçu des considérations, ce qui précède s’applique à la question. Toutefois, les demandes GET peuvent généralement nécessiter une authentification. Comme indiqué ci-dessus, l'envoi d'un nom d'utilisateur/mot de passe dans l'URL n'est jamais correct, mais ce n'est généralement pas la façon dont les informations d'authentification sont gérées. Lorsqu'une demande de ressource est envoyée au serveur, le serveur répond généralement avec un en-tête 401 et Authentication dans la réponse, auquel le client envoie un en-tête d'autorisation avec les informations d'authentification (dans le schéma de base). Maintenant, cette deuxième demande du client peut être une demande POST ou GET, rien n’empêche cela. Donc, généralement, ce n'est pas le type de demande, mais le mode de communication de l'information est en question.

Référez-vous http://en.wikipedia.org/wiki/Basic_access_authentication

0
Ironluca