Abus d'inclure
1. Cause de la vulnérabilité :
Include est la fonction la plus couramment utilisée dans l'écriture de sites Web PHP et prend en charge les chemins relatifs. Il existe de nombreux scripts PHP qui utilisent directement une variable d'entrée comme paramètre d'inclusion, provoquant des vulnérabilités telles qu'une référence de script arbitraire et une fuite de chemin absolu. Regardez le code suivant :
...
$includepage=$_GET["includepage"];
include($includepage);
...
Évidemment, il suffit de soumettre différentes variables Includepage pour obtenir la page souhaitée. Si vous soumettez une page qui n'existe pas, vous pouvez provoquer une erreur du script PHP et divulguer le chemin absolu réel (la solution à ce problème est expliquée dans l'article suivant).
2. Résolution de vulnérabilité :
La solution à cette vulnérabilité est très simple : elle consiste d’abord à déterminer si la page existe, puis à l’inclure. Ou plus strictement, utilisez un tableau pour spécifier les fichiers pouvant être inclus. Regardez le code suivant :
$pagelist=array("test1.php","test2.php","test3.php"); // Ceci spécifie les fichiers qui peuvent être inclus
if(isset($_GET["includepage"])) //Détermine s'il existe $includepage
{
$includepage=$_GET["includepage"];
foreach($pagelist comme $prepage)
{
if($includepage==$prepage) //Vérifie si le fichier est dans la liste autorisée
{
include($prépage);
$checkfind=true ;
casser;
}
}
if($checkfind==true){ unset($checkfind })
else{ die("Page de référence invalide!");
}
Cela résoudra très bien le problème.
Astuce : Les fonctions présentant ce problème incluent : require(), require_once(), include_once(), readfile(), etc. Vous devez également faire attention lors de l'écriture.
Les variables d'entrée ne sont pas filtrées
1. Cause de la vulnérabilité :
Cette vulnérabilité est apparue depuis longtemps dans ASP, provoquant d'innombrables vulnérabilités d'injection à cette époque. Mais comme PHP avait une petite influence à l’époque, peu de gens pouvaient y prêter attention. Pour PHP, l'impact de cette vulnérabilité est plus important que celui d'ASP, car davantage de scripts PHP utilisent des bases de données texte. Bien entendu, il existe également le problème de l’injection d’instructions SQL. Pour donner un exemple plus classique, le premier est la base de données :
$id=$_GET["id"]; $
query="SELECT * FROM my_tablewhere id='".$id."'" //Une vulnérabilité d'injection SQL très classique
$result=mysql_query($query);
Il est évident ici que l'on peut utiliser l'injection pour obtenir d'autres contenus de la base de données. Je ne le décrirai pas en détail ici. Tout comme l’injection ASP, vous pouvez jeter un œil aux défenses noires précédentes. Ensuite, nous examinons le problème des bases de données texte :
$text1=$_POST["text1"];
$text2=$_POST["text2"];
$text3=$_POST["text3"];
$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);
La vulnérabilité du texte est sans doute encore plus grave. Si nous insérons un petit morceau de code PHP dans la variable soumise, nous pouvons transformer cette base de données texte test.php en une porte dérobée PHP. Même l'insertion du code de téléchargement nous permet de télécharger une porte dérobée PHP complète. Augmentez ensuite les privilèges et le serveur est à vous.
2. Résolution de vulnérabilité :
La solution à cette vulnérabilité est en fait très simple : filtrer strictement toutes les variables soumises. Remplacez certains caractères sensibles. Nous pouvons remplacer le contenu HTML à l’aide de la fonction htmlspecialchars() fournie par PHP. Voici un exemple :
//Construire la fonction de filtre www.knowsky.com
fonction flt_tags($text)
{
$badwords=array("Va te faire foutre", "fuck"); //Liste de filtres de mots
$text=rtrim($text);
foreach ($badwords as $badword) //Filtrer le vocabulaire ici
{
if(stristr($text,$badword)==true){ die("Erreur : le contenu que vous avez soumis contient des mots sensibles, veuillez ne pas soumettre de contenu sensible." }
}
$text=htmlspecialchars($text); //Remplacement HTML
//Ces deux lignes remplacent le retour chariot par
$text=str_replace("r","
",$texte);
$text=str_replace("n","",$text);
$text=str_replace("&line;","│",$text); //Remplacez le séparateur de base de données texte "&line;" par le "│" pleine chasse.
$text=preg_replace("/s{ 2 }/"," ",$text); //remplacement d'espace);
$text=preg_replace("/t/"," ",$text); // Toujours en train de remplacer les espaces
if(get_magic_quotes_gpc()){ $text=stripslashes($text); } //Si magic_quotes est activé, remplacez '
renvoie $texte ;
}
$text1=$_POST["text1"];
$text2=$_POST["text2"];
$text3=$_POST["text3"];
//Filtrer toutes les entrées
$text1=flt_tags($text1);
$text2=flt_tags($text2);
$text3=flt_tags($text3);
$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);
Après quelques remplacements et filtrages, vous pouvez écrire les données en toute sécurité dans du texte ou dans une base de données.
Le jugement de l’administrateur est incomplet
1. Cause de la vulnérabilité :
Nous utilisons PHP pour écrire des scripts, qui impliquent généralement des autorisations d'administrateur. Certains scripts émettent uniquement un jugement « oui » sur les autorisations d'administrateur, mais ignorent souvent le jugement « non ». Lorsque register_globals est activé dans le fichier de configuration PHP (il est désactivé par défaut dans les versions postérieures à 4.2.0, mais de nombreuses personnes l'activent pour des raisons de commodité, ce qui constitue un comportement extrêmement dangereux), il y aura des situations où des variables seront soumises pour usurper l'identité. administrateurs. Jetons un coup d'œil à l'exemple de code :
$cookiesign="admincookiesign"; //Détermine si la variable de cookie de l'administrateur
$adminsign=$_COOKIE["sign"]; //Obtenir la variable de cookie de l'utilisateur
if($adminsign==$cookiesign)
{
$admin=vrai ;
}
if($admin){ echo "Vous êtes maintenant administrateur.";
Ça a l'air très sûr, haha. Nous supposons maintenant que register_globals est activé dans le fichier de configuration PHP. Nous avons soumis une telle adresse "test.php?admin=true", avez-vous vu le résultat ? Bien que nous n'ayons pas le bon cookie, parce que register_globals est activé, la variable admin que nous avons soumise est automatiquement enregistrée comme vraie. De plus, le script n'a pas de jugement « non », ce qui nous permet d'obtenir avec succès les autorisations d'administrateur via admin=true. Ce problème existe sur la plupart des sites Web et forums.
2. Résolution de vulnérabilité :
Pour résoudre ce problème, il suffit d'ajouter un jugement "non" à l'administrateur dans le script. Nous supposons toujours que register_globals est activé dans le fichier de configuration PHP. Jetez un oeil au code:
$cookiesign="admincookiesign"; //Détermine si la variable de cookie de l'administrateur
$adminsign=$_COOKIE["sign"]; //Obtenir la variable de cookie de l'utilisateur
if($adminsign==$cookiesign)
{
$admin=vrai ;
}
autre
{
$admin=faux ;
}
if($admin){ echo "Vous êtes maintenant administrateur.";
De cette façon, même si l'attaquant soumet la variable admin=true sans le bon cookie, le script définira $admin sur False dans les jugements futurs. Cela résout une partie du problème. Cependant, comme $admin est une variable, si une faille se produit dans d'autres références de script à l'avenir et que $admin est réaffecté, une nouvelle crise se produira. Par conséquent, nous devons utiliser des constantes pour stocker la détermination des autorisations d'administrateur. Utilisez l'instruction Define() pour définir une constante admin pour enregistrer les autorisations d'administrateur. Si elle est réaffectée après cela, une erreur se produira, atteignant ainsi l'objectif de protection. Regardez le code suivant :
$cookiesign="admincookiesign"; //Détermine si la variable de cookie de l'administrateur
$adminsign=$_COOKIE["sign"]; //Obtenir la variable de cookie de l'utilisateur
if($adminsign==$cookiesign)
{
définir(admin,true);
}
autre
{
définir(admin,false);
}
if(admin){ echo "Vous êtes maintenant en statut d'administrateur.";
Il convient de noter que nous utilisons l'instruction Define, donc lorsque vous appelez la constante Admin, n'ajoutez généralement pas le symbole de variable $ devant, mais utilisez Admin et !admin.
Base de données texte exposée
1. Cause de la vulnérabilité :
Comme mentionné précédemment, en raison de la grande flexibilité des bases de données texte, aucun support externe n'est requis. De plus, PHP possède de très fortes capacités de traitement de fichiers, de sorte que les bases de données texte sont largement utilisées dans les scripts PHP. Il existe même plusieurs bons programmes de forum qui utilisent des bases de données texte. Mais il y a des gains et des pertes, et la sécurité des bases de données texte est inférieure à celle des autres bases de données.
2. Résolution de vulnérabilité :
La base de données texte agit comme un fichier ordinaire, téléchargeable, tout comme une MDB. Par conséquent, nous devons protéger les bases de données texte de la même manière que les MDB. Remplacez le nom de suffixe de la base de données texte par .PHP. et rejoignez la première ligne de la base de données. De cette façon, la base de données texte sera traitée comme un fichier PHP et l'exécution se terminera sur la première ligne. Autrement dit, une page vide est renvoyée pour atteindre l'objectif de protection de la base de données texte.
Fuite d'un mauvais chemin
1. Cause de la vulnérabilité :
Lorsque PHP rencontre une erreur, il donnera l'emplacement, le numéro de ligne et la raison du script d'erreur, par exemple :
Remarque : Utilisation d'un test constant non défini - 'test' supposé dans D:interpubbigflytest.php à la ligne 3
Beaucoup de gens disent que ce n’est pas grave. Mais les conséquences d’une fuite du chemin réel sont inimaginables. Pour certains intrus, cette information est très importante. En fait, de nombreux serveurs sont désormais confrontés à ce problème.
Certains administrateurs réseau définissent simplement display_errors dans le fichier de configuration PHP sur Off pour résoudre le problème, mais je pense que cette méthode est trop négative. Parfois, nous avons vraiment besoin de PHP pour renvoyer des informations d'erreur pour le débogage. Et lorsque quelque chose ne va pas, vous devrez peut-être également donner une explication à l’utilisateur ou même accéder à une autre page.
2. Résolution de vulnérabilité :
PHP a fourni une fonction de gestion des erreurs personnalisée set_error_handler() depuis la version 4.1.0, mais peu de rédacteurs de scripts le savent. Parmi les nombreux forums PHP, je n'en ai vu que quelques-uns gérer cette situation. L'utilisation de set_error_handler est la suivante :
chaîne set_error_handler ( rappel error_handler [, int error_types])
Nous utilisons désormais une gestion personnalisée des erreurs pour filtrer les chemins réels.
//Admin est la détermination de l'identité de l'administrateur, true est l'administrateur.
//La fonction de gestion des erreurs personnalisée doit avoir ces quatre variables d'entrée $errno, $errstr, $errfile, $errline, sinon elle ne sera pas valide.
fonction my_error_handler($errno,$errstr,$errfile,$errline)
{
//Si vous n'êtes pas administrateur, filtrez le chemin réel
si(!admin)
{
$errfile=str_replace(getcwd(),"",$errfile);
$errstr=str_replace(getcwd(),"",$errstr);
}
commutateur ($errno)
{
cas E_ERROR :
echo "ERREUR : [ID $errno] $errstr (Ligne : $errline de $errfile)
n";
echo "Le programme s'est arrêté, veuillez contacter l'administrateur.";
// Quittez le script lorsque vous rencontrez une erreur de niveau d'erreur
sortie;
pause ;
cas E_WARNING :
echo "AVERTISSEMENT : [ID $errno] $errstr (Ligne : $errline de $errfile)
n";
pause ;
valeur par défaut :
//Ne pas afficher les erreurs de niveau de notification
casser;
}
}
//Définit la gestion des erreurs sur la fonction my_error_handler
set_error_handler("mon_error_handler");
…
De cette façon, la contradiction entre la sécurité et la commodité du débogage peut être bien résolue. Et vous pouvez également réfléchir à rendre le message d’erreur plus beau pour qu’il corresponde au style du site Web. Mais notez deux points :
(1) E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR et E_COMPILE_WARNING ne seront pas traités par ce handle, c'est-à-dire qu'ils seront affichés de la manière la plus originale. Cependant, ces erreurs sont causées par des erreurs de compilation ou du noyau PHP et ne se produiront pas dans des circonstances normales.
(2) Après avoir utilisé set_error_handler(), error_reporting() ne sera pas valide. Autrement dit, toutes les erreurs (à l'exception des erreurs mentionnées ci-dessus) seront transmises à la fonction personnalisée pour traitement.
Pour d'autres informations sur set_error_handler(), vous pouvez vous référer au manuel PHP officiel.
Vulnérabilité POST
1. Cause de la vulnérabilité :
Comme mentionné précédemment, s'appuyer sur register_globals pour enregistrer des variables est une mauvaise habitude. Dans certains programmes de livres d'or et de forums, il est encore plus nécessaire de vérifier strictement la méthode d'obtention des pages et l'intervalle de temps entre les soumissions. Pour éviter les messages de spam et les soumissions externes. Jetons un coup d'œil au code suivant pour un programme de livre d'or :
...
$text1=flt_tags($text1);
$text2=flt_tags($text2);
$text3=flt_tags($text3);
$fd=fopen("data.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);
...
Évidemment, si nous soumettons l'URL "post.php?text1=testhaha&text2=testhaha&text3=testhaha". Les données seront écrites normalement dans le fichier. Ce programme ne détecte pas la source des variables et comment le navigateur a obtenu la page. Si nous soumettons plusieurs soumissions sur cette page, cela provoquera une inondation. Il existe également des logiciels qui profitent de cette vulnérabilité pour poster des publicités sur des forums ou des livres d'or, ce qui est un comportement honteux (le livre d'or de mon ami a été inondé de plus de 10 pages en une semaine, ce qui était impuissant).
2. Résolution de vulnérabilité :
Avant de traiter et d'enregistrer des données, déterminez d'abord comment le navigateur obtient la page. Utilisez la variable $_SERVER["REQUEST_METHOD"] pour obtenir la méthode du navigateur pour obtenir la page. Vérifiez s'il s'agit de "POST". Utilisez la session dans le script pour enregistrer si l'utilisateur soumet des données via les canaux normaux (c'est-à-dire la page où le contenu de la soumission est rempli). Ou utilisez $_SERVER["HTTP_REFERER"] pour détecter cela, mais ce n'est pas recommandé. Étant donné que certains navigateurs ne configurent pas REFERER, certains pare-feu bloquent également REFERER. De plus, nous devons également vérifier le contenu soumis pour voir s'il y a du contenu en double dans la base de données. Prenez le livre d'or comme exemple, utilisez Session pour prendre la décision :
Dans la page où vous renseignez le contenu de navigation, on ajoute en front end :
$_SESSION["allowgbookpost"]=time(); //L'heure à laquelle l'inscription est remplie. Dans la page où les données du message sont acceptées et enregistrées, nous utilisons également Session pour effectuer le traitement suivant avant le traitement des données :
if(strtoupper($_SERVER["REQUEST_METHOD"])!="POST"){ die("Erreur : Ne pas soumettre en externe." } //Vérifiez si la méthode d'acquisition de page est POST
if(!isset($_SESSION["allowgbookpost"]) or (time()-$_SESSION["allowgbookpost"] < 10)){ die("Erreur : Ne pas soumettre en externe." } //Vérifiez le message) ; Heure de remplissage
if(isset($_SESSION["gbookposttime"]) and (time()-$_SESSION["gbookposttime"] < 120)){ die("Erreur : L'intervalle entre deux soumissions de messages ne doit pas être inférieur à 2 minutes. "); } // Vérifiez l'intervalle de message
non défini ($_SESSION ["allowgbookpost"]); // Désenregistrez la variableallowgbookpost pour empêcher plusieurs soumissions d'entrer dans la page de remplissage en même temps
$_SESSION["gbookposttime"]=time(); //Enregistre l'heure d'envoi des messages pour éviter le spam ou les attaques malveillantes
...
Traitement et stockage des données
...
Après ces multiples révisions, votre programme sera beaucoup plus sûr.