quarta-feira, 3 de dezembro de 2014

Protegendo o dados de banco definido como resource do tomcat

Boa noite negada.

Tem muito tempo que estou devendo esse artigo pois é extremamente importante
do ponto de vista de segurança. Só que ando um pouco sem tempo.

As aplicações que fazemos deploy no tomcat normalmente fazem acesso ao banco de dados
e as configurações para esse acesso sempre ficam expostas em um arquivo XML.
Se um invasor conseguir acesso ao nosso ambiente de produção, é só abrir o arquivo context.xml
no diretório conf do tomcat e todos os usuários e senhas estarão lá.

Então, uma ótima forma de dificultar esse acesso é criptografando a senha.
Sempre dizem que encriptar a senha é mover o problema para outro lugar.
Concordo plenamente. Então vamos mover para um lugar que exija conhecimento do cracker
para descobrir qual jar está nossa factory, decompilá-lo, executar o projeto e
alterar o código para desencriptar. Com quase nada, vamos dificultar bastante a vida de um atacante.



Esse arquivo é do meu tomcat e mostra 3 resources (apaguei os passwords do screenshot). Cada um é de uma aplicação e os três fazem acesso ao banco de dados local. Note que o type está definido como javax.sql.DataSource.
O que iremos fazer é adicionar uma factory que receba todos esses parametros, decifre a senha
e coloque a senha decifrada antes de abrirmos a conexão com o banco.

Vamos então criar a nossa factory...



Reparem que a única coisa que ela faz é pegar o object, converter em BasicDataSource,
pegar a senha, decifrar e setar a senha decifrada no objeto. Simples assim!

Agora a gente se encontra com outro problema: como cifrar e decifrar a senha ?
Isso vai vai de cada um mas vou colocar o código que usei. Estou usando criptografia
com o AES com chave de 256 bits (o algoritmo aceita chaves de 128, 192 e 256 bits). Deixei o exemplo usando o algoritmo DES também mas não é recomendado utilizá-lo pois sua segurança já foi quebrada.
Note que quando vamos decifrar a senha usando o algoritmo AES, é adicionado um IvParameterSpec
que foi criado com um array de bytes. Isso acontece porque o AES é um algoritmo cifrado de bloco.
Voce pode mudar o conteúdo do array para o que voce quiser, desde que o mesmo array seja utilizado
tanto para cifrar quanto para decifrar a senha.



Pronto. Agora basta gerarmos o jar do nosso projeto e adicionar na pasta de libs do tomcat
que fica em $TOMCAT_HOME$\lib.
Para fazer o encode e decode em Base64, eu usei o apache commons-codec. Então esse jar tambem
deve ser adicionado à pasta do tomcat para funcionar corretamente. Caso voce não queira o commons-codec como uma dependência e quer fazer funcionar apenas com nossa classe (nosso jar), basta fazer o encode e decode da Base64 na mão. Assim, nao é necessário o commons-codec.

Importante: assim como criptografamos a senha no arquivo context.xml, podemos criptografar todos os outros dados como usuário e url de conexão.

Referência: http://stackoverflow.com/questions/129160/how-to-avoid-storing-passwords-in-the-clear-for-tomcats-server-xml-resource-def