Sobre a remoção de dados confidenciais de um repositório
Ao alterar o histórico do seu repositório usando ferramentas como git filter-repo
ou o BFG Repo-Cleaner, é crucial entender as implicações, especialmente em relação com solicitações pull request abertas e dados confidenciais.
A ferramenta git filter-repo
e o BFG Repo-Cleaner reescrevem o histórico do repositório, o que altera os SHAs dos commits existentes alterados por você e todos os commits dependentes. Os SHAs de commits alterados podem afetar as solicitações de pull abertas no repositório. Recomendamos mesclar ou fechar todas as solicitações de pull abertas antes de remover arquivos do repositório.
Você pode remover o arquivo do último commit com git rm
. Para saber mais sobre como remover um arquivo adicionado com o commit mais recente, confira "Sobre arquivos grandes no GitHub".
Sobre a exposição de dados confidenciais
Este artigo explica como fazer commits com os dados confidenciais inacessíveis por meio de qualquer branch ou tag do seu repositório em GitHub.com. No entanto, esses commits ainda podem ser acessados em outro lugar:
- Em quaisquer clones ou forks do seu repositório
- Diretamente por meio de seus hashes SHA-1 em exibições em cache em GitHub
- Por meio de pull requests que façam referência
Não é possível remover dados confidenciais dos clones de outros usuários do seu repositório, mas é possível remover permanentemente as exibições e as referências em cache aos dados confidenciais nas solicitações de pull do GitHub entrando em contato com o conosco por meio do Portal de suporte do GitHub.
Important
O Suporte do GitHub não remove dados não confidenciais e só ajuda na remoção de dados confidenciais nos casos em que determinarmos que o risco não pode ser mitigado pela rotação das credenciais afetadas.
Depois de efetuar push de um commit para o GitHub, você deverá considerar todos os dados confidenciais no commit comprometido. Se você tiver feito commit de uma senha, deverá alterá-la. Se tiver feito commit de uma chave, gere outra.
Se a confirmação que introduziu os dados confidenciais existir em qualquer fork, ela continuará acessível lá. Você precisará coordenar com os proprietários dos forks, pedindo-lhes para remover os dados confidenciais ou excluir o fork completamente. GitHub não é capaz de fornecer informações de contato para esses proprietários.
Considere essas limitações e desafios ao tomar a decisão de reescrever a história do repositório.
Remover um arquivo do histórico do repositório
Você pode limpar um arquivo do histórico do repositório usando a ferramenta git filter-repo
ou a ferramenta de código aberto BFG Repo-Cleaner.
Note
Se dados confidenciais estiverem localizados em um arquivo identificado como binário, você precisará remover o arquivo do histórico, pois não é possível modificá-lo para remover ou substituir os dados.
Usar o BFG
O BFG Repo-Cleaner é uma ferramenta criada e mantida pela comunidade de código aberto. Ele fornece uma alternativa mais rápida e simples ao git filter-repo
para remover dados indesejados.
Por exemplo: para remover o arquivo com dados confidenciais sem alterar o commit mais recente, execute:
bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA
Para substituir todo o texto listado em passwords.txt
em todas as ocorrências no histórico do repositório, execute:
bfg --replace-text passwords.txt
Depois que os dados confidenciais são removidos, você deve fazer push forçado das suas alterações para GitHub. Fazer push forçado reescreve o histórico do repositório, o que remove dados confidenciais do histórico de commit. Se você fizer push forçado, isso poderá pode sobrescrever commits nos quais outras pessoas basearam o seu trabalho.
git push --force
Confira a documentação do BFG Repo-Cleaner para obter instruções completas de uso e download.
Usando arquivo git filter-repo
Warning
Ao executar git filter-repo
após o stash das alterações, você não poderá recuperar as alterações com outros comandos stash. Antes de executar git filter-repo
, é recomendado cancelar o stash das alterações feitas. Para cancelar o stash do último conjunto de alterações com stash, execute git stash show -p | git apply -R
. Para obter mais informações, confira Ferramentas do Git – Stash e limpeza.
Para ilustrar como o git filter-repo
funciona, mostraremos como remover o arquivo que contém dados confidenciais do histórico do repositório e adicioná-lo ao .gitignore
para garantir que ele não sofra um novo commit acidental.
-
Instale a última versão da ferramenta git filter-repo. Você pode instalar o
git-filter-repo
manualmente ou usando um gerenciador de pacotes. Por exemplo, para instalar a ferramenta com HomeBrew, use o comandobrew install
.brew install git-filter-repo
Para obter mais informações, confira INSTALL.md no repositório
newren/git-filter-repo
. -
Se você ainda não tem uma cópia local do repositório que contém dados confidenciais no histórico, clone o repositório no computador local.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY > Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/ > remote: Counting objects: 1301, done. > remote: Compressing objects: 100% (769/769), done. > remote: Total 1301 (delta 724), reused 910 (delta 522) > Receiving objects: 100% (1301/1301), 164.39 KiB, done. > Resolving deltas: 100% (724/724), done.
-
Navegue até o diretório de trabalho do repositório.
cd YOUR-REPOSITORY
-
Execute o comando a seguir, substituindo
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
pelo caminho para o arquivo que deseja remover, não apenas o nome do arquivo. Esses argumentos vão:-
Forçar o Git a processar todo o histórico de cada branch e marca, mas não fazer check-out
-
Remover o arquivo especificado, bem como todos os commits vazios gerados como resultado
-
Remova algumas configurações, como a URL remota, armazenada no arquivo .git/config. É interessante fazer backup desse arquivo antes para que ele possa ser restaurado mais tarde.
-
Substituir as marcas existentes
$ git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA Parsed 197 commits New history written in 0.11 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects Enumerating objects: 210, done. Counting objects: 100% (210/210), done. Delta compression using up to 12 threads Compressing objects: 100% (127/127), done. Writing objects: 100% (210/210), done. Building bitmaps: 100% (48/48), done. Total 210 (delta 98), reused 144 (delta 75), pack-reused 0 Completely finished after 0.64 seconds.
Important
Se o arquivo que contém dados confidenciais existia em algum outro caminho (porque foi movido ou renomeado), você também precisa executar esse comando nesses caminhos.
-
-
Adicione o arquivo que contém dados confidenciais ao
.gitignore
para garantir que ele não sofra um novo commit acidental.$ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore $ git add .gitignore $ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore" > [main 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore > 1 files changed, 1 insertions(+), 0 deletions(-)
-
Verifique se você removeu tudo o que queria do histórico do repositório e se foi feito check-out de todos os branches.
-
A ferramenta
git filter-repo
removerá automaticamente os itens remotos configurados. Use o comandogit remote set-url
para restaurar seus itens remotos, substituindoOWNER
eREPO
pelos detalhes de seu repositório. Para obter mais informações, confira "Gerenciar repositórios remote".git remote add origin https://github.com/OWNER/REPOSITORY.git
-
Quando estiver satisfeito com o estado de seu repositório e tiver definido o item remoto apropriado, execute o envio por push forçado das alterações locais para substituir seu repositório em GitHub.com, bem como todas as ramificações que você enviou por push. É necessário um push forçado para remover dados confidenciais do seu histórico de commit.
$ git push origin --force --all > Counting objects: 1074, done. > Delta compression using 2 threads. > Compressing objects: 100% (677/677), done. > Writing objects: 100% (1058/1058), 148.85 KiB, done. > Total 1058 (delta 590), reused 602 (delta 378) > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git > + 48dc599...051452f main -> main (forced update)
-
Para remover o arquivo confidencial das versões marcadas, você também precisará forçar o push das marcas do Git:
$ git push origin --force --tags > Counting objects: 321, done. > Delta compression using up to 8 threads. > Compressing objects: 100% (166/166), done. > Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done. > Total 321 (delta 124), reused 269 (delta 108) > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git > + 48dc599...051452f main -> main (forced update)
Remover completamente os dados de GitHub
Depois de usar a ferramenta BFG ou git filter-repo
para remover os dados confidenciais e efetuar push das alterações para o GitHub, você precisa executar mais algumas etapas para remover por completo os dados do GitHub.
-
Entre em contato com o conosco por meio do Portal de suporte do GitHub e solicite a remoção de exibições em cache e referências aos dados confidenciais em solicitações de pull no GitHub. Forneça o nome do repositório e/ou um link para o commit que você precisa remover.
Important
O Suporte do GitHub não remove dados não confidenciais e só ajuda na remoção de dados confidenciais nos casos em que determinarmos que o risco não pode ser mitigado pela rotação das credenciais afetadas.
-
Diga aos colaboradores para trocar a base (não fazer a mesclagem) dos branches que eles criaram fora do histórico do repositório antigo (afetado). Um commit de merge poderia reintroduzir o histórico antigo completo (ou parte dele) que você acabou de se dar ao trabalho de corrigir.
-
Se você usou o
git filter-repo
, pode pular esta etapa.Se você usou a ferramenta BFG, após reescrever, poderá limpar as referências em seu repositório local para o histórico antigo a ser desreferenciado e lixo coletado com os seguintes comandos (usando o Git 1.8.5 ou mais recente):
$ git reflog expire --expire=now --all $ git gc --prune=now > Counting objects: 2437, done. > Delta compression using up to 4 threads. > Compressing objects: 100% (1378/1378), done. > Writing objects: 100% (2437/2437), done. > Total 2437 (delta 1461), reused 1802 (delta 1048)
Note
Faça isso também enviando por push o histórico filtrado para um repositório novo ou vazio e fazendo um clone novo do GitHub.
Evitar commits acidentais no futuro
Impedir que colaboradores façam commits acidentais pode ajudar a evitar que informações confidenciais sejam expostas. Para obter mais informações, confira "Melhores práticas para evitar vazamentos de dados na sua organização".
Há alguns truques simples para evitar fazer commit de coisas não desejadas:
- Use um programa visual como o GitHub Desktop ou o gitk para fazer commit das alterações. Nos programas visuais, geralmente é mais fácil ver exatamente quais arquivos serão adicionados, excluídos e modificados em cada commit.
- Evite os comandos catch-all
git add .
egit commit -a
na linha de comando: usegit add filename
egit rm filename
para preparar os arquivos individualmente. - Use
git add --interactive
para revisar e preparar alterações individualmente em cada arquivo. - Use
git diff --cached
para revisar as alterações que você preparou para commit. Essa é a comparação exata quegit commit
produzirá, desde que você não use o sinalizador-a
. - Habilite a proteção por push para seu repositório para detectar e impedir que envios por push contendo segredos codificados sejam confirmados na sua base de código. Para obter mais informações, confira "Sobre a proteção por push".