Melhores Práticas para Conceder e Revogar Privilégios de Usuário no MySQL

Use MySQL GRANT, REVOKE, SHOW GRANTS e DROP USER com segurança, com exemplos de menor privilégio para contas de aplicativos e administradores.

Melhores Práticas para Conceder e Revogar Privilégios de Usuário no MySQL

Os privilégios do MySQL determinam o que seus aplicativos, ferramentas e administradores podem fazer após se conectarem. Uma única conta com acesso amplo pode transformar um pequeno bug ou uma senha vazada em exposição total do banco de dados.

Use GRANT, REVOKE e SHOW GRANTS com o princípio do menor privilégio: cada conta deve ter apenas as permissões necessárias, a partir apenas dos hosts que utiliza.

Entendendo os Privilégios do MySQL

Antes de mergulhar em GRANT e REVOKE, é crucial entender os diferentes escopos e tipos de privilégios disponíveis no MySQL. Os privilégios definem quais ações um usuário pode realizar e em quais objetos do banco de dados.

Os privilégios do MySQL podem ser categorizados por seu escopo:

  • Privilégios Globais (*.*): Aplicam-se a todos os bancos de dados e tabelas no servidor MySQL. Exemplos incluem SUPER, PROCESS, RELOAD, CREATE USER.
  • Privilégios de Banco de Dados (nome_do_banco.*): Aplicam-se a todas as tabelas e objetos dentro de um banco de dados específico. Exemplos incluem SELECT, INSERT, UPDATE, DELETE, CREATE, DROP.
  • Privilégios de Tabela (nome_do_banco.nome_da_tabela): Aplicam-se a todas as colunas dentro de uma tabela específica. Exemplos incluem SELECT, INSERT, UPDATE, DELETE, ALTER.
  • Privilégios de Coluna (nome_do_banco.nome_da_tabela.nome_da_coluna): Aplicam-se a colunas específicas dentro de uma tabela. Isso é menos comum, mas útil para controle altamente granular.
  • Privilégios de Rotina (nome_do_banco.nome_da_rotina): Aplicam-se a procedimentos armazenados e funções, controlando EXECUTE e ALTER ROUTINE.
  • Privilégios de Proxy: Permitem que um usuário atue como outro, útil para aplicativos que gerenciam identidades de usuários.

Alguns privilégios específicos comuns incluem:

  • SELECT: Ler dados de tabelas.
  • INSERT: Adicionar novas linhas a tabelas.
  • UPDATE: Modificar linhas existentes em tabelas.
  • DELETE: Remover linhas de tabelas.
  • CREATE: Criar bancos de dados, tabelas ou índices.
  • DROP: Excluir bancos de dados, tabelas ou índices.
  • ALTER: Modificar estruturas de tabelas.
  • INDEX: Criar ou remover índices.
  • REFERENCES: Estabelecer restrições de chave estrangeira.
  • CREATE VIEW, SHOW VIEW: Gerenciar visualizações.
  • CREATE ROUTINE, ALTER ROUTINE, EXECUTE: Gerenciar e executar procedimentos armazenados e funções.
  • FILE: Ler ou escrever arquivos no host do servidor (altamente poderoso, use com extrema cautela).
  • GRANT OPTION: Permite que um usuário conceda seus próprios privilégios a outros usuários. Este é um privilégio muito poderoso e deve ser concedido com moderação.

O Comando GRANT: Concedendo Privilégios com Segurança

O comando GRANT é usado para atribuir privilégios a um usuário do MySQL. Ao conceder privilégios, é crucial considerar o princípio do menor privilégio – conceda apenas o que é absolutamente necessário.

Sintaxe Básica

A sintaxe geral para o comando GRANT é:

GRANT privilégios ON objeto TO 'usuário'@'host' [WITH GRANT OPTION];
  • privilégios: Uma lista separada por vírgulas de privilégios (ex.: SELECT, INSERT).
  • objeto: Especifica o escopo (ex.: *.* para global, nome_do_banco.*, nome_do_banco.nome_da_tabela).
  • 'usuário'@'host': A conta de usuário, incluindo o nome de usuário e o host a partir do qual ele pode se conectar. O host pode ser um endereço IP, nome de host ou um curinga (% para qualquer host, localhost para conexões locais).
  • WITH GRANT OPTION: (Opcional) Permite que o usuário conceda os privilégios especificados a outros usuários.

Crie ou altere senhas com CREATE USER e ALTER USER. Versões mais antigas do MySQL permitiam GRANT ... IDENTIFIED BY, mas a sintaxe moderna do MySQL mantém a criação de conta separada.

Exemplos Práticos

