# Pasta .git pública: uma fuga de dados subestimada

> A sua pasta .git é pública? Como verificar, bloquear o acesso, reestruturar o deployment e tratar as credenciais presentes no histórico.

Fonte: https://phpsos.de/pt/blog/git-ordner-oeffentlich/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Uma pasta .git pública surge quando um site é implementado com `git clone` ou `git pull` diretamente no webroot e o servidor web não bloqueia as pastas ocultas. Então é possível obter todo o código-fonte com o histórico de versões, incluindo credenciais submetidas há muito tempo. Verifique os seus domínios com uma simples chamada, bloqueie o acesso de imediato, passe o deployment para pacotes sem `.git` e substitua as credenciais presentes no histórico.

## O código-fonte para levar

O Git é a ferramenta padrão de controlo de versões e, para equipas pequenas, é natural usá-lo também para implementar: ligar ao servidor, `git pull`, pronto. Funciona de forma fiável e é rápido. Mas tem um efeito secundário que muitas vezes ninguém repara.

Na pasta do projeto existe uma pasta oculta `.git`. Contém não só o estado atual, mas cada ficheiro em cada versão que alguma vez foi submetida, além de mensagens de commit, nomes e endereços de correio eletrónico dos programadores e referências a servidores. Se esta pasta estiver no webroot e o servidor web a servir, qualquer pessoa a pode obter.

Para os atacantes, é uma prenda. Com o código-fonte podem procurar vulnerabilidades de forma dirigida, em vez de as adivinhar do exterior. E no histórico encontram-se muitas vezes coisas que pareciam apagadas há muito: uma palavra-passe de base de dados do início, uma chave de API, um ficheiro de teste com dados de clientes.

## A sua pasta .git é pública? Como verificar

A verificação demora segundos e não altera nada. Para cada domínio e subdomínio, aceda a um ficheiro que existe em qualquer repositório Git:

```bash
# Esperado: 403 ou 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/config
# No servidor: existem pastas .git abaixo dos webroots?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
```

Um estado 200 significa: a pasta está acessível. Atenção também aos subdiretórios. Por vezes, o repositório não está no próprio webroot, mas numa pasta de plugin ou de tema que é gerida separadamente com o Git.

Verifique ainda os ambientes de staging e de teste. São atualizados com o Git mais vezes do que a produção e estão muitas vezes acessíveis em subdomínios fáceis de adivinhar.

## De imediato: bloquear o acesso

