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
}
?>
Je peux penser à plusieurs raisons pour lesquelles cela ne serait pas idéal:
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.
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.
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):
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.
Ê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.
Un utilisateur malveillant obtient des informations d'identification d'administrateur. Utilisation d'une balise d'image
<img src="https://example.com/login?username=admin&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.
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.
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()
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.
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