Ficheiros .env expostos e chaves vazadas
Um ficheiro .env exposto é um ficheiro de configuração — o que guarda a senha da sua base de dados, as suas credenciais de correio e as suas chaves de API — que o seu servidor web entrega a quem o pedir pelo nome, e uma pasta .git exposta é o mesmo acidente com todo o seu histórico de código anexo. Nenhum dos dois exige que um atacante quebre alguma coisa: o ficheiro está simplesmente num lugar que o servidor publica, e um único pedido GET comum descarrega-o. Este artigo explica como isso acontece — erros de raiz documental, alojamentos estáticos que servem o próprio repositório, artefactos de compilação que ninguém auditou —, o que quem o encontra faz com as chaves na primeira hora, e porque apagar o ficheiro depois é a parte mais pequena da resposta. Para verificar já o seu próprio site, execute o scanner de segredos vazados e leia com os seus resultados.
Como um ficheiro privado se torna público: a raiz documental
Cada servidor web tem uma raiz documental: o diretório cujo conteúdo é público por definição. Tudo o que é colocado dentro dele — de propósito ou por acidente — pode ser pedido por URL, quer alguma página ligue para ele ou não. O acidente clássico é um projeto implementado copiando todo o diretório de trabalho para o servidor: o código da aplicação, que pertence ali, chega junto com o ficheiro .env ao seu lado, a pasta .git dentro dele, as cópias de editor, o despejo de base de dados que alguém fez antes da migração e o arquivo da versão do mês passado. O servidor não distingue umas coisas das outras. Serve ficheiros; os privados também são ficheiros.
As convenções das frameworks tornam fácil cair na armadilha. Um ficheiro .env devia estar um nível acima da raiz documental, ou totalmente fora da árvore implementada, com a aplicação a lê-lo do disco — nunca através do servidor web. Mas os servidores de desenvolvimento servem de bom grado a raiz do projeto, as implementações pequenas arrastam tudo para public_html, e uma configuração copiada de um tutorial pode apontar a raiz documental para o próprio projeto. Nada se parte visivelmente quando isto acontece, e esse é exatamente o problema: o site funciona perfeitamente, o ficheiro é público, e o primeiro a reparar é quem pede /.env — um pedido que os scanners automatizados fazem contra cada site da internet, sem parar.
Alojamentos estáticos, repositórios servidos e artefactos de compilação
O alojamento estático retira a configuração do servidor da equação e substitui-a por uma regra mais simples: o que estiver no diretório de publicação é publicado. Implemente um repositório num alojamento estático com o diretório de saída posto na raiz do projeto e o alojamento servirá fielmente o repositório — .git incluído, se foi copiado para a saída. Um .git exposto é pior do que parece: o ficheiro HEAD e a configuração provam a estrutura, os ficheiros de objetos contêm cada blob alguma vez confirmado, e com as ferramentas Git comuns todo o histórico pode ser reconstruído — incluindo segredos confirmados uma vez e «apagados» numa confirmação posterior, o que os retira da árvore de trabalho e de mais lado nenhum.
Os artefactos de compilação criam uma segunda classe de exposição, mais silenciosa. Os empacotadores de JavaScript embutem o que o código referencia, por isso uma chave de API lida de uma variável de ambiente em tempo de compilação pode acabar como uma cadeia literal dentro do pacote enviado — público por desenho, legível por cada visitante, e nunca assinalado por nenhuma verificação de permissões, porque esse ficheiro devia mesmo ser público. Os mapas de fontes agravam-no ao enviar o código original ao lado do pacote. Nada disto precisa de um servidor mal configurado; só precisa de uma compilação que nunca foi inspecionada de fora.
O terceiro padrão é o resto esquecido: scripts de implementação que descompactam um arquivo na raiz web e deixam o arquivo lá, plugins de cópia que escrevem despejos numa pasta acessível por web, um config.php.bak guardado por um editor — que muitos servidores servem como texto simples precisamente porque a extensão já não corresponde ao processador PHP. Cada resto é uma cópia completa de algo privado, num endereço previsível.
O que os atacantes fazem na primeira hora
A descoberta é automatizada e constante. Os scanners enumeram os caminhos conhecidos — ficheiros env, interiores do Git, nomes de configuração, extensões de cópia — em intervalos enormes de endereços, e uma exposição fresca costuma ser encontrada em horas, muitas vezes antes. O que chega ao seu servidor é um pedido GET banal que devolve 200; não há alarme, porque da perspetiva do servidor nada de invulgar aconteceu. Assuma, portanto, que qualquer ficheiro que foi público durante um dia foi descarregado, e que o ónus da prova corre ao contrário.
A triagem também é automatizada. Um .env descarregado é analisado em segundos: as credenciais de base de dados são testadas contra qualquer porta alcançável, as chaves de nuvem são validadas com uma chamada inofensiva que diz se estão vivas, as credenciais de correio são testadas para enviar, e as chaves de pagamento são verificadas pelo seu modo — uma chave de pagamento em modo real e credenciais de produção são o prémio maior, porque cada uma se converte diretamente em dinheiro ou em dados. As chaves válidas são usadas, negociadas ou guardadas depressa, porque os seus donos podem rodá-las a qualquer momento; a primeira hora é quando uma chave exposta vale mais, e é gasta com eficiência.
Porque apagar o ficheiro não chega
Apagar o ficheiro para os novos downloads. Não faz nada pelas cópias que já existem: a de quem o encontrou, obviamente, mas também as que você fez — a resposta guardada pela sua CDN ou por um proxy empresarial, o instantâneo no rastreio de um motor de busca ou de um serviço de arquivo, o pacote que um navegador já descarregou. Até cada cache ser limpa e expirar, o ficheiro «apagado» pode continuar a ser servido por infraestrutura que controla mas esqueceu de limpar, e a versão fora do seu controlo está fora dele para sempre.
É por isso que a primeira resposta a uma exposição confirmada é rodar, não apagar: revogue a credencial exposta e emita uma nova, para que cada cópia no mundo perca o valor no mesmo momento. Rodar tem uma ordem — emitir a substituta, implementá-la, verificar que o serviço funciona e só depois revogar a credencial antiga — e estende-se a tudo o que o material exposto pode abrir: uma exposição de .git significa rodar cada segredo que alguma vez apareceu no histórico, não apenas os atuais, porque o que foi divulgado é o histórico. Depois, leia os seus registos de acesso para os caminhos expostos: dizem-lhe se foi o primeiro a saber, e as obtenções anteriores transformam um incidente de configuração numa investigação de violação com uma lista muito diferente.
A lista de sondagem, explicada — e a lista de prevenção
Um scanner como o scanner de segredos vazados só pode pedir ficheiros pelo nome, por isso a sua lista é o conjunto conhecido: /.env e as suas variantes de ambiente, /.git/HEAD e /.git/config, nomes familiares de configuração, extensões de cópia e de arquivo, e nomes de ficheiros de chaves — mais os próprios scripts da página, procurados por cadeias com forma de chave. O limite honesto corta nos dois sentidos: um scanner só encontra o que pede, e é por isso que confirma um achado pelo conteúdo, não pelo código de estado. Um 200 que devolve a sua página inicial é uma rota apanha-tudo, não um vazamento, e qualquer relatório que o conte como tal está a inflacionar-se. O risco de cadeia de fornecimento relacionado — os scripts que carrega deliberadamente de outros — é tratado em scripts de terceiros e risco de cadeia de fornecimento.
Prevenir é sobretudo colocação e uma camada de recusa. Mantenha os segredos fora da raiz documental e fora da saída de publicação do repositório; faça o servidor recusar os nomes perigosos mesmo que aterrem lá — regras de negação para ficheiros com ponto, extensões env e de configuração, arquivos e material de chaves, testadas pedindo-os —; retire o .git dos artefactos de implementação ou bloqueie-o de imediato. Na canalização, adicione análise de segredos na CI — nas confirmações, para que uma chave seja parada antes de ser enviada, e no artefacto construído, para que uma chave empacotada seja apanhada na saída e não por um estranho. Por fim, analise você mesmo com regularidade e após cada alteração de implementação: as exposições deste artigo são todas silenciosas, e a única maneira de saber da sua antes de outra pessoa é fazer ao seu próprio servidor as mesmas perguntas que os scanners fazem.