Un sito il cui utente di database può cancellare tabelle e leggere ogni altro database dista una sola SQL injection dal perdere tutto quel che sta sul server. Il rimedio non costa nulla: dia a ogni sito un utente proprio, con diritti solo sul proprio database.

Un utente per un database

CREATE USER 'site_shop'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'site_shop'@'localhost';
FLUSH PRIVILEGES;

Questi quattro verbi sono ciò che serve a un'applicazione in funzione. Noti che cosa manca: DROP, ALTER, CREATE e qualsiasi cosa su *.*.

Ciò che a un installatore serve, per poco

Un installatore o una migrazione hanno davvero bisogno di creare e modificare tabelle. Lo conceda per l'installazione e se lo riprenda dopo: un permesso tenuto solo finché lo si usa non può essere abusato quando non lo si usa.

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';

Questi mai

GRANT ALL ON *.* dà a un sito lettura e scrittura su ogni altro database del server, più il diritto di creare utenti. In troppe guide è l'impostazione predefinita.
  • FILE - legge e scrive file sul server con l'identità dell'utente di database.
  • SUPER - cambia le impostazioni globali e chiude le sessioni altrui.
  • GRANT OPTION - lascia che l'utente distribuisca diritti, anche a se stesso.

Controlli che cosa ha già dato

SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'site_shop'@'localhost';

La parte host è metà della sicurezza

'user'@'localhost' può collegarsi soltanto dalla macchina stessa. 'user'@'%' può collegarsi da qualunque punto di internet, e allora l'unica cosa di mezzo è una password.

EGPNL crea l'utente con i permessi giusti quando lei crea un database, perciò questa pagina conta soprattutto su un VPS che amministra da sé.