web-dev-qa-db-fra.com

Est-ce une mauvaise pratique d'utiliser la méthode GET comme nom d'utilisateur / mot de passe de connexion pour les administrateurs?

Je travaille sur des applications web et comme vous le savez, avoir un panel administrateur est indispensable dans la plupart des cas. Nous pouvons voir que de nombreuses applications Web ont une page de connexion spécifique pour les administrateurs dans laquelle il existe un formulaire (généralement la méthode POST) que les administrateurs peuvent utiliser pour se connecter à leur panneau.

Mais comme les noms de champ sont connus, un pirate peut tenter de casser les mots de passe même si certaines méthodes de sécurité sont mises en œuvre.

Alors, quel est le problème avec une simple clé GET (comme nom d'utilisateur) et sa valeur (comme mot de passe)? Pourquoi il n'est pas beaucoup utilisé ou du moins, n'est-il pas suggéré dans de nombreux articles?

Pour les administrateurs, les pages de connexion conviviales ne sont pas vraiment nécessaires! Les données seront enregistrées dans les deux cas (GET/POST) s'il y a un attaquant MiTM.

Mais en utilisant cette méthode, les champs seront inconnus, attendez-vous aux administrateurs eux-mêmes. Voici un exemple PHP code:

"category.php": (Un nom de page sans signification)

<?php
if (isset($_GET['meaningless_user']) && $_GET['meaningless_Word'] == "something"){
    session_start();
    $_SESSION["user"] = "test";
    header('Location: category.php');   // Redirect to same or other page so GET parameters will disappear from the url     
} else {
    die(); // So it'll be like a blank page
}
?>
51
Amirreza Nasiri

Je peux penser à plusieurs raisons pour lesquelles cela ne serait pas idéal:

  • Dans l'extrait de code que vous avez publié, vous codez maintenant en dur une clé secrète dans le code source de votre programme. C'est mauvais car maintenant si vous voulez publier ou partager votre code source avec quelqu'un d'autre, vous devrez vous rappeler de caviarder cette clé. La sécurité d'un système ne doit pas dépendre du fait que son code source reste caché.
  • Cela n'évolue pas bien. Si vous n'avez qu'une seule clé secrète que tous les administrateurs doivent partager, il devient beaucoup plus facile de fuir accidentellement. Si elle fuit, vous n'auriez aucun moyen de savoir qui est responsable de la fuite. Vous pouvez fournir une clé différente à chaque administrateur, mais cela devient très compliqué très rapidement.
  • Vous ne pouvez pas changer la clé facilement. De manière générale, vous devrez probablement avoir des administrateurs de site qui sont pas également des opérateurs de serveur. Mais avec cette configuration, vous ne pouvez accorder à personne la possibilité de modifier la clé sans également autoriser l'accès au code source et au serveur, qu'ils peuvent ou non savoir comment utiliser handle. Ajuster le code source fonctionnant sur un système de production au gré des erreurs est sujet à erreur et entraînera probablement des temps d'arrêt.
  • Parce que vous utilisez GET, il est très facile pour la clé de fuir à travers les historiques du navigateur ou le partage de lien accidentel.
  • Ce n'est pas très convivial. Son utilisation nécessite de savoir comment manipuler manuellement un paramètre GET spécifique. Vous dites que la convivialité pour les administrateurs n'est pas nécessaire, mais ce n'est certainement pas vrai en général. L'ensemble de votre site doit être aussi convivial que possible, y compris le panneau administrateur.

En résumé, je peux voir ce type de système utilisé comme mesure temporaire sur un petit site, où il y a un administrateur de site qui a également écrit le code source du site et gère le serveur. Mais quelque chose de plus grand que cela, vous voudrez avoir un véritable panneau de connexion administrateur, avec des informations d'identification hachées et salées stockées dans la base de données comme tout autre utilisateur.

63
tlng05

Cela stockerait le lien de connexion avec le mot de passe et le nom d'utilisateur dans l'historique du navigateur. Il pourrait également être accidentellement capturé par des éléments tels que les journaux de pare-feu, qui ne captureraient pas les variables de publication.

137
jdow

Pas strictement du point de vue de la sécurité, mais Hypertext Transfer Protocol - HTTP/1.1 RFC 2616 le dit clairement:

... la convention a été établie que les méthodes GET et HEAD NE DEVRAIENT PAS avoir la signification de prendre une action autre que la récupération . Ces méthodes doivent être considérées comme "sûres". Cela permet aux agents utilisateurs de représenter d'autres méthodes, telles que POST, PUT et DELETE, de manière spéciale, afin que l'utilisateur soit informé du fait qu'un une action est demandée.

GET doit être utilisé uniquement pour la récupération. Dans votre cas, vous soumettez des données au serveur, le serveur effectue ces actions spécifiques (au minimum):

  • Authentification d'un utilisateur
  • Création d'une session pour suivre l'état de l'utilisateur (PHP crée des données de session dans des fichiers plats ou une base de données)
  • Définition d'un cookie de session pour suivre la session

POST sur HTTPS serait la méthode préférée pour transmettre des données sensibles; nom d'utilisateur, mot de passe dans ce cas.

28
AbraCadaver

Êtes-vous à l'aise avec le stockage des mots de passe administrateur en texte clair dans les journaux d'accès à votre serveur Web?

Le problème que je vois ici est qu'une demande GET doit mettre tous les noms et valeurs de champ dans l'URI de la demande. Les URI de demande sont enregistrés par toutes sortes de processus et seront probablement stockés, dans leur intégralité, dans le journal d'accès au serveur Web.

Cela signifie que le journal d'accès à votre serveur Web augmente les risques de sécurité car il contient désormais les noms d'utilisateur et les mots de passe des pages de connexion basées sur GET. Bien que vous puissiez généralement traiter les journaux de serveur comme contenant des informations privilégiées (les adresses IP de votre client par exemple), ils ne sont généralement pas suffisamment sensibles pour contenir suffisamment d'informations pour compromettre l'interface administrative d'un client.

POST est supérieur pour cela, car les noms et valeurs de champ ne sont pas stockés dans le journal.

26
Andy Holland

Un utilisateur malveillant obtient des informations d'identification d'administrateur. Utilisation d'une balise d'image

<img src="https://example.com/login?username=admin&amp;password=topsecret" style="display:none"> 

ils trompent votre navigateur pour se connecter (les images ne sont pas soumises à des restrictions interdomaines par défaut). Ils peuvent ensuite utiliser une série d'appels "image" pour obtenir ou modifier des données (beaucoup d'appels AJAX utilisent également GET de manière incorrecte). Il existe façons d'éviter cela =, mais la plupart des gens ne les activent pas. Si vous utilisez POST, ce vecteur d'attaque ne fonctionne pas.

