OWASP (Open Web Application Security Project) publie le Top 10 des vulnérabilités web les plus critiques. Connaître et corriger ces failles est le minimum vital pour tout site web professionnel. Voici les principales menaces et comment s'en protéger en PHP.
1. Injection SQL : la faille la plus dévastatrice
L'injection SQL permet à un attaquant d'exécuter des requêtes SQL arbitraires via les entrées utilisateur. La protection est simple : utilisez toujours les requêtes préparées.
// VULNERABLE
$query = "SELECT * FROM users WHERE email = '{$_POST['email']}'";
// SECURE : requête préparée
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST['email']]);
2. XSS (Cross-Site Scripting)
Le XSS injecte du JavaScript malveillant dans les pages vues par d'autres utilisateurs. Protection : échappez toujours les sorties.
// Dans les templates Twig : {{ variable }} est auto-échappé
// En PHP natif :
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// Content Security Policy header
header("Content-Security-Policy: default-src 'self'; script-src 'self'");
3. CSRF (Cross-Site Request Forgery)
Le CSRF force un utilisateur authentifié à exécuter des actions non désirées. Protection : tokens CSRF sur chaque formulaire.
// Générer le token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
// Dans le formulaire
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
// Vérifier à la réception
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die('Requête invalide');
}
4. Upload de fichiers non sécurisé
Un upload mal configuré permet d'exécuter du code PHP sur votre serveur.
function secureUpload(array $file): string {
$allowedTypes = ['image/jpeg', 'image/png', 'image/webp'];
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($file['tmp_name']);
if (!in_array($mimeType, $allowedTypes)) {
throw new Exception('Type de fichier non autorisé');
}
// Renommer avec extension forcée, stocker hors de la racine web
$ext = match($mimeType) { 'image/jpeg' => 'jpg', 'image/png' => 'png', default => 'webp' };
$filename = bin2hex(random_bytes(16)) . '.' . $ext;
move_uploaded_file($file['tmp_name'], '/var/uploads/' . $filename);
return $filename;
}
5. Authentification défaillante
Mots de passe faibles, stockage non hashé, sessions non invalidées. Solutions :
// Hasher les mots de passe
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// Vérifier
if (password_verify($inputPassword, $hash)) { /* OK */ }
// Sessions sécurisées
session_start();
session_regenerate_id(true); // Après connexion
6. Exposition de données sensibles
Ne jamais stocker de mots de passe en clair, journaliser des données sensibles, ou retourner des stack traces en production.
// Masquer les erreurs en production
ini_set('display_errors', '0');
ini_set('log_errors', '1');
error_reporting(E_ALL);
7. Headers de sécurité HTTP
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
Vérifiez votre configuration sur securityheaders.com qui attribue une note A-F.
Conclusion
La sécurité web n'est pas optionnelle. Les failles owasp sont connues, documentées et exploitées automatiquement par des bots. Utiliser des requêtes préparées, échapper les sorties, ajouter des tokens CSRF et configurer correctement les headers HTTP protège votre site des 95% des attaques automatisées. Formez-vous régulièrement sur les nouvelles menaces via le site officiel OWASP.
La sécurité web est une course aux armements permanente. Au-delà de l'OWASP Top 10, intégrez la sécurité dans le cycle de développement avec le SAST via SonarQube ou Semgrep, et le DAST avec OWASP ZAP en CI/CD. Le principe de moindre privilège s'applique à tous les niveaux : comptes de base de données, permissions fichiers, tokens API avec scopes limités. Activez les security headers HTTP (CSP, HSTS, X-Frame-Options) et scannez vos dépendances avec npm audit ou Snyk régulièrement. Pratiquez avec les challenges HackTheBox ou OWASP WebGoat pour développer des réflexes de sécurité solides au quotidien.
Sécurité en profondeur
La sécurité web efficace suit le principe de défense en profondeur : chaque couche (réseau, serveur, application, données) doit avoir ses propres contrôles de sécurité. Un seul outil ou une seule mesure ne suffit jamais. Mettez en place une politique de divulgation responsable (bug bounty ou security.txt) pour encourager les chercheurs en sécurité à vous signaler les vulnérabilités de manière éthique avant qu'elles ne soient exploitées.