Aller au contenu principal

Contrôles d'accès défaillants

Principe de l'attaque

Les contrôles d'accès sont des mécanismes qui limitent l'accès à une ressource dans un système informatique. Lorsque ces contrôles sont défaillants, un attaquant peut accéder à des informations sensibles ou effectuer des actions sans avoir les autorisations appropriées.

Un exemple courant de ce type d'attaque est le "privilège escalation" où un utilisateur avec des privilèges limités arrive à obtenir des privilèges plus élevés, comme ceux d'un administrateur.

Une application Web vulnérable

Code source de la version vulnérable

Voici un exemple simple d'une application Web vulnérable écrite en PHP :

<?php
session_start();
if (isset($_GET['admin'])) {
$_SESSION['admin'] = $_GET['admin'];
}

if ($_SESSION['admin'] == 1) {
echo "Bienvenue, administrateur!";
} else {
echo "Vous n'êtes pas autorisé à accéder à cette page.";
}
?>

Dans ce code, l'application vérifie si un paramètre admin est passé dans l'URL. Si c'est le cas, il est stocké dans la session de l'utilisateur. Ensuite, l'application vérifie si la valeur de admin dans la session est égale à 1 pour déterminer si l'utilisateur est un administrateur.

Déroulement de la démo (attaque possible)

Un attaquant pourrait facilement exploiter cette vulnérabilité en ajoutant simplement ?admin=1 à l'URL, ce qui lui donnerait des privilèges d'administrateur.

Les étapes de l'attaque

  1. L'attaquant visite l'URL http://example.com/vulnerable_page.php?admin=1.
  2. L'application enregistre la valeur 1 pour admin dans la session de l'utilisateur.
  3. L'application vérifie la valeur de admin dans la session, la trouve égale à 1, et donne donc à l'utilisateur l'accès à la page d'administration.

Correction de la vulnérabilité

Code source de la version corrigée

Pour créer la base de données

Voici un exemple de fichier SQL pour créer la base de données avec une table users :

CREATE DATABASE IF NOT EXISTS webapp;

USE webapp;

CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(255) NOT NULL
);

INSERT INTO users (username, password, role)
VALUES
('user', PASSWORD('userpassword'), 'user'),
('admin', PASSWORD('adminpassword'), 'admin');
attention

Notez que la fonction PASSWORD() de MySQL/MariaDB n'est pas aussi sécurisée que Bcrypt ou Argon2. De plus, elle est obsolète dans les versions récentes de MySQL/MariaDB. Dans un contexte réel, vous devriez utiliser une bibliothèque de hachage de mot de passe plus sécurisée et stocker le sel (une donnée utilisée lors du hachage) séparément.

Pour créer le fichier index.php :

Voici un exemple simple de l'application Web corrigée :

<?php
session_start();
if (isset($_SESSION['user_id'])) {
$user_id = $_SESSION['user_id'];
$user = getUserFromDatabase($user_id); // On suppose que cette fonction récupère les informations de l'utilisateur depuis la base de données

if ($user['role'] == 'admin') {
echo "Bienvenue, administrateur!";
} else {
echo "Vous n'êtes pas autorisé à accéder à cette page.";
}
} else {
echo "Vous devez vous connecter pour accéder à cette page.";
}
?>

Voici une implémentation très simplifiée de la fonction getUserFromDatabase() :

function getUserFromDatabase($user_id) {
// On suppose que la connexion à la base de données est déjà établie
global $db;

// Préparation de la requête SQL
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $user_id);

// Exécution de la requête
$stmt->execute();

// Récupération du résultat
$result = $stmt->get_result();
$user = $result->fetch_assoc();

return $user;
}
astuce

Dans cette fonction, nous utilisons les méthodes prepare(), bind_param(), execute() et get_result() pour prévenir les attaques d'injection SQL.

C'est une bonne pratique de sécurité à toujours respecter lorsque vous travaillez avec des bases de données.

Déroulement de la démo (attaque impossible)

Même si l'attaquant tente d'accéder à http://example.com/vulnerable_page.php?admin=1, il ne recevra pas les privilèges d'administrateur car l'application ne se fie pas à la valeur admin passée par l'URL.

Principe de la correction

La correction consiste à ne jamais faire confiance aux données fournies par l'utilisateur sans les avoir vérifiées.

Dans la version corrigée, l'application ne fait plus confiance à une valeur passée par l'URL. Au lieu de cela, elle vérifie les informations de l'utilisateur dans la base de données pour déterminer si l'utilisateur est un administrateur.

Risques liés à cette vulnérabilité

Si un attaquant parvient à exploiter une vulnérabilité de contrôle d'accès, il peut accéder à des informations sensibles, effectuer des actions non autorisées, et même prendre le contrôle total de l'application.

Code de bonne conduite

Il est crucial de toujours vérifier les permissions de l'utilisateur avant de lui donner accès à une ressource. Ne faites jamais confiance aux données fournies par l'utilisateur sans les avoir vérifiées.

Test de mémorisation/compréhension


Qu'est-ce qu'un contrôle d'accès défaillant ?


Comment un attaquant pourrait-il exploiter le code de la version vulnérable présentée dans ce cours ?


Comment la version corrigée de l'application empêche-t-elle l'attaque ?


Quels sont les risques liés à une vulnérabilité de contrôle d'accès ?


Quel est le principe de base de la correction de cette vulnérabilité ?



astuce

N'oubliez pas, la cybersécurité est un domaine en constante évolution. Restez curieux et continuez à apprendre !