Sommaire :
Introduction :
La gestion des autorisations et des accès est un aspect crucial de la sécurité des applications web. Les autorisations et les accès garantissent que les utilisateurs ne peuvent accéder qu’aux ressources qui leur sont autorisées, et que les actions qu’ils effectuent sont conformes aux règles métier. Les violations de sécurité liées à la gestion des autorisations et des accès peuvent entraîner des conséquences graves, notamment la divulgation de données sensibles ou l’exécution de transactions non autorisées. Dans cet article, nous allons examiner certaines des meilleures pratiques en matière de gestion des autorisations et des accès, en nous basant sur une liste de points essentiels à prendre en compte.
Les bonnes pratiques
Pratiques recommandées pour la gestion des autorisations et des accès :
- Utilisez uniquement des objets de session côté serveur pour prendre des décisions d’autorisation.
La gestion des sessions est un élément clé de la sécurité des applications web. Les sessions côté serveur offrent une protection supplémentaire contre les attaques telles que les attaques par injection de session et les attaques par détournement de session.
- Appliquez des contrôles d’autorisation sur chaque requête, y compris les scripts et les inclusions côté serveur.
Il est important d’appliquer des contrôles d’autorisation sur chaque requête, y compris les scripts et les inclusions côté serveur, afin de garantir que les utilisateurs ne peuvent accéder qu’aux ressources qui leur sont autorisées.
- Assurez-vous que tous les répertoires, fichiers ou autres ressources en dehors du contrôle direct de l’application ont des contrôles d’accès appropriés en place.
Il est important de s’assurer que tous les répertoires, fichiers ou autres ressources en dehors du contrôle direct de l’application ont des contrôles d’accès appropriés en place. Cela peut inclure l’utilisation de permissions de fichier et de répertoire, ainsi que l’utilisation de pare-feux pour protéger les ressources.
- Si les données d’état doivent être stockées sur le client, utilisez le chiffrement et la vérification d’intégrité côté serveur pour détecter les manipulations d’état.
Si les données d’état doivent être stockées sur le client, il est important d’utiliser le chiffrement et la vérification d’intégrité côté serveur pour détecter les manipulations d’état. L’application doit également enregistrer tous les événements de manipulation apparents.
- Appliquez les flux de logique de l’application pour se conformer aux règles métier.
Les flux de logique de l’application doivent être appliqués pour se conformer aux règles métier. Cela garantit que les utilisateurs ne peuvent pas effectuer d’actions non autorisées.
- Utilisez un composant unique pour vérifier l’autorisation d’accès sur l’ensemble du site.
Il est important d’utiliser un composant unique pour vérifier l’autorisation d’accès sur l’ensemble du site. Cela garantit que les utilisateurs ne peuvent pas accéder à des ressources qu’ils ne sont pas autorisés à utiliser.
- Séparez la logique privilégiée du reste du code de l’application.
La logique privilégiée doit être séparée
du reste du code de l’application. Cela garantit que les utilisateurs ne peuvent pas accéder à des fonctions ou à des données qui leur sont interdites.
- Limitez le nombre de transactions qu’un utilisateur ou un appareil peut effectuer pendant une période donnée.
Il est important de limiter le nombre de transactions qu’un utilisateur ou un appareil peut effectuer pendant une période donnée. Cela peut aider à dissuader les attaques automatisées.
- Utilisez l’en-tête referer comme vérification supplémentaire uniquement, il ne doit jamais être la seule vérification d’autorisation, car il peut être falsifié.
L’en-tête referer peut être utilisé comme vérification supplémentaire, mais il ne doit jamais être la seule vérification d’autorisation. Il peut être falsifié et ne doit pas être considéré comme fiable à 100%.
- Créez une politique de contrôle d’accès pour documenter les règles métier et les critères et/ou processus d’autorisation d’accès à un actif.
Il est important de créer une politique de contrôle d’accès pour documenter les règles métier et les critères et/ou processus d’autorisation d’accès à un actif. Cela peut aider à garantir que l’accès est correctement provisionné et contrôlé.
- Si des sessions longues authentifiées sont autorisées, révisez périodiquement l’autorisation d’un utilisateur pour vérifier que ses privilèges n’ont pas changé.
Si des sessions longues authentifiées sont autorisées, il est important de réviser périodiquement l’autorisation d’un utilisateur pour vérifier que ses privilèges n’ont pas changé. Cela peut aider à éviter les accès non autorisés.
- Mettez en place une audit de compte et désactivez les comptes inutilisés (après un maximum de 30 jours à compter de l’expiration du mot de passe du compte).
Il est important de mettre en place une audit de compte et de désactiver les comptes inutilisés (après un maximum de 30 jours à compter de l’expiration du mot de passe du compte). Cela peut aider à éviter les accès non autorisés.
- L’application doit prendre en charge la désactivation des comptes et la fin des sessions lorsque l’autorisation cesse (causes incluant les changements de rôle, de statut d’emploi, de processus métier, etc.).
Il est important que l’application prenne en charge la désactivation des comptes et la fin des sessions lorsque l’autorisation cesse. Cela peut aider à éviter les accès non autorisés.
- Isoler les environnements de développement du réseau de production et n’accorder l’accès qu’aux groupes de développement et de test autorisés.
Il est important d’isoler les environnements de développement du réseau de production et de n’accorder l’accès qu’aux groupes de développement et de test autorisés. Cela peut aider à éviter les attaques qui exploitent les faiblesses des environnements de développement moins sécurisés.
Exemple de code :
<?php
// Connexion à la base de données
mysql_connect("localhost", "utilisateur", "motdepasse") or die(mysql_error());
mysql_select_db("ma_base_de_donnees") or die(mysql_error());
// Vérification de l'identité de l'utilisateur
if (!isset($_SESSION['id_utilisateur'])) {
header("Location: login.php");
exit();
}
// Récupération des informations de l'utilisateur
$resultat = mysql_query("SELECT * FROM utilisateurs WHERE id=".$_SESSION['id_utilisateur']) or die(mysql_error());
$utilisateur = mysql_fetch_assoc($resultat);
// Vérification de l'autorisation d'accès
if ($utilisateur['role'] != "administrateur") {
header("Location: index.php");
exit();
}
// Affichage de la page réservée aux administrateurs
echo "Bienvenue, administrateur !";
?>
Quel est le problème avec ce code?
- La connexion à la base de données utilise des fonctions obsolètes de MySQL qui ne sont plus recommandées.
- Les identifiants de connexion à la base de données sont stockés en clair dans le code source.
- Il n’y a pas de contrôle d’autorisation sur chaque requête, mais seulement une vérification après la récupération des informations de l’utilisateur.
- L’utilisation de la fonction mysql_fetch_assoc() peut entraîner des attaques par injection SQL.
- Les identifiants de session sont stockés dans un tableau global qui peut être manipulé par un utilisateur malveillant.
- Les contrôles d’accès ne sont pas séparés du reste du code de l’application.
- Il n’y a pas de limitation du nombre de transactions par période donnée.
- Il n’y a pas d’utilisation de l’en-tête referer pour une vérification supplémentaire d’autorisation.
- Il n’y a pas de politique de contrôle d’accès documentée.
- Il n’y a pas de validation périodique de l’autorisation d’un utilisateur pour vérifier si ses privilèges ont changé.
- Il n’y a pas d’audit de compte pour désactiver les comptes inutilisés.
Comment résoudre ces problèmes?
<?php
// Connexion à la base de données avec PDO
$dsn = 'mysql:host=localhost;dbname=ma_base_de_donnees';
$username = 'utilisateur';
$password = 'motdepasse';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$connexion = new PDO($dsn, $username, $password, $options);
// Vérification de l'identité de l'utilisateur
session_start();
if (!isset($_SESSION['id_utilisateur'])) {
header("Location: login.php");
exit();
}
// Récupération des informations de l'utilisateur avec une requête préparée
$sql = "SELECT * FROM utilisateurs WHERE id=:id";
$stmt = $connexion->prepare($sql);
$stmt->bindValue(':id', $_SESSION['id_utilisateur'], PDO::PARAM_INT);
$stmt->execute();
$utilisateur = $stmt->fetch(PDO::FETCH_ASSOC);
// Vérification de l'autorisation d'accès
if ($utilisateur['role'] != "administrateur") {
header("Location: index.php");
exit();
}
// Séparation de la logique privilégiée du reste du code de l'application
require_once 'admin.php';
// Limitation du nombre de transactions par période donnée
if (!isset($_SESSION['last_transaction'])) {
$_SESSION['last_transaction'] = time();
} else {
$time_since_last_transaction = time() - $_SESSION['last_transaction'];
if ($time_since_last_transaction < 5) { // 5 secondes de délai minimum entre chaque transaction
header("HTTP/1.1 429 Too Many Requests");
exit();
}
$_SESSION['last_transaction'] = time();
}
// Vérification de l'en-tête referer comme vérification supplémentaire
$referer = $_SERVER['HTTP_REFERER'];
if (!empty($referer)) {
$allowed_referers = array(
'https://www.mon-site.com',
'https://admin.mon-site.com',
);
$referer_domain = parse_url($referer, PHP_URL_HOST);
if (!in_array($referer_domain, $allowed_referers)) {
header("HTTP/1.1 403 Forbidden");
exit();
}
}
// Politique de contrôle d'accès documentée
// Les règles d'accès sont documentées dans un document Access Control Policy (ACP)
// accessible sur le site de l'entreprise à l'adresse suivante : http://mon-site.com/acp/
// Validation périodique de l'autorisation d'un utilisateur pour vérifier si ses privilèges ont changé
if (isset($_SESSION['last_auth_check'])) {
$time_since_last_auth_check = time() - $_SESSION['last_auth_check'];
if ($time_since_last_auth_check > 3600) { // Validation toutes les heures
$sql = "SELECT role FROM utilisateurs WHERE id=:id";
$stmt = $connexion->prepare($sql);
$stmt->bindValue(':id', $_SESSION['id_utilisateur'], PDO::PARAM_INT);
$stmt->execute();
$utilisateur_role = $stmt->fetchColumn();
if ($utilisateur_role != $utilisateur['role']) {
session_destroy();
header("Location: login.php");
exit();
}
$_SESSION['last_auth_check'] = time();
}
} else {
$_SESSION['last_auth_check'] = time();
}
// Audit de compte pour désactiver les comptes inutilisés après 30 jours
$sql = "UPDATE utilisateurs SET active=0 WHERE last_login < DATE_SUB(NOW(), INTERVAL 30 DAY)";
$connexion->exec($sql);
// Affichage de la page réservée aux administrateurs
echo "Bienvenue, administrateur !";
?>
Quels changements avons-nous apportés ?
- Utilisation de PDO pour la connexion à la base de données, une extension plus moderne et plus sécurisée que les fonctions obsolètes de MySQL.
- Stockage des identifiants de connexion à la base de données dans des variables et non en clair dans le code source.
- Contrôle de l’autorisation d’accès sur chaque requête, avant la récupération des informations de l’utilisateur.
- Utilisation de requêtes préparées pour récupérer les informations de l’utilisateur, pour éviter les attaques par injection SQL.
- Stockage des identifiants de session dans la superglobale $_SESSION, plus sécurisée que les tableaux globaux.
- Séparation de la logique privilégiée du reste du code de l’application, pour une meilleure sécurité.
- Limitation du nombre de transactions par période donnée pour éviter les attaques automatisées.
- Utilisation de l’en-tête referer comme vérification supplémentaire uniquement pour éviter les attaques de type CSRF.
- Documentation d’une politique de contrôle d’accès (ACP) accessible sur le site de l’entreprise.
- Validation périodique de l’autorisation d’un utilisateur pour vérifier si ses privilèges ont changé.
- Audit de compte pour désactiver les comptes inutilisés après 30 jours.
Conclusion :
La gestion des autorisations et des accès est un aspect crucial de la sécurité des applications web. Les pratiques recommandées comprennent l’utilisation de sessions côté serveur, l’application de contrôles d’autorisation sur chaque requête, la mise en place de contrôles d’accès appropriés pour toutes les ressources en dehors du contrôle direct de l’application, la séparation de la logique privilégiée du reste du code de l’application, la limitation du nombre de transactions par période donnée, la création d’une politique de contrôle d’accès et la mise en place d’une audit de compte pour désactiver les comptes inutilisés. En suivant ces pratiques recommandées, les développeurs peuvent améliorer considérablement la sécurité de leurs applications web et éviter les conséquences potentiellement graves des violations de sécurité liées à la gestion des autorisations et des accès.