Migliori Pratiche per Concedere e Revocare i Privilegi degli Utenti MySQL

Utilizza MySQL GRANT, REVOKE, SHOW GRANTS e DROP USER in modo sicuro con esempi di privilegio minimo per account applicativi e amministrativi.

Migliori Pratiche per Concedere e Revocare i Privilegi degli Utenti MySQL

I privilegi MySQL determinano cosa le tue applicazioni, strumenti e amministratori possono fare dopo la connessione. Un singolo account con accesso esteso può trasformare un piccolo bug o una password divulgata in un'esposizione completa del database.

Utilizza GRANT, REVOKE e SHOW GRANTS con il principio del privilegio minimo: ogni account dovrebbe avere solo i permessi di cui ha bisogno, solo dagli host che utilizza.

Comprendere i Privilegi MySQL

Prima di addentrarci in GRANT e REVOKE, è fondamentale comprendere i diversi ambiti e tipi di privilegi disponibili in MySQL. I privilegi definiscono quali azioni un utente può eseguire e su quali oggetti del database.

I privilegi MySQL possono essere categorizzati per ambito:

  • Privilegi Globali (*.*): Si applicano a tutti i database e tabelle sul server MySQL. Esempi includono SUPER, PROCESS, RELOAD, CREATE USER.
  • Privilegi di Database (nome_database.*): Si applicano a tutte le tabelle e oggetti all'interno di un database specifico. Esempi includono SELECT, INSERT, UPDATE, DELETE, CREATE, DROP.
  • Privilegi di Tabella (nome_database.nome_tabella): Si applicano a tutte le colonne all'interno di una tabella specifica. Esempi includono SELECT, INSERT, UPDATE, DELETE, ALTER.
  • Privilegi di Colonna (nome_database.nome_tabella.nome_colonna): Si applicano a colonne specifiche all'interno di una tabella. Questo è meno comune ma utile per un controllo altamente granulare.
  • Privilegi di Routine (nome_database.nome_routine): Si applicano a procedure e funzioni memorizzate, controllando EXECUTE e ALTER ROUTINE.
  • Privilegi Proxy: Permettono a un utente di agire come un altro, utile per applicazioni che gestiscono identità utente.

Alcuni privilegi specifici comuni includono:

  • SELECT: Leggere dati dalle tabelle.
  • INSERT: Aggiungere nuove righe alle tabelle.
  • UPDATE: Modificare righe esistenti nelle tabelle.
  • DELETE: Rimuovere righe dalle tabelle.
  • CREATE: Creare database, tabelle o indici.
  • DROP: Eliminare database, tabelle o indici.
  • ALTER: Modificare le strutture delle tabelle.
  • INDEX: Creare o eliminare indici.
  • REFERENCES: Stabilire vincoli di chiave esterna.
  • CREATE VIEW, SHOW VIEW: Gestire viste.
  • CREATE ROUTINE, ALTER ROUTINE, EXECUTE: Gestire ed eseguire procedure e funzioni memorizzate.
  • FILE: Leggere o scrivere file sul server host (molto potente, usare con estrema cautela).
  • GRANT OPTION: Permette a un utente di concedere i propri privilegi ad altri utenti. Questo è un privilegio molto potente e dovrebbe essere concesso con parsimonia.

Il Comando GRANT: Concedere Privilegi in Modo Sicuro

Il comando GRANT viene utilizzato per assegnare privilegi a un utente MySQL. Quando si concedono privilegi, è cruciale considerare il principio del privilegio minimo: concedere solo ciò che è assolutamente necessario.

Sintassi di Base

La sintassi generale per il comando GRANT è:

GRANT privilegi ON oggetto TO 'utente'@'host' [WITH GRANT OPTION];
  • privilegi: Un elenco separato da virgole di privilegi (es., SELECT, INSERT).
  • oggetto: Specifica l'ambito (es., *.* per globale, nome_database.*, nome_database.nome_tabella).
  • 'utente'@'host': L'account utente, inclusi il nome utente e l'host da cui può connettersi. L'host può essere un indirizzo IP, un nome host o un carattere jolly (% per qualsiasi host, localhost per connessioni locali).
  • WITH GRANT OPTION: (Opzionale) Permette all'utente di concedere i privilegi specificati ad altri utenti.

Crea o modifica le password con CREATE USER e ALTER USER. Le versioni precedenti di MySQL permettevano GRANT ... IDENTIFIED BY, ma la sintassi moderna di MySQL mantiene la creazione dell'account separata.

Esempi Pratici