Até o deployment ser reestruturado, uma regra no servidor web bloqueia o acesso às pastas do controlo de versões. Um bloqueio geral de ficheiros ocultos, como descrito em [Proteger corretamente credenciais e ficheiros .env](https://phpsos.de/pt/blog/env-dateien-schuetzen/), cobre isto também. Quem quiser bloquear apenas o controlo de versões usa uma regra mais estreita:

```nginx
location ~ /\.(git|svn|hg)(/|$) {
    return 404;
}
```

```apache
RedirectMatch 404 /\.(git|svn|hg)(/|$)
```

Depois, repita a verificação acima, e com uma chamada real a partir do exterior: um teste de configuração bem-sucedido diz apenas que a sintaxe está certa, não que a regra se aplica antes de outras regras para ficheiros estáticos. Em painéis como o Plesk ou o cPanel, introduza a regra nas diretivas adicionais previstas para o efeito, para que não se perca na próxima geração da configuração.

> **Agir de imediato:**
> Se a pasta esteve acessível, trate todas as credenciais que alguma vez estiveram no repositório como conhecidas. Bloquear, por si só, não basta; os valores têm de ser substituídos.

## De forma duradoura: implementar sem .git no webroot

O bloqueio é uma proteção, não uma solução. A longo prazo, o controlo de versões não pertence ao servidor de produção. Caminhos provados, consoante o seu ambiente:

| Procedimento | Como funciona | Adequado para |
|---|---|---|
| Pacote de build a partir do CI | o pipeline constrói um arquivo sem `.git`, o servidor extrai-o para um novo diretório de release | equipas com CI/CD |
| `git archive` | gera um arquivo de uma versão sem dados de versionamento | projetos pequenos sem pipeline |
| `rsync` com exclusões | transfere apenas os ficheiros necessários | servidores clássicos |
| Imagem de contentor | o código é copiado para a imagem durante a construção, `.git` excluído via `.dockerignore` | operação em contentores |

Um diretório de release por versão, com uma ligação simbólica para o estado atual, tem outra vantagem: em caso de problemas, pode regressar de imediato. Para configurações com contentores, [CI/CD: reconstruir imagens PHP automaticamente](https://phpsos.de/pt/blog/php-images-in-ci-neu-bauen/) descreve como tornar os builds reprodutíveis. Aí deve também verificar-se que o `.git` não chega à imagem.

```bash
# Exemplo: gerar o pacote de uma versão sem dados de versionamento
git archive --format=tar.gz -o release.tar.gz HEAD
```

## Outros ficheiros de projeto que não pertencem ao webroot

A pasta `.git` é o exemplo mais conhecido, mas não o único. Quem implementa diretórios de projeto inteiros leva para o webroot outros ficheiros que lá não têm nada que fazer:

- Pastas de ambientes de desenvolvimento como `.idea` ou `.vscode`, em que as extensões para o upload de ficheiros guardam por vezes endereços de servidores e credenciais.
- `composer.json` e `composer.lock`, que revelam as versões exatas de todas as bibliotecas e facilitam assim a procura de vulnerabilidades conhecidas.
- Configurações para testes, ferramentas de build e pipelines, que revelam nomes de anfitriões e processos internos.
- Resíduos de sistemas operativos como `.DS_Store`, que contêm listas de ficheiros de diretórios inteiros.

A solução é a mesma que para a pasta `.git`: servir apenas o que tem de ser público, idealmente através de uma subpasta própria como webroot. Quem de qualquer modo passa o deployment para pacotes define logo uma lista de ficheiros excluídos e verifica-a a cada nova ferramenta no projeto.

## Se a pasta esteve aberta: verificar o histórico e os registos

Se se verificar que a pasta `.git` esteve acessível, proceda nesta ordem:

1. **Bloquear o acesso** e repetir a verificação.
2. **Pesquisar o histórico** para saber que segredos alguma vez foram submetidos: ficheiros de configuração, `.env`, chaves, dumps de bases de dados.
3. **Substituir as credenciais**, todas as encontradas no passo 2, mesmo que hoje já não estejam no código.
4. **Analisar os registos de acesso** para ver se ficheiros em `/.git/` foram obtidos com o estado 200 e a partir de que endereços. Como fazê-lo é mostrado em [Analisar os registos do servidor web após um ataque](https://phpsos.de/pt/ratgeber/logfiles-auswerten/).
5. **Verificar o código-fonte de forma dirigida**, pois os atacantes conhecem-no agora. As fraquezas conhecidas devem ser corrigidas com prioridade.
6. **Esclarecer a proteção de dados**, se o histórico continha dados pessoais, por exemplo exportações de teste. A avaliação cabe ao seu encarregado da proteção de dados.

Depois, as ferramentas de pesquisa de segredos em repositórios passam a fazer parte permanente do pipeline. A OWASP recomenda expressamente tais verificações, como hook antes da submissão e no CI.

## Como ajuda concretamente a PHP SOS?

- Verificamos todos os seus domínios e subdomínios à procura de pastas de controlo de versões acessíveis.
- Bloqueamos o acesso de imediato e passamos o deployment para pacotes sem dados de versionamento.
- Pesquisamos o histórico à procura de segredos e acompanhamos a substituição dos acessos afetados.
- Analisamos os registos de acesso e documentamos se e quando foram obtidos dados.

Estas medidas fazem parte do nosso [reforço de segurança de servidores para servidores web PHP](https://phpsos.de/pt/leistungen/server-haertung/).


## Perguntas frequentes

**Como surge uma pasta .git pública?**  
Normalmente através de um deployment com git clone ou git pull diretamente no webroot. A pasta .git, com todo o histórico de versões, fica então ao lado do index.php e, sem bloqueio, o servidor web serve os seus ficheiros.

**Basta apagar a pasta .git?**  
Para o futuro, sim; para o passado, não. Se a pasta esteve acessível, o conteúdo pode já ter sido copiado. Deve por isso substituir as credenciais que alguma vez estiveram no repositório.

**Ajuda remover posteriormente as credenciais do histórico do Git?**  
Evita que as novas cópias as contenham. Quem já obteve o repositório continua a ter as versões antigas. Decisiva é por isso a substituição das credenciais, não apenas a reescrita do histórico.

**Isto afeta também outros sistemas de controlo de versões?**  
Sim. Também pastas como .svn ou .hg contêm dados do projeto e nunca devem estar acessíveis no webroot. Um bloqueio geral de ficheiros e pastas com ponto no início cobre todos estes casos.

## Fontes

- [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Documentação do Nginx](https://nginx.org/en/docs/)
- [Apache HTTP Server: documentação](https://httpd.apache.org/docs/)
