web-dev-qa-db-fra.com

Est-il sûr d'afficher une erreur de requête MySQL dans la page Web en cas de problème?

Est-il sûr d'afficher la requête détaillée dans la page Web d'erreur avec les détails ci-dessous?

** L'instruction INSERT est en conflit avec la contrainte FOREIGN KEY "ABC". Le conflit s'est produit dans la base de données ** L'instruction est terminée. [INSERT INTO **] **

Je sais que montrer ce genre d'erreur aidera les testeurs de pénétration et les pirates, mais j'ai besoin de quelqu'un pour faire la lumière sur ce point. Comment ces informations peuvent-elles être utilisées pour l'injection SQL ou ce genre de choses? Ou est-il acceptable d'afficher des informations aussi sensibles?

19
Ruban Savvy

Les utilisateurs finaux ne devraient jamais voir les détails sanglants de votre environnement.

Au lieu de cela, il est plus professionnel d'afficher une page générique "Désolé, quelque chose s'est mal passé". Au moins, les visiteurs peuvent voir que vous disposez d'un véritable mécanisme de gestion des erreurs sur votre site Web.

Cependant, ces erreurs doivent être écrites dans le journal des erreurs mysql et doivent également déclencher une notification par e-mail ou autrement à l'équipe informatique. Ces erreurs ne doivent pas se produire, cela peut donc être le signe que votre site est défaillant ou peut être attaqué.

47
Anonymous

Non, ce n'est certainement pas sûr car il crée des vecteurs d'attaque par injection SQL supplémentaires qui ne sont pas présents autrement. Exemple: si vous avez un flux d'injection SQL dans une insertion, il s'agit d'une sorte d'injection "aveugle" car l'insertion ne renvoie aucune ligne de résultat à l'appelant. Mais si vous ramenez un message d'erreur d'insertion potentiel au client, vous le rendez vulnérable à l'injection dite "XPath" (voir ce document pour plus de détails). L'essentiel est que vous injectiez une fonction xml qui est censée calculer une variable de type de données xml. L'un des arguments de la fonction est une variable xpath qui peut à nouveau être calculée par des instructions select et une concaténation de chaînes. Au lieu de fournir un xpath valide, vous effectuez une sélection (par exemple, "sélectionnez password_hash parmi les utilisateurs où id = 'admin'"). Ainsi, la base de données exécutera un INSERT qui est délibérément erroné lors de votre injection. Le résultat sera un message d'erreur comme

 'bb9af55cd325deaa89bb7b4e36085b4d' n'est pas un xpath valide 

Si vous affichez des messages d'erreur comme ceux-ci à l'appelant, cela peut être utilisé pour énumérer essentiellement la base de données. J'ai vu cela se produire récemment. Le message d'erreur a été réduit à 30 caractères et il était uniquement possible de sélectionner une colonne et une ligne à la fois, mais il était toujours possible d'énumérer la base de données entière avec.

13
kaidentity

D'autres ont à juste titre expliqué pourquoi les détails de MySQL ne devraient pas être exposés via l'interface utilisateur principale d'un site Web/d'une application sur un serveur de production.

Mais il y a un problème plus large et beaucoup plus élevé en jeu lorsque vous affichez des erreurs à un utilisateur final comme celui-ci:

Il télégraphie essentiellement l'idée que le serveur/site est mal géré.

Ce qui signifie que vous êtes une cible mûre pour le piratage non pas à cause du contenu des détails mais parce que les détails ont été exposés pour commencer.

Votre attitude en tant que développeur d’applications - administrateur système et autres - consiste à faire en sorte que votre produit final puisse échouer gracieusement d’une manière qui n’expose pas les "ossements" de l’architecture du système tout en vous transmettant malgré tout des données de débogage utiles.

7
JakeGould

Si votre application est correctement conçue, l'affichage du texte des messages d'erreur ne devrait pas être un problème de sécurité. Si c'était le cas, cela signifierait que votre sécurité repose sur l'obscurcissement qui est considéré comme une mauvaise pratique.