Esaminiamo alcuni scenari comuni.

  1. Creare un Nuovo Utente e Concedere Accesso Globale in Sola Lettura (Fortemente Sconsigliato)

    CREATE USER 'lettore_globale'@'localhost' IDENTIFIED BY 'PasswordForte123!';
    GRANT SELECT ON *.* TO 'lettore_globale'@'localhost';
    

    Attenzione: Concedere SELECT su *.* dà accesso a tutti i database e tabelle. Questo è generalmente troppo ampio per gli utenti applicativi e dovrebbe essere evitato a meno che non sia assolutamente necessario per specifiche attività amministrative.

  2. Concedere Accesso Completo a un Database Specifico per un Utente Applicativo

    Uno scenario comune per un utente applicativo che deve gestire i dati all'interno del proprio database.

    CREATE USER 'utente_app'@'localhost' IDENTIFIED BY 'PasswordAppSicura!';
    GRANT SELECT, INSERT, UPDATE, DELETE ON `miodb_app`.* TO 'utente_app'@'localhost';
    

    Qui, utente_app può eseguire operazioni CRUD di base solo all'interno del database miodb_app, ma non creare nuove tabelle o modificare lo schema.

  3. Concedere Accesso in Sola Lettura a una Tabella Specifica

    Per uno strumento di reporting che deve solo leggere da una tabella particolare.

    CREATE USER 'strumento_report'@'%' IDENTIFIED BY 'SegretoReport!';
    GRANT SELECT ON `db_vendite`.`ordini` TO 'strumento_report'@'%';
    

    L'host '%' permette a strumento_report di connettersi da qualsiasi host, ma solo con accesso SELECT sulla tabella ordini in db_vendite.

  4. Concedere GRANT OPTION (Usare con Estrema Cautela)

    Se un amministratore deve delegare la gestione dei privilegi per un database specifico.

    CREATE USER 'admin_db'@'localhost' IDENTIFIED BY 'PasswordAdmin#456';
    GRANT ALL PRIVILEGES ON `db_inventario`.* TO 'admin_db'@'localhost' WITH GRANT OPTION;
    

    admin_db può ora concedere qualsiasi privilegio su db_inventario ad altri utenti. Questo è un privilegio potente che bypassa il controllo centrale e dovrebbe essere usato solo quando inevitabile.

Suggerimenti per Concedere Privilegi

  • Principio del Privilegio Minimo: Concedere sempre il set minimo di privilegi richiesto per il funzionamento di un utente o applicazione. Evitare ALL PRIVILEGES a meno che non sia per un account amministratore di database dedicato.
  • Host Specifici: Limitare le connessioni utente a indirizzi IP o nomi host specifici ('utente'@'192.168.1.10' o 'utente'@'serverapp.esempio.com') invece di '%' quando possibile.
  • Utenti Separati: Creare account utente separati per diverse applicazioni o servizi, anche se accedono allo stesso database. Questo isola potenziali violazioni della sicurezza.
  • Niente root per le Applicazioni: Non utilizzare mai l'account utente root per le tue applicazioni. Creare utenti dedicati con privilegi minimi.

Il Comando REVOKE: Revocare i Privilegi in Modo Efficace

Il comando REVOKE viene utilizzato per rimuovere i privilegi da un utente MySQL. È importante quanto GRANT per mantenere un ambiente di database sicuro, specialmente quando i ruoli cambiano o le applicazioni vengono dismesse.

Sintassi di Base

La sintassi generale per il comando REVOKE è:

REVOKE privilegi ON oggetto FROM 'utente'@'host';
  • privilegi: Un elenco separato da virgole di privilegi da revocare.
  • oggetto: L'ambito da cui revocare (deve corrispondere all'ambito in cui i privilegi sono stati concessi).
  • 'utente'@'host': L'account utente da cui revocare i privilegi.

Esempi Pratici

  1. Revocare il Privilegio DELETE da un Utente Applicativo

    Se un'applicazione non ha più bisogno di eliminare dati, o se si desidera ridurre i suoi permessi.

    REVOKE DELETE ON `miodb_app`.* FROM 'utente_app'@'localhost';
    

    Ora, utente_app può ancora eseguire SELECT, INSERT e UPDATE, ma non può DELETE all'interno di miodb_app.

  2. Revocare GRANT OPTION da un Amministratore Delegato

    Se admin_db non ha più bisogno di gestire i permessi di altri utenti per db_inventario.

    REVOKE GRANT OPTION ON `db_inventario`.* FROM 'admin_db'@'localhost';
    

    Nota: Per revocare GRANT OPTION, è necessario specificare esplicitamente GRANT OPTION nell'istruzione REVOKE.

  3. Revocare Tutti i Privilegi su un Database Specifico

    Per rimuovere tutti i privilegi che un utente ha su un particolare database.

    REVOKE ALL PRIVILEGES ON `vecchio_db`.* FROM 'vecchia_app'@'%';
    

    Attenzione: REVOKE ALL PRIVILEGES su *.* revocherà tutti i privilegi globali, che possono includere SUPER, CREATE USER, ecc. Fare attenzione quando si utilizza questo ambito a livello globale.

  4. Eliminare un Account Utente

    Quando un utente o un'applicazione non sono più necessari, è meglio rimuovere completamente l'utente.

    DROP USER 'strumento_report'@'%';
    

    Questo comando rimuove l'utente e tutti i suoi privilegi associati.