4
Machavity

Le problème de l'utilisation de la méthode get est que les données seront visibles à l'écran et dans les journaux du serveur Web par défaut.

Ma règle de base est d'utiliser la publication pour les mots de passe et les grandes informations telles que les éditeurs d'articles de blog et d'utiliser get pour presque tout le reste. Bien sûr, il existe quelques exceptions où les données sont trop sensibles pour apparaître même dans les journaux. Mais ceux-ci sont rares même dans le secteur des entreprises.

Par exemple, j'ai une fonctionnalité de type assistant avec 5 étapes où je génère un identifiant de processus à la première étape et à chaque étape, vous verrez ?proc_id=123. PHP prend en charge la chaîne de requête même dans les méthodes de publication. Même dans une étape où les données du formulaire sont trop grandes et je suis obligé d'utiliser la méthode de publication, l'ID du processus est toujours visible dans l'URL comme ?proc_id=123.

Cela facilite la création de signets, la compréhension des journaux d'accès et la sensibilisation des tiers qui souhaitent s'intégrer à mes applications.

Certaines précautions doivent être prises dans ce scénario pour éviter des problèmes avec le bouton de retour tels que la suppression des URL d'historique qui ne doivent pas être soumises à nouveau. La plupart des actions de sauvegarde sont comme ça.

Bien sûr, le POST ne vous protégera pas d'une attaque MiTM. Il empêchera seulement que des informations sensibles telles que les mots de passe soient écrites dans les journaux de votre site et dans l'historique local du navigateur.

3
Lucas

Considérez également que les requêtes GET sont destinées à ne rien changer du côté serveur. Un changement d'état comme "déconnecté" -> "connecté" doit toujours être effectué avec une requête POST.

Avoir un paramètre GET comme

https://example.com/loginpage.php?password=topsecret 

est sémantiquement exactement le même que

https://example.com/loginpage/password/topsecret 

Il n'y a donc aucune authentification. C'est juste une URL "secrète" que vous devez connaître pour vous "connecter".

Pour que ce soit plus clair. Si vous utilisez Apache par exemple, vous pouvez obtenir le même résultat avec une redirection comme celle-ci:

 RedirectTemp mot de passe/topsecret trèsobfuscateddirectoryname/login 

puis sur la page de connexion, placez votre session_start()

3
Andre Geddert

Même si l'utilisateur et le mot de passe n'étaient pas stockés dans l'historique du navigateur (ce qu'ils sont, en tant que paramètres d'URL), il est extrêmement facile pour tout pirate de voler vos informations. Il apparaîtra dans les journaux du serveur, ce qui rend encore plus facile d'effectuer une attaque de l'homme du milieu. Il permet également de nombreuses mauvaises pratiques, comme les personnes qui mettent en signet l'URL de connexion, l'oublient et permettent à d'autres humains d'utiliser leur navigateur Web.

TL; DR: C'est une horrible idée.

2
Leo Wilson

Oui, c'est une mauvaise pratique. Tout avantage de sécurité disponible en ayant un nom de champ secret peut également être obtenu en ajoutant ce secret au mot de passe.

Au lieu de GET avec

elephant=rthg4e5sdc

il vaut mieux utiliser POST with

password=elephantrthg4e5sdc

Et bien sûr, vous pouvez à nouveau augmenter la sécurité en changeant cela en quelque chose de plus comme

password=ehu3dva7rthg4e5sdc
1
bdsl