Skip to main content

Удаление конфиденциальных данных из репозитория

При фиксации конфиденциальных данных в репозиторий Git его можно удалить из журнала.

Удаление конфиденциальных данных из репозитория

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

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

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

Сведения о воздействии конфиденциальных данных

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

  • В любых клонах или вилках репозитория
  • Непосредственно через хэши SHA-1 в кэшированных представлениях на GitHub
  • Через все запросы на вытягивание, ссылающиеся на них

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

Important

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

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

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

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

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

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

Note

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

Использование 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

Warning

При выполнении 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.
      

      Important

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

  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. Средство git filter-repo автоматически удаляет настроенные удаленные приложения. git remote set-url Используйте команду для восстановления удаленных данных, замены OWNER и REPO сведений о репозитории. Дополнительные сведения см. в разделе Управление удаленными репозиториями.

    git remote add origin https://github.com/OWNER/REPOSITORY.git
    
  8. После того как вы удовлетворены состоянием репозитория, и вы настроили соответствующие удаленные, принудительно отправьте локальные изменения, чтобы перезаписать репозиторий на 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)
    
  9. Чтобы удалить конфиденциальный файл из выпусков с тегами, потребуется также выполнить принудительную отправку в теги 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. Обратитесь к us через портал поддержки GitHub, а затем попросите удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание GitHub. Укажите имя репозитория и (или) ссылку на фиксацию, необходимую вам.

    Important

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

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

  3. Если вы использовали git filter-repo, этот шаг можно пропустить.

    Если вы использовали средство BFG после перезаписи, вы можете очистить ссылки в локальном репозитории в старом журнале, чтобы быть разыменовываемой и сборкой мусора со следующими командами (с помощью Git 1.8.5 или более поздней версии):

    $ 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

    Вы также можете добиться этого, переместив отфильтрованный журнал в новый или пустой репозиторий, а затем создав свежий клон из 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.
  • Включите защиту push-уведомлений для репозитория, чтобы обнаруживать и предотвращать отправки, содержащие жестко закодированные секреты, не фиксируются в базе кода. Дополнительные сведения см. в разделе Сведения о защите push-уведомлений.

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