web-dev-qa-db-fra.com

Y a-t-il une différence entre GET et POST pour la sécurité des applications Web?

J'ai 2 choix pour envoyer des données entre 2 applications Web.

  1. J'encode les données en Base64 et je les ajoute à l'URL, je récupère ces paramètres sur mon application de destination et je décode les paramètres.

    Par exemple., http:/myDomain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

  2. Envoyez les paramètres sous forme de valeurs masquées de application1 à application2.

    String res = (String) request.getAttribute ("paramValue"); 
     Document.myForm.action = 'myDestinationURL'; 
     Document.myForm.method = "POST"; 
     document.myForm.submit (); 
     
     <form name = "myForm" method = "post"> 
     <input type = "hidden" name = "paramValue" value = "<% = res%>" />

Dans le choix 1, on peut connaître les paramètres que j'envoie et ma technique d'encodage. Dans le choix 2, on peut visualiser les données que j'envoie en faisant une source de vue facilement.

Outre les éléments ci-dessus, quelles sont les manières possibles pour un intrus de mieux connaître mon système? Et quelle option convient le mieux en général à un développeur? Choix 1 ou Choix 2?

41
Vikas V

L'option 1 peut de toute façon introduire un certain nombre de problèmes non liés à la sécurité:

  • L'URL résultante peut être mise en cache par le navigateur ou mise en signet, ce qui oblige les utilisateurs à renvoyer.
  • L'URL résultante peut être partagée par les utilisateurs, obligeant des tiers à soumettre.
  • L'URL peut être envoyée à votre fournisseur de navigateur , qui peut accéder au site.

Mais il s'agit de sécurité, et cela introduit quelques risques non présents dans l'option 2:

  • L'URL avec son paramètre peut se retrouver dans les journaux de proxy de tout le long du chemin, révélant vos données.
  • Votre fonction de décodage est désormais un vecteur d'attaque supplémentaire. (Gère-t-il correctement l'Unicode? Existe-t-il des restrictions de longueur?)
  • Vous pouvez être tenté de penser que votre chaîne encodée est en quelque sorte sécurisée, lorsqu'elle est juste la sécurité par l'obscurité (et pas beaucoup d'obscurité), ou peut-être plus appropriée, théâtre de sécurité .

Cela dit cependant; ils sont autrement largement équivalents dans la sécurité qu'ils offrent. Ils soumettent tous les deux des données en texte brut dans l'en-tête HTTP, et base64 n'est pas exactement la science des fusées (et vous pouvez coder en base64 votre POST).

Aucun des deux n'offre une protection significative pour vos données.

S'il s'agit d'informations que vous ne voulez pas que l'utilisateur voit; pourquoi l'envoyez-vous à l'utilisateur pour commencer? Considérez l'architecture que vous utilisez et voyez s'il existe un moyen de supprimer tout simplement le risque en ne traitant pas ces informations du côté client.

Donc, pour répondre à la question: en ce qui concerne l'envoi de données - les deux révèlent les mêmes informations à un attaquant; choisissez l'option qui convient le mieux à la situation ( ce billet de blog Treehouse peut vous y aider ), mais vous ne devriez pas vous fier sur l'une ou l'autre méthode pour réellement protéger quoi que ce soit.

43
Bob Watson

Il est facile de faire des requêtes intersite GET en incluant un simple <img> tag dans une page Web. Par exemple, dans une page de www.evilhacker.com, certains Javascript produisent un long flux de <img> tag avec les chemins choisis par l'attaquant, tous pointant vers www.targetbank.com - et votre navigateur inclura le cookie bancaire dans toutes les demandes.

Cela signifie que vous feriez mieux de ne pas prendre en charge les demandes GET ce qui implique toute modification sur le site cible. En règle générale, les requêtes GET doivent être réservées aux opérations pour lesquelles attaques de relecture ne sont pas un problème - c'est-à-dire qu'en pratique, les accès en lecture aux données statiques uniquement .

15
Thomas Pornin

Utilisez POST pour envoyer des demandes de modification de données sur le serveur.

D'après la spécification HTTP , les requêtes GET (par exemple, les paramètres dans l'URL) ne doivent être utilisées que pour les requêtes de récupération (d'où le nom GET) mais pas pour modifier les données. POST (paramètres non visibles, mais toujours non chiffrés dans la requête HTTP) doivent être utilisées chaque fois que la requête crée/met à jour/modifie des données qui doivent être stockées dans la base de données (autres que les journaux standard) . Cela rend légèrement plus difficile pour les attaquants de falsifier des requêtes intersites, ainsi que moins susceptibles de double-soumettre ou stocker accidentellement des informations secrètes dans l'historique de votre page Web/les journaux du serveur Web.

La variable pin est-elle un secret?

Ce que vous faites en ce moment semble être dangereux selon la signification de la variable pin. Est-ce que cela doit être gardé secret des écoutes indiscrètes potentielles ou les personnes interceptant la broche pourraient-elles faire une sorte d'attaque avec elle? Si tel est le cas, utilisez uniquement HTTPS (pour le chiffrement de bout en bout sur la couche de transport) pour chaque demande avec ces données secrètes. La valeur en base 64 que vous avez utilisée semblait être 3000670269 (Étant donné que je devais ajouter deux signes égaux pour en faire un bon codage b64).

Que se passerait-il si un attaquant tentait d'utiliser d'autres broches?

Disons mon pin='300670269', Mais pour tester votre système, j'ai envoyé MzAwMDY3MDI1OQ (Pour pin='3000670259'). Cela leur permettrait-il de pénétrer efficacement dans un autre compte d'utilisateurs? Si c'est le cas, vous devriez au moins faire quelque chose comme avoir une variable supplémentaire POST comme checksum=SHA256(pin+secret_server_side_string)secret_server_side_string Est une longue chaîne aléatoire (par exemple, quelque chose comme de10RRORX50UAUhx0dDIxJnzXKBAs68yjdWVz8QQ - 40 aléatoire supérieur + inférieur + chiffres a lg (62) * 40 = 238 bits d'entropie), et vos applications n'agissent sur la broche que si la somme de contrôle correspond la broche. Votre application doit générer la somme de contrôle (sans révéler la chaîne secret_server_side_string au client). Vous devez également veiller à ce que votre application effectue des comparaisons de chaînes à temps constant lors de la vérification de la somme de contrôle avec la broche, afin que votre application ne soit pas vulnérable aux synchronisation des attaques.