Vamos percorrer alguns cenários comuns.

  1. Criando um Novo Usuário e Concedendo Acesso Global Somente Leitura (Altamente Desencorajado)

    CREATE USER 'leitor_global'@'localhost' IDENTIFIED BY 'StrongPass123!';
    GRANT SELECT ON *.* TO 'leitor_global'@'localhost';
    

    Aviso: Conceder SELECT em *.* dá acesso a todos os bancos de dados e tabelas. Isso geralmente é muito amplo para usuários de aplicativos e deve ser evitado, a menos que seja absolutamente necessário para tarefas administrativas específicas.

  2. Concedendo Acesso Total a um Banco de Dados Específico para um Usuário de Aplicativo

    Um cenário comum para um usuário de aplicativo que precisa gerenciar dados dentro de seu próprio banco de dados.

    CREATE USER 'usuario_app'@'localhost' IDENTIFIED BY 'AppPassSecure!';
    GRANT SELECT, INSERT, UPDATE, DELETE ON `meuapp_db`.* TO 'usuario_app'@'localhost';
    

    Aqui, usuario_app pode realizar operações CRUD básicas apenas dentro do banco de dados meuapp_db, mas não pode criar novas tabelas ou modificar o esquema.

  3. Concedendo Acesso Somente Leitura a uma Tabela Específica

    Para uma ferramenta de relatórios que só precisa ler de uma tabela específica.

    CREATE USER 'ferramenta_relatorio'@'%' IDENTIFIED BY 'ReportSecret!';
    GRANT SELECT ON `vendas_db`.`pedidos` TO 'ferramenta_relatorio'@'%';
    

    O host '%' permite que ferramenta_relatorio se conecte de qualquer host, mas apenas com acesso SELECT na tabela pedidos em vendas_db.

  4. Concedendo GRANT OPTION (Use com Extrema Cautela)

    Se um administrador precisar delegar o gerenciamento de privilégios para um banco de dados específico.

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

    O admin_db agora pode conceder quaisquer privilégios em inventario_db a outros usuários. Este é um privilégio poderoso que contorna o controle central e deve ser usado apenas quando inevitável.

Dicas para Conceder Privilégios

  • Princípio do Menor Privilégio: Sempre conceda o conjunto mínimo de privilégios necessário para um usuário ou aplicativo funcionar. Evite ALL PRIVILEGES, a menos que seja para uma conta de administrador de banco de dados dedicada.
  • Hosts Específicos: Restrinja as conexões de usuários a endereços IP ou nomes de host específicos ('usuário'@'192.168.1.10' ou 'usuário'@'servidorapp.exemplo.com') em vez de '%' quando possível.
  • Usuários Separados: Crie contas de usuário separadas para diferentes aplicativos ou serviços, mesmo que acessem o mesmo banco de dados. Isso isola possíveis violações de segurança.
  • Sem root para Aplicativos: Nunca use a conta de usuário root para seus aplicativos. Crie usuários dedicados com privilégios mínimos.

O Comando REVOKE: Revogando Privilégios Efetivamente

O comando REVOKE é usado para remover privilégios de um usuário do MySQL. É tão importante quanto GRANT para manter um ambiente de banco de dados seguro, especialmente quando funções mudam ou aplicativos são desativados.

Sintaxe Básica

A sintaxe geral para o comando REVOKE é:

REVOKE privilégios ON objeto FROM 'usuário'@'host';
  • privilégios: Uma lista separada por vírgulas de privilégios a serem revogados.
  • objeto: O escopo do qual revogar (deve corresponder ao escopo onde os privilégios foram concedidos).
  • 'usuário'@'host': A conta de usuário da qual revogar os privilégios.

Exemplos Práticos

  1. Revogando o Privilégio DELETE de um Usuário de Aplicativo

    Se um aplicativo não precisar mais excluir dados, ou se você quiser reduzir suas permissões.

    REVOKE DELETE ON `meuapp_db`.* FROM 'usuario_app'@'localhost';
    

    Agora, usuario_app ainda pode SELECT, INSERT e UPDATE, mas não pode DELETE dentro de meuapp_db.

  2. Revogando GRANT OPTION de um Administrador Delegado

    Se admin_db não precisar mais gerenciar as permissões de outros usuários para inventario_db.

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

    Nota: Para revogar GRANT OPTION, você deve especificar explicitamente GRANT OPTION na instrução REVOKE.

  3. Revogando Todos os Privilégios em um Banco de Dados Específico

    Para remover todos os privilégios que um usuário tem em um banco de dados específico.

    REVOKE ALL PRIVILEGES ON `banco_antigo`.* FROM 'app_antigo'@'%';
    

    Aviso: REVOKE ALL PRIVILEGES em *.* revogará todos os privilégios globais, o que pode incluir SUPER, CREATE USER, etc. Tenha cuidado ao usar este escopo globalmente.

  4. Removendo uma Conta de Usuário

    Quando um usuário ou aplicativo não for mais necessário, é melhor remover o usuário completamente.

    DROP USER 'ferramenta_relatorio'@'%';
    

    Este comando remove o usuário e todos os seus privilégios associados.

