Un site dont l'utilisateur de base peut supprimer des tables et lire toutes les autres bases est à une injection SQL de tout perdre sur le serveur. Le remède ne coûte rien : donnez à chaque site son propre utilisateur, avec des droits sur sa seule base.
Un utilisateur pour une base
CREATE USER 'site_shop'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'site_shop'@'localhost';
FLUSH PRIVILEGES;
Ces quatre verbes sont ce dont une application en marche a besoin. Notez ce qui manque : DROP, ALTER, CREATE, et tout ce qui porte sur *.*.
Ce qu'un installeur demande, brièvement
Un installeur ou une migration a bel et bien besoin de créer et de modifier des tables. Accordez-le le temps de l'installation et reprenez-le ensuite : un droit qu'on ne détient que pendant qu'on s'en sert ne peut pas être détourné quand on ne s'en sert pas.
GRANT CREATE, ALTER, INDEX, DROP ON shop.* TO 'site_shop'@'localhost';
-- after the install
REVOKE CREATE, ALTER, INDEX, DROP ON shop.* FROM 'site_shop'@'localhost';
Jamais ceux-ci
GRANT ALL ON *.* donne à un site la lecture et l'écriture sur toutes les autres bases du serveur, plus le droit de créer des utilisateurs. C'est le réglage par défaut dans beaucoup trop de tutoriels.- FILE - lit et écrit des fichiers sur le serveur sous l'identité de l'utilisateur de base.
- SUPER - change les réglages globaux et tue les sessions des autres.
- GRANT OPTION - laisse l'utilisateur distribuer des droits, y compris à lui-même.
Vérifier ce que vous avez déjà donné
SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'site_shop'@'localhost';
La partie hôte, c'est la moitié de la sécurité
'user'@'localhost' ne peut se connecter que depuis la machine elle-même. 'user'@'%' peut se connecter depuis n'importe où sur internet, et il ne reste alors qu'un mot de passe en travers du chemin.