11
dr jimbob

En plus de la réponse de Bob, il existe un autre inconvénient de sécurité lors de l'utilisation de requêtes GET avec des paramètres sensibles.

L'URL, qui inclut les informations sensibles, est envoyée à des serveurs Web tiers hébergeant des ressources référencées par la page HTML résultante.

Exemple:

Première demande:

GET /someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ HTTP/1.0
Host: domain

Réponse à cette demande:

HTTP/1.0 OK
Content-type: text/html

<img src="http://thirdparty/hello.jpg" />

Le navigateur Web affiche le code HTML et essaie d'obtenir l'image comme suit:

GET /hello.jpg HTTP/1.0
Host: thirdparty
Referer: http://domain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

Cela peut être particulièrement un problème lorsque le HTML affiché sur la page est contrôlé par un attaquant (dans une certaine mesure, ayant du HTML sur liste blanche). Par exemple, un service de messagerie Web qui place la session dans l'URL permettrait aux attaquants d'envoyer une image dans le corps HTML de l'e-mail pointant vers le serveur/script Web de l'attaquant. Ensuite, l'attaquant doit simplement suivre l'URL dans l'en-tête Referer envoyée par le navigateur Web de la victime lors du rendu de l'image. Ce type de vulnérabilité a en fait affecté le courrier Excite (nous parlons ici d'histoire :)) et certains autres services de messagerie Web dans le passé.

3
Sandro Gauci

Il y a une récente attaque intéressante qui a été exploitée pour échapper aux règles du pare-feu d'application Web connues sous le nom de " HTTP Parameter Pollution attack ". Je vais vous expliquer avec un exemple comme

POST /index.aspx?par=1&par=2 HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Cookie: par=5; par=6
Content-Length: 19
par=3&par=4 

Pour cette application post-demande, le comportement dépendra du développeur et de Java.

  1. javax.servlet.ServletRequestInterface (analyse directe de la chaîne de requête)
  2. Java.lang.StringgetParameter (Java.lang.Stringname) Renvoie la valeur d'un paramètre de demande sous forme de chaîne, ou null si le paramètre n'existe pas
  3. Java.lang.String [] getParameterValues ​​(Java.lang.Stringname) Retourne un tableau d'objets String contenant toutes les valeurs du paramètre de demande donné, ou null si le paramètre n'existe pas.
3
Ali Ahmad

Un autre facteur de sécurité à considérer est que les journaux d'accès du serveur Web capturent généralement les URL qui ont été demandées, y compris les paramètres de chaîne de requête. Si vous ne souhaitez pas que la chaîne de requête soit enregistrée, vous devrez peut-être recourir à une demande POST.

Il y a, bien sûr, des facteurs non liés à la sécurité à prendre en compte lors du choix entre les requêtes GET et POST, telles que le comportement du navigateur lors du rechargement de la page, ou lorsque la page est rappelée via le navigateur) Bouton retour.

0
200_success