Manuel PHP
Précédent | Chapitre 4. Sécurité | Suivant

# Rapport d'erreur

En terme de sécurité, il y a deux conséquence au rapport d'erreur. D'un coté, cela améliore la sécurité, mais d'un autre, cela la réduit aussi.

Une tactique d'attaque standard consiste à faire faire des erreurs au système, et lire les variables d'environnement et de contexte qui sont retournées. Cela permet au pirate de lire de nombreuses informations sur le serveur, et de détecter des faiblesses du serveur. Par exemple, si un intrus a glané des informations sur votre page, avec une première utilisation de votre site, il peut essayer de remplacer les variables par ses propres valeurs :

Exemple 4-5. Attacque de site avec une page HTML personnalisée
    <form method="post" action="http://www.site.cible.com/?username=badfoo&password=badfoo">
    <input type="hidden" name="username" value="badfoo">
    <input type="hidden" name="password" value="badfoo">
    </form>

Les erreurs PHP qui sont normalement retournées peuvent être très pratiques pour un développeur qui essaie de débugger un script, car elles donnent de précieux renseignements tels que quelle fonction a échoué, quel fichier n'a pas été trouvé, quel script PHP a buggé, et quelle ligne est en faute. Toutes ces informations sont exploitables. Il est commun aux développeurs PHP d'utiliser les fonctions show_source(), highlight_string(), ou highlight_file() comme outils de débuggage, mais sur un site en production, cela expose des variables cachées, des syntaxes non vérifiées ou d'autres informations critiques. Il est particulièrement dangeureux d'exécuter du code de sources connues, avec les gestionnaires de débuggage. Si l'intrus peut comprendre votre technique habituelle d'utilisation, il peut tenter une attaque frontale sur une page, en envoyant des chaînes de débuggage :

Exemple 4-6. Exploiter des variables classiques de débuggage
    <form method="post" action="http://www.site.cible.com/?errors=Y&showerrors=1"&debug=1">
    <input type="hidden" name="errors" value="Y">
    <input type="hidden" name="showerrors" value="1">
    <input type="hidden" name="debug" value="1">
    </form>

Indépendamment de la gestion des erreurs, la possibilité de tester la gestion des erreurs d'un système conduit à un trou de sécurité, et la diffusion de plus d'informations sur votre système.

Si un pirate affiche une page html, et essaye de la tester (pour rechercher des faiblesses du système), il peut déterminer sur quel système PHP a été compilé.

Une erreur de fonction indique si un système supporte une base de données spécifique, ou bien indique comment la page a été générée. Cela peut orienter l'intrus vers les ports de cette base de données ou bien vers une attaque liée à cette application. En envoyant des données erronées, par exemple, un pirate peut déterminer l'ordre d'authentification dans un script (à partir des lignes d'erreurs), et d'essayer de les exploiter ailleurs, dans le script.

Une erreur de fichier, ou une erreur générale PHP peut indiquer quelles sont les permissions du serveur web, ainsi que la structure et l'organisation des fichiers. Les gestionnaires d'erreurs utilisateurs peuvent aussi aggraver ce problème, en permettant l'exploitation facile d'informations préalablement cachées.

Il y a trois solutions majeures à ces problèmes : la première est de scruter toutes les fonctions, et d'essayer de traiter toutes les erreurs. La deuxième est d'inactiver le rapport d'erreur, dès que le script est en production. La troisième est d'utiliser les fonctions de gestions des erreurs. Suivant votre politique de sécurité, vous pouvez utiliser un panachage savant des trois méthodes.

Une méthode pour gagner du temps est d'utiliser la fonction error_reporting(), pour vous aider à sécuriser le code, et détecter les utilisations dangeureuses de variables. Vous testez votre code en béta-test avec la valeur `E_ALL`, et vous pouvez rapidement repérer les variables qui ne sont pas protégées. Une fois que le code est prêt à être déployé, utilisez la constante `E_NONE`, pour isoler votre code.

Exemple 4-7. Détecter des variables non protégées avec E_ALL
    <?php
      if ($username) {
    // Non initialisée, ou vérifée avant utilisation
        $good_login = 1;
      }
      if ($good_login == 1) {
    // Si le test ci-dessus échoue, les valeurs n'ont pas été testées
        fpassthru ("/données/très/très/sensibles/index.html");
      }
    ?>

Précédent | Sommaire | Suivant
Sécurité des fichiers | Niveau supérieur | Utilisation des variables HTTP