Drupal — durcissement complet de la configuration et des permissions
Référence de durcissement pour Drupal 10/11 : permissions de fichiers, settings.php, rôles, exposition réduite et vérification de l'état de sécurité.
Procédure de durcissement d’une instance Drupal 10/11 portant sur les permissions système, la configuration applicative et la réduction de la surface d’exposition.
Contexte
Drupal expose par défaut plusieurs vecteurs : fichiers de configuration lisibles, modules d’administration accessibles, permissions de rôles trop larges et endpoints de service (/jsonapi, /rest) actifs. Le durcissement vise à réduire ces vecteurs sans altérer le fonctionnement applicatif.
Détection
Inventaire des permissions de fichiers anormales (fichiers de code modifiables par le serveur web) :
find /var/www/drupal.exemple.fr/web -type f -name '*.php' -perm -o=w
find /var/www/drupal.exemple.fr/web/sites -type f -name 'settings.php' -perm -g=w -o -perm -o=r
Audit des permissions de rôles accordant des accès critiques :
drush role:list --format=json
drush eval 'foreach (\Drupal\user\Entity\Role::loadMultiple() as $r) { if ($r->hasPermission("administer modules") || $r->hasPermission("administer permissions") || $r->hasPermission("administer users")) print $r->id()."\n"; }'
Identification des comptes avec rôle administrateur :
drush sql:query "SELECT u.uid, u.name FROM users_field_data u INNER JOIN user__roles r ON u.uid = r.entity_id WHERE r.roles_target_id = 'administrator';"
Durcissement
Permissions de fichiers conformes (code en lecture seule pour le serveur web, répertoire files isolé) :
chown -R deploy:www-data /var/www/drupal.exemple.fr/web
find /var/www/drupal.exemple.fr/web -type d -exec chmod 750 {} \;
find /var/www/drupal.exemple.fr/web -type f -exec chmod 640 {} \;
chmod 440 /var/www/drupal.exemple.fr/web/sites/default/settings.php
chmod -R 770 /var/www/drupal.exemple.fr/web/sites/default/files
Verrouillage de settings.php (lecture seule des fichiers de config, désactivation de l’interface d’installation, salage du hash) :
$settings['file_scan_ignore_directories'] = ['node_modules', 'bower_components'];
$settings['update_free_access'] = FALSE;
$settings['allow_authorize_operations'] = FALSE;
$config['system.file']['allow_insecure_uploads'] = FALSE;
$settings['trusted_host_patterns'] = ['^drupal\.exemple\.fr$'];
$settings['config_sync_directory'] = '../config/sync';
$settings['hash_salt'] = file_get_contents('/etc/drupal/hash_salt.key');
Le hash_salt doit résider hors de l’arborescence web :
install -o root -g www-data -m 0440 <(openssl rand -base64 55) /etc/drupal/hash_salt.key
Désactivation des services exposés inutilisés et du module dblog au profit de syslog :
drush pm:uninstall jsonapi rest dblog -y
drush pm:enable syslog -y
drush config:set system.logging error_level hide -y
Refus d’accès aux fichiers sensibles côté serveur (Nginx) :
location ~* \.(engine|inc|install|module|profile|po|sh|sql|theme|twig|tpl(\.php)?|xtmpl|yml)$ {
deny all;
return 404;
}
location ~ (^|/)\. { return 403; }
location ~ ^/sites/.*/private/ { return 403; }
location ~ ^/sites/[^/]+/files/.*\.php$ { deny all; }
Principe de moindre privilège sur les rôles : retrait des permissions administer * du rôle d’édition de contenu et limitation du rôle administrateur à un ou deux comptes nominatifs. Désactivation de la création de comptes en libre accès :
drush config:set user.settings register admin_only -y
Vérification
Confirmation qu’aucun fichier de code n’est modifiable par le serveur web et que settings.php est protégé :
sudo -u www-data test -w /var/www/drupal.exemple.fr/web/index.php && echo "VULNERABLE" || echo "OK"
stat -c '%a %U %G' /var/www/drupal.exemple.fr/web/sites/default/settings.php
Vérification que les endpoints sensibles renvoient 403/404 :
curl -s -o /dev/null -w '%{http_code}\n' https://drupal.exemple.fr/sites/default/settings.php
curl -s -o /dev/null -w '%{http_code}\n' https://drupal.exemple.fr/core/install.php
Le tableau de bord /admin/reports/status ne doit signaler aucune alerte rouge sur les permissions de fichiers ni sur la version de PHP.
Vous avez un projet sur ces sujets ?
Nous contacter →