Não é segredo que a informação faz o mundo girar atualmente. Se uma empresa cuidar de sua propriedade intelectual e cada funcionário puder obter facilmente as informações necessárias, a empresa pode esperar pelo crescimento. Se houver caos nos dados, a empresa falhará apesar do espírito de equipe.
Neste artigo, vamos explorar os fundamentos de segurança de banco de dados e exemplos de proteção de informações no Oracle. Na verdade, os fundamentos teóricos para proteger informações no banco de dados, que vamos considerar neste artigo, também serão úteis para pessoas que trabalham com outros bancos de dados.
Permissões de acesso
Na maioria das empresas em que trabalhei, todos os administradores e desenvolvedores tinham acesso total aos bancos de dados, assim como um funcionário do departamento de TI era um deus e podia fazer o que quisesse. Por que isso acontece? Há duas razões para isso:
- Enquanto trabalham em um departamento, os funcionários podem se encontrar por 8 horas todos os dias e se tornar amigos. Como eles não podem conceder acesso? Amizade é uma coisa, mas negócios são negócios.
- Conceder alguns direitos de acesso ou modificar alguma configuração pode exigir alguns privilégios. Às vezes, os administradores pensam que os programadores definem melhor as configurações. Assim, eles fornecem aos programadores direitos de acesso desnecessários. Em vez disso, os programadores não devem estar envolvidos na administração e não devem ter nenhum direito para isso.
Na minha experiência, o segundo problema é muito comum, portanto, vamos analisá-lo em detalhes.
Ao desenvolver programas para bancos de dados, os programadores sabem uma senha de superusuário ou simplesmente têm direitos de administrador de banco de dados. Isso é desnecessário e absolutamente inseguro. Apenas o administrador do banco de dados deve ter direitos totais. Mesmo o chefe do departamento, o diretor e os melhores amigos podem ter menos privilégios.
Por exemplo, ao desenvolver programas, basta ter os direitos de proprietário do esquema no banco de dados Oracle que armazena as tabelas de trabalho. Esses direitos são suficientes para criar novas tabelas, pacotes, índices e outros objetos, bem como conceder direitos de acesso a objetos de esquema a outros usuários. Você não precisa dos direitos do sistema para trabalhar em tempo integral.
Se não houver um administrador de banco de dados em tempo integral, é muito ruim. É melhor quando há alguém responsável pelo desempenho, otimização e segurança do banco de dados. Pelo menos, você precisa nomear um programador que será responsável por isso e terá direitos exclusivos.
Segundo as estatísticas, os funcionários da empresa causam perda de dados com mais frequência. Ainda assim, apesar desse fato, a maioria das empresas continua ignorando esse segmento e diferentes bancos de dados armazenados em discos de acesso gratuito são vendidos até mesmo no metrô.
Usuários e funções
Existem dois tipos de objetos para conceder direitos de acesso em bancos de dados:usuários e funções. As funções são alguns grupos que combinam usuários que devem ter direitos semelhantes. Por exemplo, todos os contadores podem exigir acesso a documentos financeiros. Para evitar que você conceda direitos a cada contador, podemos combiná-los em uma função com o acesso necessário.
Como você pode ver, o princípio das funções é semelhante aos grupos no sistema operacional Windows. Ainda assim, tem algumas diferenças. Não sem razão, todos os três tipos de objetos, como usuários, grupos e funções, podem ser implementados no banco de dados. No entanto, apenas usuários e funções são implementados na maioria dos bancos de dados. É necessário gerenciar e monitorar todos esses objetos para que cada usuário que obtenha os direitos concedidos pelas funções possa ter acesso aos dados que realmente são necessários para resolver as tarefas. É necessário usar os direitos de acesso como regras para um firewall. Usando esses direitos, você pode resolver o mesmo problema – permitir que um usuário execute apenas determinadas tarefas e evitar possíveis perdas ou corrupção.
Com a ajuda de funções, é bastante conveniente controlar o acesso, fornecer permissões ou bloquear todo o grupo de usuários. Uma função pode ser incluída na outra, herdando assim seus direitos de acesso. Portanto, podemos criar uma estrutura hierárquica de direitos.
Todos os funcionários com direitos de acesso a um banco de dados corporativo podem ser incluídos em uma única função com direitos mínimos. Agora, se você precisar de privilégios adicionais, acesso a tabelas específicas, precisará adicionar um usuário a outras funções (se um grupo exigir o mesmo acesso) ou fornecer os direitos a uma conta específica.
No programa, para controlar o acesso às tabelas, é possível verificar o resultado quanto a erros após cada tentativa de abertura do dataset. Se ocorrer um erro de acesso, o acesso à tabela especificada será bloqueado para um usuário. Assim, não há necessidade de implementar os direitos de acesso ao aplicativo cliente. No entanto, se você quiser implementar isso, não haverá nenhum dano. Pelo menos, não vejo nada de crítico nisso; parece ter o efeito oposto.
Auditoria de segurança
Se cada usuário estiver trabalhando em sua própria conta em seu banco de dados, você pode chamar a variável user para determinar o usuário atual, por exemplo:
SELECT user from dual
Esta consulta retornará um nome de usuário, sob o qual a conexão com o servidor é aberta. Se várias pessoas puderem fazer login usando um nome, essa consulta retornará o mesmo nome para ambos e seria inútil para a auditoria. Especialmente, se o controle de bloqueio ocorrer no nível do servidor.
Se vários usuários podem fazer login usando o mesmo nome de usuário, é complicado, mas ainda possível, identificar quem fez login na conta. A consulta a seguir permite obter as informações detalhadas sobre a sessão:
select s.user#, s.username, s.osuser, s.terminal, s.program from sys.v_$session s WHERE username=user
Como você pode ver, a consulta retornou o nome de usuário, conectado ao banco de dados, um nome no sistema operacional, um nome de usuário do terminal e um programa.
Aqui, você pode acessar a visualização v_$session do esquema do sistema sys. Esta visualização retorna algumas informações sobre as conexões com o servidor. Na cláusula WHERE, limitamos a saída apenas ao usuário atual. Como resultado, a consulta retorna o ID do usuário, nome, nome no sistema operacional, terminal e o programa a partir do qual a conexão foi estabelecida.
Quando você conhece um nome de usuário e um nome de terminal, pode identificar um usuário com certeza. Para saber a quais funções o usuário atual foi adicionado, você pode executar a seguinte consulta:
SELECT GRANTED_ROLE FROM dba_role_privs WHERE grantee=user
Segurança da conta
Não diremos que não deve haver senhas padrão. Alguns bancos de dados, por exemplo, MySQL erram quando criam uma senha de sistema simples e conhecida após a instalação. Também não diremos que a senha deve ser complicada. Essa regra se aplica a todas as áreas de TI e deve ser conhecida até mesmo por um usuário iniciante. Vamos falar sobre problemas de banco de dados.
Na minha experiência, ao desenvolver programas corporativos, os desenvolvedores usam a mesma conta para acessar um banco de dados. Os parâmetros desta conta são registrados diretamente no programa, enquanto o acesso a módulos particulares, incluindo contabilidade, armazém, departamento de pessoal, etc. é implementado de forma programática. Por um lado, esse método é conveniente, pois o programa pode se conectar ao banco de dados com direitos de administrador e não precisará cuidar das funções e direitos de acesso às tabelas. Por outro lado, este método está longe de ser seguro. O nível de usuários está crescendo e os amigos dos funcionários da sua empresa podem ser educados na área de segurança e hackers. Depois de saber o nome e a senha, sob os quais o programa se conecta ao banco de dados, um usuário comum pode obter mais oportunidades do que deseja.
A linguagem SQL não é uma linguagem secreta e complicada. Existem muitos programas com os quais você pode visualizar facilmente qualquer dado no banco de dados. Com o nome de usuário e senha, qualquer pessoa pode roubar todos os seus dados. Assim, será vendido em qualquer banca que venda discos.
Um nome de usuário e senha nunca devem ser armazenados no programa. O acesso ao programa também deve ser limitado e impossível para terceiros. É bastante lógico combinar os dois logins em um. É necessário criar uma conta separada no servidor de banco de dados com os direitos mínimos necessários para cada usuário da organização. Esses nomes e senhas devem ser usados ao fazer login no programa. Você pode usar uma lógica comum e muito eficaz – se você conseguir fazer login no banco de dados com os dados inseridos, o acesso é permitido; se não, você deve abortar o programa. Este processo é simples e eficaz porque utilizamos autorização de banco de dados.
Para verificar se os usuários não trabalham simultaneamente em dois computadores diferentes com o mesmo nome, você pode executar a seguinte consulta:
select s.username, s.terminal, count(*) from sys.v_$session s WHERE username=user HAVING count(*)>1 GROUP BY s.username, s.terminal
Na verdade, ele não deve retornar nenhum registro.
Visualizações
As visualizações são uma maneira muito conveniente de desligar a estrutura de dados e criar um nível adicional de proteção ao mesmo tempo. É verdade que as visualizações têm um impacto negativo na produtividade, mas têm um impacto positivo na segurança. Podemos conceder seus próprios direitos de acesso, enquanto as tabelas das quais os dados são recuperados podem permanecer inacessíveis a essa conta.
Quando é melhor usar visualizações? Primeiro, vamos definir quais são suas desvantagens. Uma visão é uma instrução SELECT para recuperar dados. Ele pode acessar tanto uma quanto várias tabelas. Se você apenas selecionar os dados da visualização, não haverá perda de desempenho. No entanto, podemos usar visualizações em outras consultas para selecionar dados e referenciá-los nas tabelas. Por exemplo:
SELECT list of fields FROM view, table_1, table_2 WHERE some parameters
Nesse caso, a consulta busca dados da exibição e de duas tabelas. Além disso, podemos visualizar um relacionamento entre todos os objetos e uma condição adicional pode ser definida.
Agora, vamos ver a consulta como o otimizador de banco de dados a vê:
SELECT list of fields FROM (SELECT ...), table1, table2 WHERE some parameters
Nesse caso, substituí a exibição por uma instrução SELECT abstrata entre parênteses na qual a exibição consiste. Acontece que o servidor vê uma consulta com uma subconsulta. Se a subconsulta retornar dados dinâmicos, em vez de um valor estático, essa seleção de dados funcionará mais lentamente do que se escrevêssemos a mesma consulta sem a subconsulta.
Segurança de dados
Você nunca deve conceder acesso total a objetos sem uma necessidade especial. Eu sempre começo fornecendo direitos apenas para permitir a seleção de dados com a instrução SELECT. Se o usuário realmente precisar inserir novos registros e não puder realizar as tarefas a ele atribuídas, neste caso, adicione a permissão na instrução INSERT da tabela especificada.
As operações mais perigosas para os dados são modificação e exclusão, ou seja, UPDATE e DELETE, respectivamente. Você precisa conceder esses direitos com cuidado. Certifique-se de que os dados podem ser modificados ou excluídos. Somente neste caso, selecione os direitos apropriados. Algumas tabelas são estendidas apenas por natureza.
É necessário ter certeza de que os dados serão afetados com frequência. Por exemplo, a tabela de funcionários pode ser estendida e modificada, mas um único registro nunca deve ser excluído. A remoção pode influenciar o histórico de trabalho dos funcionários, relatórios e integridade de dados. O caso em que um oficial de recursos humanos acidentalmente adiciona um registro extra e deseja excluí-lo ainda é possível. No entanto, esses casos são raros e o erro pode ser corrigido pelo administrador do banco de dados. Entendemos que ninguém quer trabalhar demais e é mais fácil conceder uma permissão, no entanto, a segurança é mais valiosa.
A concessão de direitos é realizada usando o operador GRANT. Em geral, fica assim:
GRANT o que dar direitos a objetos ON a usuários ou funções
Por exemplo, a consulta a seguir concede o direito de inserir e exibir a tabela TestTable para User1:
GRANT Select, Insert ON TestTable TO User1
Chaves estrangeiras
Muitos usuários têm medo de chaves estrangeiras porque geralmente elas não permitem a exclusão de dados quando há uma junção externa. O problema pode ser facilmente resolvido se for estabelecida uma exclusão em cascata. No entanto, a maioria dos especialistas não gosta dessa possibilidade. Uma ação ridícula pode corromper dados muito importantes sem nenhuma solicitação de confirmação. Os dados vinculados devem ser excluídos explicitamente e somente se o usuário tiver confirmado conscientemente que os dados podem ser excluídos.
Não tenha medo de chaves estrangeiras. Eles nos fornecem uma maneira conveniente de controlar a integridade dos dados do servidor de banco de dados, portanto, essa é a segurança que nunca é demais. O fato de que pode haver problemas com a exclusão é apenas um benefício. É melhor não excluir os dados do que perdê-los para sempre. A chave estrangeira junto com o índice não reduz o desempenho. Esta é apenas uma pequena verificação ao excluir os dados ou modificar o campo-chave ao qual os dados estão conectados em diferentes tabelas.
Backup
O backup também é um dos fatores de segurança que ignoramos antes da primeira perda de dados. No entanto, pessoalmente, eu o teria incluído nos principais. A perda de dados pode ser causada não apenas por hackers e usuários inaptos, mas também devido ao mau funcionamento do equipamento. Falhas no equipamento podem levar à perda do banco de dados, cuja restauração pode levar horas ou até dias.
É necessário desenvolver a política de backup mais eficaz com antecedência. O que se quer dizer com isso? O tempo de inatividade causado pela perda de dados e até o momento da restauração da capacidade de trabalho deve ser mínimo. A perda de dados também deve ser mínima e o backup não deve afetar o trabalho do usuário. Se houver dinheiro e oportunidades, é melhor usar sistemas como RAID, cluster ou até replicação de dados.
Backup e recuperação são um tópico separado e interessante. Não poderíamos abordá-lo aqui, mas não o consideraremos em detalhes.
Resumo
Consideramos os fundamentos de segurança, em particular para a Oracle. Não esqueça que a proteção fornecida pelo banco de dados é de apenas um nível, enquanto a proteção deve ser multinível. Para dormir um pouco com a mente limpa, é necessário implementar todos os recursos de segurança na rede, servidores e todos os computadores, incluindo antivírus, anti-spyware, VPN, IDS, etc. Quanto mais níveis de proteção houver, mais difícil será superá-los.
Deve haver uma política e controle de segurança claros. Se um funcionário sair, sua conta será excluída. Se você tiver usuários trabalhando com a mesma senha ou usando uma senha de grupo para realizar alguma tarefa, todas essas senhas devem ser alteradas. Por exemplo, se um administrador sair e você tiver todos os administradores usando a mesma conta, você deverá alterar a senha.
A segurança é necessária. Você deve se proteger não apenas de hackers, mas também de usuários “novatos”, que podem corromper dados por sua inexperiência. Uma boa política de segurança ajuda a prevenir tais casos e essa possibilidade não pode ser excluída. É melhor fornecer a capacidade de proteger os dados da inexperiência com antecedência do que perder muito tempo para restaurar os dados e obter tempo de inatividade desnecessário.
Leia também:
Configurando permissões de acesso ao banco de dados