Compte Rendu TP Sécurité

PROSPER MATHIEU - MMI2-B2

Préparation de l'environnement

Objectifs : Rendre le script EssaiSecurite.php compatible avec le serveur actuel et préparer la base de données de test.

Approche : Création de la table utilisateurs via SQL, insertion de données factices, et remplacement des fonctions obsolètes mysql_* par mysqli_* dans le code PHP.

1. Structure SQL

CREATE TABLE IF NOT EXISTS utilisateurs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    login VARCHAR(50),
    password VARCHAR(50)
);

INSERT INTO utilisateurs (login, password) VALUES ('admin', 'admin');
INSERT INTO utilisateurs (login, password) VALUES ('toto', 'toto');

2. Code de connexion (PHP)

function valid() {
    // Connexion mise à jour vers MySQLi
    $link = mysqli_connect("localhost", "mathieuprosper_Admin", "x_Sz6VY_u[N%", "mathieuprosper_login");
    // ...
}

Résultat

Capture phpMyAdmin

Exercice 1 : Injection SQL

Objectifs : Exploiter puis corriger une faille d'injection SQL permettant de contourner l'authentification.

Approche : Injection d'une condition tautologique (OR 1=1) dans le champ mot de passe pour forcer la validation de la requête. Correction via l'échappement des caractères.
Test d'exploitation : Saisie du login admin et du mot de passe ' OR 1=1 --.
Résultat : Connexion réussie sans le mot de passe.

Code Corrigé

$log = mysqli_real_escape_string($link, $_POST['nom']);
$password = mysqli_real_escape_string($link, $_POST['pass']);
$sql = "SELECT * FROM utilisateurs WHERE login='$log' AND password='$password'";
Fonctionnement : L'attaque fonctionne car le moteur SQL interprète l'apostrophe injectée comme la fin de la chaîne de caractères et le OR 1=1 comme une condition logique toujours vraie (tautologie).

La fonction mysqli_real_escape_string() corrige cela en "échappant" les caractères spéciaux (ajout d'antislashs \'). Le SGBD traite alors l'entrée de l'utilisateur strictement comme une donnée textuelle (un littéral) et non comme une instruction SQL exécutable, neutralisant ainsi l'injection.

Exercice 2 : Faille XSS

Objectifs : Démontrer l'exécution de code JavaScript arbitraire et sécuriser l'affichage.

Approche : Injection d'une balise <script> dans le formulaire. Correction par encodage des entités HTML à l'affichage.
Test d'exploitation : Saisie de <script>document.title='this site sucks';</script> dans le champ nom.
Résultat : Le titre de la page change, prouvant l'exécution du code JS.

Code Corrigé

echo "identification erronée, monsieur " . htmlentities($_POST["nom"]);
Fonctionnement : La faille provient du fait que le serveur répercute l'entrée utilisateur directement dans le code source HTML (DOM). Le navigateur ne pouvant distinguer le code légitime du code injecté, il exécute le JavaScript.

La solution consiste à utiliser htmlentities() lors de l'affichage. Cette fonction convertit les métacaractères HTML (comme < et >) en entités (&lt;, &gt;). Le navigateur affiche alors les balises visuellement comme du texte brut au lieu de les interpréter comme du code exécutable.

Résultat

Capture d'écran faille XSS

Exercice 3 : Faille CSRF

Objectifs : Empêcher l'exécution d'actions sensibles (vote) via des requêtes forgées depuis un site tiers.

Approche : Utilisation d'un jeton (token) unique et aléatoire lié à la session utilisateur pour vérifier l'origine de la requête.
Test d'exploitation : Appel de l'URL https://mathieu.prosper.mmi-velizy.fr/MMI2/BEN_AMOR/TD-securite/EssaiSecurite.php?choix=1 via une balise image cachée.
Résultat : Le vote est pris en compte automatiquement.

Code Corrigé

// Génération du token
$token = time(); 
$_SESSION['token'] = $token;
// ... (Code HTML du champ hidden) ...

// Vérification du token
if (isset($_GET['token']) && $_GET['token'] == $_SESSION['token']) {
    // Validation du vote
}
Fonctionnement : L'attaque exploite le fait que le navigateur envoie automatiquement les cookies de session, même pour des requêtes initiées par un site tiers (Cross-Site). Le serveur pense donc que l'action est légitime.

La protection repose sur un secret partagé (le Token) généré côté serveur et stocké en session. Comme l'attaquant ne peut pas lire la session de l'utilisateur (Same-Origin Policy), il ne peut pas inclure le bon token dans sa fausse requête. Le serveur rejette donc l'action si le token est absent ou invalide.

Résultat

Capture vote.txt modifié

Exercice 4 : Register Globals

Objectifs : Comprendre et contrer l'écrasement de variables via l'URL (faille simulée ici avec extract).

Approche : Initialisation stricte des variables en se basant uniquement sur le tableau $_SESSION.
Test d'exploitation : Ajout du paramètre ?login=1 dans l'URL.
Résultat : Accès à la zone sécurisée sans authentification.

Code Corrigé

$login = isset($_SESSION['login']) ? $_SESSION['login'] : null;

if (!isset($login)) { 
    // Redirection vers le formulaire
}
Fonctionnement : Lorsque register_globals était activé (ou simulé via extract($_REQUEST)), PHP transformait automatiquement les paramètres d'URL en variables globales. Cela permettait d'injecter la variable $login de l'extérieur pour tromper la condition if(!isset($login)).

Le correctif consiste à ne jamais faire confiance aux variables globales implicites. En initialisant explicitement $login à partir de $_SESSION (source de confiance), on rend impossible l'écrasement de la variable d'authentification par une entrée utilisateur via GET ou POST.

Exercice 5 : Faille RFI

Objectifs : Empêcher l'inclusion de fichiers arbitraires via l'URL.

Approche : Mise en place d'une "Liste Blanche" (Whitelist) des fichiers autorisés.
Test d'exploitation : URL ?page=hack avec un fichier hack.php local.
Résultat : Le code malveillant est exécuté.

Code Corrigé

$whitelist = array('conf', 'accueil');
$page = isset($_GET['page']) ? $_GET['page'] : 'conf';

if (in_array($page, $whitelist)) {
    include($page . ".php");
} else {
    include("conf.php");
}
Fonctionnement : La vulnérabilité initiale (LFI/RFI) provenait de l'utilisation directe de l'entrée utilisateur dans la fonction include(), permettant au serveur d'exécuter n'importe quel fichier.

La solution par "Whitelist" inverse la logique de sécurité : au lieu de tenter de bloquer les entrées malveillantes, on définit explicitement la liste des seuls fichiers autorisés. La fonction in_array() vérifie si la page demandée est valide. Si ce n'est pas le cas, le script force le chargement d'une page par défaut sécurisée, rendant l'inclusion arbitraire impossible.