Cela étant dit, la vraie question est: quelle sera l'expérience utilisateur face à des messages comme ça? Si votre application est destinée aux utilisateurs moyens, ils recevront un message qui ne leur apportera aucune information utile: soit ils ne comprennent rien, soit ils ne peuvent rien faire d'utile. Pire, ils pourraient penser ces développeurs paresseux n'ont même pas correctement traité leurs erreurs - c'est ce que je pense ...

C'est la raison pour laquelle l'utilisation courante est d'afficher un message plus doux indiquant que quelque chose s'est mal passé, veuillez réessayer et contacter le support si l'erreur persiste, sans les détails sanglants. Le message d'erreur complet ne doit être affiché que lorsque l'application est exécutée par le support dans un mode spécial car les techniciens du support sont intéressés par les détails de l'erreur.

Si vous voulez vraiment faire le plus beau travail avec des erreurs:

  • assurez-vous que vous enregistrez l'erreur et son contexte: date-heure, utilisateur, paramètres de la demande, éventuellement les données de session clés pour permettre au support de remplir un ticket est quelque chose doit être fixé dans l'application
  • afficher uniquement les informations soft externes à l'utilisateur
  • ajouter un moyen spécifique pour le support d'accéder à tous les détails de l'erreur lorsqu'ils essaient de le reproduire - cela a un coût mais sera très apprécié par les techniciens du support
  • éventuellement attribuer un identifiant unique à l'incident et l'afficher à l'utilisateur

Cette dernière possibilité n'a de sens que pour les applications de grande valeur avec un nombre limité d'utilisateurs. Cela permettra au support d'avoir immédiatement toutes les références du problème lorsqu'il sera contacté par l'utilisateur. Mais cela signifie également que vous êtes prêt à répondre individuellement à toute erreur qui pourrait être très coûteuse pour les applications normales.

3
Serge Ballesta

Tout détail technique pouvant être obtenu par un attaquant peut potentiellement être exploité pour exploiter des failles ou pour mieux comprendre le système (pour plus tard exploiter des failles ..). Dans votre cas, il pourrait éventuellement être utilisé pour SQL Injection, mais cela pourrait également permettre d'identifier votre SGBD (si vous utilisez des requêtes natives avec des fonctions propres à MySQL par exemple), puis de tester des exploits spécifiques au SGBD si le système n'est pas corrigé.

Donc, pour répondre à la question: non, il n'est pas sûr de divulguer vos requêtes car cela augmente votre risque de sécurité.

Comme mentionné dans les commentaires, la meilleure pratique consiste à masquer ces informations dans les environnements de production.

Une pratique courante (par exemple les profils Maven pour Java développeurs) consiste à créer un projet pour un environnement spécifique. Le profil "production" aurait une configuration différente qui n'affiche pas les traces de pile sur les réponses html mais enregistrez-les uniquement dans le backend.

En tant que sidenote, l'affichage de messages d'erreur techniques peut également "attirer" des attaquants aléatoires qui souhaitent perfectionner leurs compétences en piratant n'importe quel système, car cela vous fait ressembler à une cible faible.

2
niilzon

Un certain nombre de réponses ont souligné qu'il n'est pas recommandé d'afficher ces erreurs. Cependant, je vais me concentrer sur votre question: est-ce sûr?

Regardons un exemple de message d'erreur. Cette application est écrite en Python et Flask:

enter image description here

Cela nous dit quelques choses sur l'application: elle utilise SQLite, l'application est en c:\jobs\token\, il y a une table data et quelques autres choses.

Il n'y a pas de données utilisateur ici. Cela ne révèle pas le solde du compte d'une autre personne, les messages privés, quelque chose comme ça. Bien qu'il soit possible qu'un message d'erreur puisse le révéler, en pratique, c'est rare.

