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.

EGPNL crée l'utilisateur avec les bons droits quand vous créez une base : cette page compte donc surtout sur un VPS que vous administrez vous-même.