Uma prática comum hoje em dia é utilizar variáveis de ambiente para guardar dados sensíveis de produção, como senhas de conexão com banco de dados, chaves para acesso a arquivos, e toda sorte de segredos. É comum porque é prática, fica muito fácil configurar uma aplicação desta forma.

No entanto, o uso de variáveis de ambiente é especialmente problemático do ponto de vista de segurança, por colocar o segredo diretamente na memória do processo (muitas vezes da máquina como um todo), o que permite a leitura fácil.

As formas mais comuns de leitura são por um processo malicioso que está rodando na máquina e consegue ler os dados de outro processo, memória que acaba sendo escrita em disco (por hibernar a máquina ou no paging file) e acaba sendo depois recuperada, ou por um dump de memória.

O dump de memória

Vou me ater aqui ao caso do dump de memória, que é um caso bem comum e fácil de provar. O dump de memória é uma fotografia de um processo em determinado momento. É muito fácil tirar um dump de memória de um processo, você pode utilizar o próprio gestor de tarefas do Windows, clicar com o botão direito em um processo e extrair o dump:

Gestor de processos com o menu de contexto aberto sobre um processo com a opção de criar o arquivo de dump

Você pode tirar um dump completo da memória, que é um retrato fiel da aplicação, e normalmente vai ocupar o mesmo tamanho em disco que a memória do aplicativo ocupava e mais um pouco para informações adicionais, ou um minidump, que contém bem menos informações. Um minidump de um processo pode ter menos que 1MB, e também contém as informações da memória. O Task Manager tira um dump completo, você pode utilizar o Process Explorer se quiser tirar um mini dump.

O processo pode ser automatizado com ferramentas como o procdump da Sysinternals (que hoje é parte da Microsoft). O procdump de 64 bits tem meros 334KB, e pode rodar diretamente da web utilizando o Sysinternals Live, através do comando:

\\live.sysinternals.com\tools\procdump.exe

A maneira mais fácil de ter o Process Explorer e o Procdump na sua máquina é instalá-los via chocolatey utilizando o pacote sysinternals.

Lendo a variável a partir do dump

Pra ler o dump utilize o WinDbg, que agora tem até uma versão de preview na store do Windows que baixa e instala rapidinho (menos de 100MB), e é bem mais amigável que a versão espartana que vinha desde a versão do Windows que vinha com disquetes.

Por bem mais amigável entenda mais amigável, mas ainda nada amigável. WinDbg não é uma ferramenta para iniciantes.

Carregue o dump no WinDbg (File > Open Dump File), e basta emitir o comando !peb e ver todas a variáveis de ambiente do processo. No link dos docs do peb dá pra ver um exemplo de saída, com as variáveis.

Resumindo: qualquer usuário com permissão administrativa consegue ler as variáveis de memória de qualquer processo do computador em 3 passos:

  1. Tire um minidump
  2. Instale o WinDbg
  3. Leia o minidump com o !peb no WinDbg

Sendo que só o primeiro passo precisa ser feito na máquina sendo atacada. O arquivo resultante, o dump, pode ter menos de 1MB, e pode ser transportado para outra máquina onde pode ser lido utilizando o WinDbg. Ou seja, o ataque pode ser concluído remotamente.

Se o ataque acontecer via interface gráfica fica ainda mais fácil, o próprio Process Explorer dá acesso as variáveis de ambiente de qualquer processo. Basta clicar duas vezes em um processo e ir até a aba Environment.

Como resolver

Não utilize variáveis de ambiente para segredos. Isso pode ser feito de várias formas. Uma opção é colocar os segredos em arquivos, o que pode ser feito manualmente, como parte da montagem dos artefatos de produção, ou como segredos de contêineres do Kubernetes montados como arquivos. Há ainda outras técnicas.

Se você está rodando sua aplicação no Azure você pode usar o Azure Key Vault. Pra entender como ele funciona, veja esses docs. O problema é que você vai precisar da chave para o cofre. Não a coloque em uma variável de ambiente! Depois vou falar melhor como resolver esse problema, mas adianto que uma opção muito interessante envolve o uso do Managed Service Identity. E você sempre pode colocar a chave em um arquivo de configuração em vez de colocar na memória. Só cuidado para nunca colocar esse tipo de arquivo no source control.

Concluindo

Evite variáveis de ambiente para informações secretas, você vai ter mais seguranca.

Mas não espere que isso te deixará totalmente em segurança. Uma vez lida, a informação secreta fica na memória do processo, que também pode ser analisada. Vou explicar esse problema, analisá-lo com cuidado e propor como resolvê-lo no meu próximo post.