Jump to content

Sécuriser une page web avec PHP

From DevNotes

Sécuriser une page web en PHP ne dépend pas d'une seule formule magique, mais plutôt d'une superposition de bonnes pratiques. C'est ce qu'on appelle la défense en profondeur.

Voici un guide des piliers essentiels pour verrouiller votre page et protéger vos utilisateurs.

1. Protéger l'accès à la page (Authentification et Sessions)

[edit | edit source]

Si votre page contient des données sensibles, vous devez vérifier que l'utilisateur est connecté et qu'il a le droit d'être là.

  • Utilisez des sessions sécurisées : Avant de stocker quoi que ce soit dans $_SESSION, configurez les cookies de session pour qu'ils ne soient pas interceptables.
  • Vérifiez le statut à chaque chargement :
    <?php
    
    // À mettre tout en haut de votre fichier PHP, avant le moindre espace ou code HTML
    ini_set('session.cookie_httponly', 1); // Empêche le vol de cookie via JavaScript
    ini_set('session.cookie_secure', 1);   // Force le passage par HTTPS
    ini_set('session.use_only_cookies', 1);
    session_start();
    
    // Vérification si l'utilisateur est connecté
    if (!isset($_SESSION['user_logged_in']) || $_SESSION['user_logged_in'] !== true) {
        // Redirection immédiate vers la page de connexion
        header('Location: login.php');
        exit; // Crucial pour stopper l'exécution du reste de la page
    }
    
    ?>
    

2. Bloquer les injections SQL (Sécurité de la base de données)

[edit | edit source]

C'est l'une des failles les plus courantes. Ne concaténez jamais les variables de l'utilisateur directement dans vos requêtes SQL (ex: "SELECT * FROM users WHERE id = " . $_GET['id']).

La solution : Utilisez des requêtes préparées avec PDO ou MySQLi. Les données et la structure de la requête sont séparées, rendant l'injection impossible.

// Exemple avec PDO
$stmt = $pdo->prepare('SELECT * FROM articles WHERE id = :id AND statut = :statut');
$stmt->execute([
    'id' => $_GET['id'],
    'statut' => 'publie'
]);
$article = $stmt->fetch();

3. Éviter les failles XSS (Cross-Site Scripting)

[edit | edit source]

La faille XSS survient lorsque vous affichez une donnée fournie par un utilisateur (un commentaire, un nom, etc.) sans la nettoyer. Un pirate pourrait y injecter du code JavaScript malveillant qui s'exécutera chez les autres visiteurs.

  • La règle d'or : Filtrer à l'entrée, échapper à la sortie.
  • La solution : Utilisez htmlspecialchars() à chaque fois que vous affichez une variable dynamique dans votre HTML.
    <!-- Mauvais et dangereux -->
    <p>Bienvenue, <?php echo $_GET['name']; ?></p>
    
    <!-- Bon et sécurisé -->
    <p>Bienvenue, <?php echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8'); ?></p>
    

4. Valider et filtrer les entrées ($_POST, $_GET)

[edit | edit source]

Ne faites jamais confiance aux données qui viennent du navigateur. Même un menu déroulant ou une case à cocher peut être modifié par un utilisateur malveillant avant l'envoi.

Utilisez les fonctions de filtrage de PHP (filter_var) pour valider les emails, les entiers, ou les URL.

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if (!$email) {
    // L'email n'est pas valide, on rejette l'action
}

5. Se protéger des failles CSRF (Cross-Site Request Forgery)

[edit | edit source]

La faille CSRF consiste à piéger un utilisateur connecté pour lui faire exécuter une action à son insu (par exemple, modifier son mot de passe via un lien caché sur un autre site).

La solution : Générer un jeton unique (token CSRF) stocké en session, l'inclure dans vos formulaires, et le vérifier à la réception.

<?php

// 1. Génération du token (à l'affichage du formulaire)
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

?>

// 2. Dans le formulaire HTML
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">

<?php

// 3. À la réception du POST
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    die("Action non autorisée (Échec CSRF)");
}

?>

6. Bonnes pratiques serveurs et PHP

[edit | edit source]

La sécurité de votre page dépend aussi de la configuration de votre environnement :

  • Passez en HTTPS : C'est obligatoire pour chiffrer les échanges entre le visiteur et votre serveur (indispensable pour les mots de passe et cookies).
  • Masquez les erreurs en production : PHP ne doit jamais afficher les détails de ses erreurs aux utilisateurs (cela donne des indices aux pirates). Dans votre fichier php.ini en production :
    display_errors = Off
    log_errors = On
    
  • Hachez les mots de passe correctement : Si votre page gère des inscriptions, n'utilisez jamais MD5 ou SHA1. Utilisez la fonction native de PHP :
    $hash = password_hash($password_saisi, PASSWORD_DEFAULT);
    
    // Pour vérifier lors de la connexion :
    if (password_verify($password_saisi, $hash_en_bdd)) { ... }