Dicas para Revogar Privilégios

  • Corresponder Escopo: Ao revogar, certifique-se de que o escopo do objeto (*.*, nome_do_banco.*, etc.) corresponda precisamente a como o privilégio foi originalmente concedido. Se você concedeu SELECT em nome_do_banco.*, deve revogá-lo de nome_do_banco.*, não de nome_do_banco.nome_da_tabela.
  • Verificar: Sempre use SHOW GRANTS FOR 'usuário'@'host'; após conceder ou revogar privilégios para confirmar as alterações.
  • Evitar flushes desnecessários: FLUSH PRIVILEGES não é necessário após GRANT, REVOKE, CREATE USER ou DROP USER; o MySQL aplica essas instruções imediatamente.
  • Considerar efeitos em cascata: Se um usuário com GRANT OPTION concedeu privilégios a outros, revogar seu GRANT OPTION não revoga automaticamente os privilégios que ele concedeu. Você precisaria revogá-los separadamente.

Melhores Práticas para Gerenciamento de Privilégios de Usuário no MySQL

Implementar uma estratégia robusta de gerenciamento de privilégios é crucial para a segurança do banco de dados.

1. Princípio do Menor Privilégio (PoLP)

Esta é a regra de ouro. Conceda apenas os privilégios mínimos absolutos necessários para um usuário ou aplicativo executar sua função pretendida. Por exemplo:

  • Uma ferramenta de relatórios precisa de SELECT.
  • Um aplicativo web normalmente precisa de SELECT, INSERT, UPDATE, DELETE.
  • Um processo ETL pode precisar de INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE (mas apenas em esquemas de staging específicos).

2. Contas de Usuário Dedicadas

  • Evitar Contas Compartilhadas: Cada aplicativo, serviço ou usuário administrativo deve ter sua própria conta de usuário MySQL única. Isso auxilia na auditoria e no rastreamento de atividades.
  • Sem root para Aplicativos: Nunca configure seus aplicativos para se conectar como usuário root. O usuário root tem acesso irrestrito e deve ser usado apenas para tarefas administrativas críticas por administradores humanos.

3. Senhas Fortes e Rotação de Senhas

  • Exija senhas fortes e únicas para todas as contas de usuário do MySQL. Utilize os plugins de validação de senha do MySQL, se disponíveis.
  • Implemente uma política regular de rotação de senhas, especialmente para contas com altos privilégios.

4. Restrições de Host

  • Limite as conexões de usuários a endereços IP ou nomes de host específicos sempre que possível. Substitua '%' por localhost, o IP de um servidor de aplicativos ou uma sub-rede de rede ('usuário'@'192.168.1.%'). Isso impede tentativas de acesso não autorizado de locais desconhecidos.

5. Auditorias e Revisões Regulares

  • Revise periodicamente todas as contas de usuário e seus privilégios associados. Remova quaisquer contas obsoletas ou privilégios desnecessários.
  • Use SHOW GRANTS FOR 'usuário'@'host'; para inspecionar permissões.
  • Considere ferramentas automatizadas para auditar grandes ambientes.

6. Documentar Permissões

  • Mantenha uma documentação clara de seus usuários de banco de dados, suas funções e os privilégios concedidos a cada um. Isso ajuda a manter a consistência e facilita as auditorias de segurança.

7. Separar Ambientes de Desenvolvimento, Staging e Produção

  • Nunca use credenciais de produção em ambientes de desenvolvimento ou staging. Cada ambiente deve ter seu próprio conjunto de usuários e privilégios distintos.

8. Evitar GRANT OPTION a Menos que Absolutamente Necessário

  • Conceder WITH GRANT OPTION delega o gerenciamento de privilégios a esse usuário, o que pode contornar as políticas de segurança centrais. Reserve isso para usuários administrativos altamente confiáveis e apenas no escopo mais restritivo possível.

Visualizando Privilégios Atuais

Para verificar os privilégios atribuídos a um usuário, use o comando SHOW GRANTS:

SHOW GRANTS FOR 'nome_do_usuario'@'host';

Exemplo:

SHOW GRANTS FOR 'usuario_app'@'localhost';

A saída pode ser semelhante a:

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

A linha GRANT USAGE ON *.* indica que o usuário não tem privilégios globais, apenas a capacidade de se conectar.

Conclusão

Mantenha o gerenciamento de privilégios do MySQL restrito e revisável. Crie contas dedicadas, restrinja hosts, conceda apenas as ações necessárias no menor escopo útil e verifique cada alteração com SHOW GRANTS. Quando um aplicativo ou pessoa não precisar mais de acesso, revogue o privilégio ou remova a conta em vez de deixar credenciais obsoletas para trás.