Suggerimenti per Revocare i Privilegi

  • Corrispondenza dell'Ambito: Quando si revoca, assicurarsi che l'ambito dell'oggetto (*.*, nome_database.*, ecc.) corrisponda esattamente a come il privilegio è stato originariamente concesso. Se hai concesso SELECT su nome_database.*, devi revocarlo da nome_database.*, non da nome_database.nome_tabella.
  • Verificare: Utilizzare sempre SHOW GRANTS FOR 'utente'@'host'; dopo aver concesso o revocato privilegi per confermare le modifiche.
  • Saltare flush non necessari: FLUSH PRIVILEGES non è necessario dopo GRANT, REVOKE, CREATE USER o DROP USER; MySQL applica queste istruzioni immediatamente.
  • Considerare gli effetti a cascata: Se un utente con GRANT OPTION ha concesso privilegi ad altri, revocare il suo GRANT OPTION non revoca automaticamente i privilegi che ha concesso. Dovresti revocarli separatamente.

Migliori Pratiche per la Gestione dei Privilegi degli Utenti MySQL

Implementare una strategia robusta di gestione dei privilegi è cruciale per la sicurezza del database.

1. Principio del Privilegio Minimo (PoLP)

Questa è la regola d'oro. Concedere solo i privilegi minimi assoluti richiesti a un utente o applicazione per svolgere la funzione prevista. Ad esempio:

  • Uno strumento di reporting necessita di SELECT.
  • Un'applicazione web tipicamente necessita di SELECT, INSERT, UPDATE, DELETE.
  • Un processo ETL potrebbe aver bisogno di INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE (ma solo su specifici schemi di staging).

2. Account Utente Dedicati

  • Evitare Account Condivisi: Ogni applicazione, servizio o utente amministrativo dovrebbe avere il proprio account utente MySQL unico. Questo aiuta nell'auditing e nel tracciamento delle attività.
  • Niente root per le Applicazioni: Non configurare mai le tue applicazioni per connettersi come utente root. L'utente root ha accesso illimitato e dovrebbe essere utilizzato solo per attività amministrative critiche da amministratori umani.

3. Password Forti e Rotazione delle Password

  • Imporre password forti e uniche per tutti gli account utente MySQL. Utilizzare i plugin di validazione delle password di MySQL se disponibili.
  • Implementare una politica di rotazione regolare delle password, specialmente per account con privilegi elevati.

4. Restrizioni sull'Host

  • Limitare le connessioni utente a indirizzi IP o nomi host specifici quando possibile. Sostituire '%' con localhost, l'IP di un server applicativo o una sottorete di rete ('utente'@'192.168.1.%'). Questo previene tentativi di accesso non autorizzati da posizioni sconosciute.

5. Audit e Revisioni Regolari

  • Rivedere periodicamente tutti gli account utente e i loro privilegi associati. Rimuovere eventuali account obsoleti o privilegi non necessari.
  • Utilizzare SHOW GRANTS FOR 'utente'@'host'; per ispezionare i permessi.
  • Considerare strumenti automatizzati per l'auditing di ambienti di grandi dimensioni.

6. Documentare i Permessi

  • Mantenere una documentazione chiara degli utenti del database, dei loro ruoli e dei privilegi concessi a ciascuno. Questo aiuta a mantenere la coerenza e facilita gli audit di sicurezza.

7. Separare gli Ambienti di Sviluppo, Staging e Produzione

  • Non utilizzare mai le credenziali di produzione in ambienti di sviluppo o staging. Ogni ambiente dovrebbe avere il proprio set di utenti e privilegi distinti.

8. Evitare GRANT OPTION a Meno che Non Sia Assolutamente Necessario

  • Concedere WITH GRANT OPTION delega la gestione dei privilegi a quell'utente, il che può bypassare le politiche di sicurezza centrali. Riservare questo solo per utenti amministrativi altamente fidati e sull'ambito più restrittivo possibile.

Visualizzare i Privilegi Correnti

Per verificare i privilegi assegnati a un utente, utilizzare il comando SHOW GRANTS:

SHOW GRANTS FOR 'nome_utente'@'host';

Esempio:

SHOW GRANTS FOR 'utente_app'@'localhost';

L'output potrebbe apparire come:

+-------------------------------------------------------------+
| Grants for utente_app@localhost                               |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'utente_app'@'localhost'                |
| GRANT SELECT, INSERT, UPDATE ON `miodb_app`.* TO 'utente_app'@'localhost' |
+-------------------------------------------------------------+

La riga GRANT USAGE ON *.* indica che l'utente non ha privilegi globali, solo la capacità di connettersi.

Conclusione

Mantenere la gestione dei privilegi MySQL ristretta e verificabile. Creare account dedicati, limitare gli host, concedere solo le azioni necessarie sull'ambito utile più piccolo e controllare ogni modifica con SHOW GRANTS. Quando un'app o una persona non ha più bisogno di accesso, revocare il privilegio o eliminare l'account invece di lasciare credenziali obsolete.