• Время чтения ~2 мин
  • 10.04.2023

При фиксации конфиденциальных данных, таких как пароль или ключ SSH, в репозиторий Git, его можно удалить из журнала. Чтобы полностью удалить ненужные файлы из журнала репозитория, можно использовать средство git filter-repo или инструмент с открытым кодом BFG Repo-Cleaner.

Средство git filter-repo и BFG Repo-Cleaner перезаписывают журнал репозитория, что меняет агенты работоспособности системы для существующих фиксаций, которые вы изменяете, и всех зависимых фиксаций. Измененные агенты работоспособности системы фиксации могут затронуть открытые запросы на вытягивание в репозитории. Перед удалением файлов из репозитория рекомендуется объединить или закрыть все открытые запросы на вытягивание.

Файл можно удалить из последней фиксации с помощью git rm. Сведения об удалении файла, добавленного с последней фиксацией, см. в разделе Сведения о больших файлах на GitHub.

Предупреждение. В этой статье описывается, как сделать фиксации с конфиденциальными данными недоступными из любых ветвей или тегов в репозитории в GitHub.com. Однако эти фиксации по-прежнему могут быть доступны в любых клонах или вилках репозитория непосредственно через хэши SHA-1 в кэшированных представлениях в GitHub, а также через любые запросы на вытягивание, ссылающиеся на них. Вы не можете удалить конфиденциальные данные из клонов репозитория других пользователей, но вы можете окончательно удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание в GitHub, обратившись к Поддержка GitHub.

Если фиксация, которая ввела конфиденциальные данные, существует в любых вилках репозитория, она будет по-прежнему доступна, если только владелец вилки не удалит конфиденциальные данные из вилки или полностью удалит вилку.

После отправки фиксации в GitHub любые конфиденциальные данные в фиксации следует рассматривать как скомпрометированные. Если вы зафиксировали пароль, его следует изменить. Если вы зафиксировали ключ, создайте новый ключ. Удаление скомпрометированных данных не устраняет начальную уязвимость, особенно в существующих клонах или вилках репозитория.

Учитывайте эти ограничения при принятии решения переписать журнал репозитория.

Очистка файла из журнала репозитория

Вы можете очистить файл из журнала репозитория с помощью средства git filter-repo или средства BFG Repo-Cleaner с открытым исходным кодом.

Использование BFG

BFG Repo-Cleaner — это инструмент, созданный и обслуживаемый сообществом разработчиков открытого кода. Он является более быстрой и простой альтернативой git filter-repo для удаления нежелательных данных.

Чтобы удалить файл с конфиденциальными данными и оставить последнюю фиксацию без изменений, выполните следующую команду:

$ bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Чтобы заменить все вхождения текста, представленного в passwords.txt, в журнале репозитория, выполните:

$ bfg --replace-text passwords.txt

После удаления конфиденциальных данных необходимо принудительно отправить изменения в GitHub. В этом случае выполняется перезапись журнала репозитория, в результате которой конфиденциальные данные удаляются из журнала фиксации. При принудительной отправке могут быть перезаписаны фиксации, над которыми работают другие пользователи.

$ git push --force

Полные инструкции по использованию и загрузке см. в документации по BFG Repo-Cleaner.

Использование git filter-repo

Внимание! При выполнении git filter-repo после того, как вы спрятали изменения, вы не сможете получить изменения с помощью других команд для скрытия. Перед выполнением git filter-repo рекомендуется показать все внесенные изменения. Чтобы показать последний набор спрятанных изменений, выполните команду git stash show -p | git apply -R. Дополнительные сведения см. в разделе Средства Git — скрытие и очистка.

