SQL Server - Como ocultar os databases para usuários não autorizados - Dirceu Resende
Nesse artigo eu gostaria de demonstrar como melhorar a segurança das suas instâncias SQL Server de uma forma bem simples e utilizando uma combinação das técnicas de Ocultação e Restrição de Acesso (lembrando que na Segurança temos 3 técnicas principais: Ocultação, Restrição de Acesso e Criptografia).
O que eu gostaria de discutir nesse artigo é sobre o privilégio VIEW ANY DATABASE, concedido por padrão para a role public, que assim como o nome sugere, permite que todos os logins da instância consigam visualizar todos os databases que nela estão criados.
Através da técnica de Restrição de Acesso vamos remover esse privilégio da role public, para que através de ocultação, um possível invasor não consiga identificar o nome dos databases da instância, dificultando bastante o sucesso de seus ataques.
Um cenário muito comum que ocorre no dia a dia, é uma mesma instância abrigar várias aplicações distintas. De nada vale você proteger a sua aplicação e o seu banco utilizando todas as boas práticas, se uma dessas aplicações que compartilha o servidor possui vulnerabilidades e o usuário da conexão com o banco tenha o perfil sysadmin, por exemplo, ou mesmo tenha um acesso restrito mas exponha o nome de todos os databases que estão na instância.
Para demonstrar que isso realmente existe, você pode utilizar a consulta abaixo para identificar os usuários que possuem essa permissão no banco:
Ou se você só acredita em testes práticos, vamos lá:
Criei o login "teste_view_any_database" com apenas o comando acima, sem dar NENHUMA permissão para esse usuário. Vou conectar na instância com ele e vamos ver o que eu consigo fazer:
Sem nenhuma permissão, consegui listar todos os databases e suas propriedades. Agora vou retirar a permissão VIEW ANY DATABASE da role public e vou testar novamente:
Agora vou liberar acesso de leitura em uma das bases:
Agora vou testar se o usuário consegue consultar os dados normalmente nas tabelas e se ele consegue consultar informações desse database:
Como vocês puderam observar acima, após remover essa permissão, o usuário consegue consultar normalmente os dados. O que ele não vai conseguir mais fazer, é consultar informações da instância pelas DMV's sys.databases e sys.sysdatabases, nem abrir a lista dos databases pelo SQL Server Management Studio e nem no Object Explorer:
Mesmo SEM a permissão VIEW ANY DATABASE, o login consegue utilizar a instrução USE [database] para alternar entre os databases ativos da sessão em que ele tenha acesso (permissão de CONNECT). Ao trocar o banco da sessão, você conseguirá consultar os dados desse database nas DMV's sys.databases e sys.sysdatabases normalmente:
É importante destacar que, caso esse usuário seja o owner do database (db_owner), ele conseguirá listar esse database mesmo sem a permissão VIEW ANY DATABASE:
Entretanto, entendo que para um usuário que faz consultas no banco, isso pode atrapalhar e reduzir bastante a produtividade dessas pessoas. Por tanto, um meio termo seria remover essa permissão da role public e criar uma nova role, que tenha essa permissão, mas que apenas os usuários de pessoas (sem usuários de sistema) façam parte dessa role:
Em muitas empresas, os sistemas costumam utilizar logins com autenticação SQL Server e as pessoas se conectam utilizando autenticação AD. Nesse cenário, a administração pode ficar ainda mais fácil, adicionado o grupo padrão do AD "Domain Users" na aba de Logins e liberando a permissão VIEW ANY DATABASE para esse grupo do AD. Desta forma, todos os usuários de pessoas poderão visualizar os databases, mas nenhum sistema terá esse acesso. O ruim dessa abordagem, é que TODOS os usuários do AD terão acesso ao seu banco de dados.
E por fim, é importante salientar que sugiro não utilizar o DENY VIEW ANY DATABASE na role public, uma vez que o DENY sobrepõe a permissão de GRANT e mesmo liberando acessos específicos para os usuários, o usuário não vai conseguir listar os databases.
Lembrando que usuários sysadmin conseguem listar os databases normalmente mesmo com REVOKE ou DENY dessa permissão para a role public.
IMPORTANTE: ANTES de remover essa permissão em produção, TESTE várias vezes os seus sistemas para garantir que eles não terão nenhum impacto. Se o seu sistema precisa listar os databases da instância para alguma operação, com certeza ele terá impacto (a não ser que ele seja db_owner, mas aí temos um problema de permissão, hein…)
Bom pessoal, espero que vocês tenham gostado dese post.
Acredito que com pequenas medidas, quando aplicadas juntas, podemos melhorar a segurança do nosso ambiente e dificultar bastante o "trabalho" de possíveis invasores.
Next Como foi o Microsoft Ignite The Tour (São Paulo) e o MVP Get Together 2018
Previous SQL Server – Como identificar as consultas que utilizam um determinado índice através do plan cache