Rapport d'erreurs
En termes de sécurité, il y a deux conséquences 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 à analyser les types des erreurs qui sont retournées,
ainsi que leur contexte. Cela permet à l'attaquant d'obtenir des
informations à propos du serveur, en vue de détecter de possibles faiblesses.
Par exemple, si un intrus a glané des informations sur une page dépendant
de la soumission préalable d'un formulaire, il peut essayer d'écraser les
variables par ses propres valeurs :
Exemple #1 Attaque de variables 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éboguer un
script, car elles donnent de précieux renseignements tels que
la fonction qui a échouée, depuis quel fichier PHP, et même le numéro
de la ligne à laquelle l'erreur s'est produite. Toutes ces informations sont exploitables.
Il n'est pas rare que les développeurs PHP utilisent
les fonctions show_source(),
highlight_string(), ou
highlight_file() comme outils de déboguage, mais sur un
site en production, cela peut exposer des variables cachées, des syntaxes non
vérifiées, ou d'autres informations critiques. Il est particulièrement
dangereux d'exécuter du code de sources connues avec des gestionnaires de
débogage inclus, ou de travailler avec des techniques de débogage répandues.
Si l'attaquant peut déterminer quelle technique générale vous utilisez, il peut
tenter une attaque frontale sur une page, en envoyant des chaînes de débogage connues :
Exemple #2 Exploiter des variables classiques de débogage
<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 méthode de gestion des erreurs, la possibilité de tester
un système pour identifier des erreurs revient à fournir à un attaquant
plus d'informations sur votre système.
Par exemple, le style même d'une erreur PHP standard indique d'un système fait
tourner PHP.
Si un attaquant affiche une page .html, et essaye de la tester (pour rechercher des
faiblesses connues du système), en lui envoyant des données invalides, il peut déterminer
qu'elle a été construite via un script PHP.
Une erreur de fonction peut indiquer si un système supporte une base de
données spécifique, ou bien donner des indices quant à la façon dont une page a
été conçue ou développé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'identification dans un script (à partir des numéros de lignes d'erreurs),
ou sonder à la recherche de failles qui pourraient être exploitées à
différents endroits du script.
Une erreur de fichier, ou une erreur générale de 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 seconde est de totalement désactiver le rapport d'erreur, dès
que le script est en production. La troisième est d'utiliser les
fonctions de gestion des erreurs de PHP pour créer vos propres gestionnaires d'erreurs.
En fonction de votre politique de sécurité, il se peut que vous arriviez à la conclusion
que ces solutions sont toutes les trois applicables à votre situation.
Une méthode pour gagner du temps est d'utiliser la fonction
error_reporting(), pour vous aider à
sécuriser votre code, et détecter certaines utilisations dangereuses de variables.
En testant votre code, avant le déploiement, avec E_ALL
,
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é, vous devriez soit désactiver complètement
le rapport d'erreur en passant 0 à la fonction error_reporting(),
soit en désactivant l'affichage des erreurs en utilisant l'option de configuration
display_errors
de php.ini. Si vous choisissez la
seconde solution, vous devriez également définir le chemin vers votre fichier
de log en utilisant la directive de configuration error_log
,
et en activant la directive log_errors
.
Exemple #3 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");
}
?>