Чтобы продемонстрировать, как работает git filter-repo, мы покажем, как удалить файл с конфиденциальными данными из журнала репозитория, добавить его в .gitignore и убедиться, что он не был случайно зафиксирован повторно.

  1. Установите последнюю версию средства git filter-repo. Можно установить git-filter-repo вручную или с помощью диспетчера пакетов. Например, чтобы установить средство с помощью HomeBrew, используйте команду brew install.

    brew install git-filter-repo
    

    Дополнительные сведения см. в файле INSTALL.md в репозитории newren/git-filter-repo.

  2. Если у вас еще нет локальной копии репозитория с конфиденциальными данными в журнале, клонируйте репозиторий на локальный компьютер.

    $ 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.
  3. Перейдите в рабочую папку репозитория.

    $ cd YOUR-REPOSITORY
  4. Выполните следующую команду, заменив PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA путем к файлу, который необходимо удалить, а не только именем файла. Эти аргументы:

    • заставят Git обработать, но не извлечь весь журнал каждой ветви и тега;
    • удалить указанный файл, а также все пустые фиксации, сформированные в результате;
    • удалить некоторые конфигурации, например удаленный URL-адрес, хранящийся в файле .git/config. Возможно, потребуется заранее выполнить резервное копирование этого файла для последующего восстановления.
    • Перезапись существующих тегов
      $ 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.

    Примечание. Если файл с конфиденциальными данными существовал в других путях (в результате перемещения или переименования), необходимо также выполнить данную команду для этих путей.

  5. Добавьте файл с конфиденциальными данными в .gitignore, чтобы предотвратить случайную фиксацию.

    $ 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(-)
  6. Внимательно проверьте, удалили ли вы все, что требуется, из журнала репозитория и все ли ветви извлечены.

  7. Когда вы будете довольны состоянием репозитория, принудительно отправьте локальные изменения, чтобы перезаписать репозиторий в GitHub.com, а также во всех ветвях, которые вы добавили. Для удаления конфиденциальных данных из журнала фиксаций требуется принудительная отправка.

    $ 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)
  8. Чтобы удалить конфиденциальный файл из выпусков с тегами, потребуется также выполнить принудительную отправку в теги 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)

Полное удаление данных с сайта GitHub

После удаления конфиденциальных данных с помощью средства BFG или git filter-repo и отправки изменений в GitHub необходимо выполнить ряд действий, чтобы полностью удалить данные из GitHub.

  1. Обратитесь в Поддержка GitHub с просьбой удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание в GitHub. Укажите имя репозитория и (или) ссылку на фиксацию, необходимую для удаления.

  2. Сообщите участникам совместной работы о необходимости переместить изменения из одной ветви в другую и не объединять, какие-либо ветви, созданные из старого (испорченного) журнала репозитория. Одна фиксация слияния может снова вернуть некоторые или все испорченные журналы, которые вам только что пришлось очистить.

  3. Через некоторое время, когда вы уверены, что в работе средства BFG/git filter-repo не было непредвиденных побочных эффектов, можно принудительно разыменовывать все объекты в локальном репозитории и собрать мусор с помощью следующих команд (в Git 1.8.5 или более поздней версии):

    $ git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
    $ 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)

    Примечание: Для этого можно также отправить отфильтрованный журнал в новый или пустой репозиторий, а затем сделать новый клон из GitHub.

Предотвращение случайных фиксаций в будущем

Существует несколько простых приемов, позволяющих избежать фиксации данных, которые не хотите фиксировать:

  • Используйте для фиксации изменений визуальную программу, такую как GitHub Desktop или gitk. Как правило, визуальные программы упрощают просмотр файлов, которые будут добавляться, удаляться и изменяться при каждой фиксации.
  • Избегайте использования в командной строе команд catch-all git add . и git commit -a — используйте git add filename и git rm filename, чтобы подготовить каждый файл по отдельности.
  • Используйте git add --interactive для проверки и подготовки каждого отдельного изменения в каждом файле.
  • Используйте git diff --cached для проверки изменений, подготовленных для фиксации. Это точное несовпадение, которое git commit будет производить до тех пор, пока вы не используете флаг -a.

Дополнительные материалы

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297