Dans quelle mesure les détails de la demande sont-ils confidentiels? La principale préoccupation ici est de faciliter la vie d'un attaquant. Certaines vulnérabilités, telles que la traversée de chemin et l'injection SQL, sont plus faciles à exploiter avec un peu de fuite d'informations dans les messages d'erreur. Cependant, ils sont toujours exploitables sans fuite d'informations - c'est juste un travail plus difficile. La restriction des messages d'erreur n'arrête pas ces attaques. Cela ne rend l'exploitation que légèrement plus difficile. Le changement est si mineur que je ne le considère même pas lorsque j'évalue le risque d'une vulnérabilité comme l'injection SQL.

Donc, la réponse à votre question est oui, c'est sûr . Ce n'est pas la meilleure pratique, mais ce n'est en aucun cas particulièrement dangereux.

2
paj28

Donner des détails sur la configuration de votre base de données est généralement une mauvaise idée. Les utilisateurs légitimes ne devraient pas avoir besoin de le savoir et les utilisateurs malveillants peuvent y trouver quelque chose qu'ils auraient autrement à deviner.

D'autres réponses ont plutôt bien détaillé le type de risque que cela peut poser pour votre base de données.

L'affichage du rapport d'erreur peut également ouvrir un tout nouveau vecteur d'attaque sur votre site Web. Dites, que se passe-t-il si j'ai demandé le document avec l'ID <script>alert('XSS')</script> - probablement que l'on ne trouve pas dans la base de données et j'obtiens le rapport d'erreur. Les gestionnaires d'erreurs ne sont souvent pas la partie la plus soigneusement construite d'une base de code, donc j'ai peut-être juste réussi à exécuter une attaque XSS contre le site.

1
Niko Kiirala

Les messages d'erreur de syntaxe pour les instructions SQL ne devraient jamais être révélés, car cela ferait vraiment gagner du temps à l'attaquant essayant d'exploiter un SQLi vulnérabilité.

Les numéros de ligne d'application sont moins graves, mais du point de vue de la sécurité, la page d'erreur ne devrait pas révèle tous les détails, car les pages d'erreur sont souvent une étape intermédiaire utilisée pour terminer un piratage réussi.

Si vous souhaitez conserver la commodité des pages d'erreur détaillées, je recommanderais de configurer votre système pour ne révéler ces détails qu'aux personnes autorisées en fonction de l'adresse IP du LAN, et peut-être aussi d'une authentification basée sur les cookies. Si vous codez vos propres pages d'erreur personnalisées, cela devrait être assez simple à faire.

Sinon, vous devrez simplement utiliser l'approche moins pratique de consulter les journaux d'erreurs chaque fois que vous aurez besoin de ces détails.

1
Bryan Field

Il est fortement recommandé de ne pas montrer l'erreur réelle aux utilisateurs. Cela s'applique partout, pas seulement dans MySQL. Vous devez utiliser un bloc try catch pour gérer les erreurs.

Dans votre cas, un utilisateur ou un attaquant peut voir le nom de votre table, les détails de la ligne et le nom. Un pirate peut utiliser l'injection SQL ou toute autre attaque via votre erreur fournie. Il est donc préférable de masquer ces détails sensibles.

0
Parth Makadiya

C'est certainement pas une bonne idée de montrer les détails de votre environnement de base de données aux utilisateurs. Le backend de votre système devrait être un mystère total pour les utilisateurs. Les journaux de votre serveur devraient vous donner suffisamment d'informations pour diagnostiquer des erreurs telles que celle que vous avez montrée.

Vous devez également tenir compte de ce que les utilisateurs peuvent voir s'ils consultent la source d'une page de votre application Web - la source de la page révèle-t-elle les détails de la table ou de la colonne de la base de données dans les noms de champ de formulaire?

Si vous avez le temps, vous pouvez jouer avec les attaquants en affichant de faux messages d'erreur, qui décrivent des objets de base de données qui n'existent pas dans votre base de données. Les attaquants seraient alors frustrés d'essayer d'attaquer ces tables.

0
hairysocks