如何删除GIT仓库中的敏感信息

如何删除GIT仓库中的敏感信息

正常 Git 仓库中应该尽量不包含数据库连接/AWS帐号/巨大二进制文件,否则一旦泄漏到 Github ,这些非常敏感信息会影响客户的信息安全已经公司的信誉。公司可能其它还有相关规定,如禁止私人邮件加入GIT仓库。如果违反这些规定,可能会面临辞退、高额罚款、或牢狱之灾等非常严厉的惩罚。

由于 Git 的正常操作流程,导致敏感信息一旦进入主分支,再怎么在新的 Pull Request 中删除,也无能为力了。其它人都能在历史记录中查询到历史记录中的配置。所以这要求对 Git 的签名和签入、推送要有高度的敬畏之心。

然而根据 墨菲定律 ,可能发生的事情 一定会发生 。时不时,故意或失手,就会有人将这些信息写到了 Git 仓库中。如果代码还没有上传( git push ),那可能还好说,只要将分支删除,然后重新写一下功能即可。但如果已经上传了,或功能太多太复制没办法及时删除,就会后悔莫及了。

这里我将演示一个故意写满“敏感信息”的 Github 仓库,然后一步一步演示怎么在历史记录中,删除“敏感信息”,以完成“脱敏”。

仓库需处理的问题说明:

敏感源 敏感原因 处理方法
sdflysha@qq.com 个人邮箱签入公司项目 替换为“公司”邮箱:sdflysha@starworks.cc
文件Program.cs AWS Key保存在文件 替换将AWS Key为:REPLACED
文件appsettings.Production.json 生产环境配置文件 删除
文件夹userSecrets 敏感信息文件夹 删除
Program.exe 大二进制文件签入 删除

这个演示满载“敏感”信息的代码仓库,可以从:https://github.com/sdcb/sensitive-repo-demo 这里下载。

“敏感”信息演示:

  • 个人邮箱签入“公司”项目,可以通过 gitk 命令看到:

  • AWS Key配置写在代码中(见 Program.cs ):

    string awsAccessKey = "pwiCZSMCIcM6+q+h";
      string awsSecretKey = "861YUaeCHqzaS5OX+OmAK1XD37kmQhA2";
      Console.WriteLine("Hello, I Switched to correct email!");
  • 生产环境配置文件(见 appsettings.Production.json ):

    {
          "ConnectionString": "Data Source=production-db.starworks.cc,32768; User Id=sensitive_user; Password=MyVeryVerlyStr0ngPassw0rd!; Initial Catalog=ProductionDB; app=Program1"
      }
  • 敏感信息文件夹(见 userSecrets 文件夹)
  • 大二进制文件(见 bin\Program.exe

从以上敏感信息的诚意,可见小编( 周杰的DotNet骚操作 )为了写这遍文章已经拼了:joy:。

如何删除敏感信息

前置条件

必须先切换到主分支(一般为 master ),然后获取最新代码再进行操作:

git checkout master
git pull

如果有任何修改的对象,都会阻止提交,因此必须先签入所有未提交的本地修改。

git filter-branch ——删除邮箱/用户名

该命令用于解决将个人邮箱/个人用户名签入公司项目。

该命令是 Git 客户端内置的,不用下载。

bfg ——删除其它信息

bfg ( BFG Repo-Cleaner )是个强大的工具,有如下功能:

  • 用于删除文件内敏感信息(不删文件)
  • 删除敏感文件
  • 删除敏感文件夹
  • 删除大二进制文件。

bfg 基于Java,安装很繁琐,但通过 choco 命令,可以快速进行安装:

  1. 先在命令提示符( cmd )下执行如下脚本,安装 choco ( Chocolatey ):

    @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
  2. 再使用 choco 命令安装 bfg 工具( 需要管理员权限 ):

    choco install bfg-repo-cleaner

    期间,它会自动下载 JRE 等组件,执行效果如下(需要按多次 Y / Yes ):

    重点:执行此命令需要以 管理员权限 运行 cmd

执行命令,删除敏感信息

删除个人邮箱签入“公司”项目

执行如下命令即可:

git filter-branch --env-filter '
    OLD_EMAIL="sdflysha@qq.com"
    CORRECT_NAME="sdflysha"
    CORRECT_EMAIL="sdflysha@starworks.com"

    if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
    then
        export GIT_COMMITTER_NAME="$CORRECT_NAME"
        export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
    fi
    
    if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
    then
        export GIT_AUTHOR_NAME="$CORRECT_NAME"
        export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
    fi
' --tag-name-filter cat -- --branches --tags

重点:

  • 将上述脚本中的 OLD_EMAILsdflysha@qq.com 替换为你的私人(错误)邮箱;
  • CORRECT_NAMECORRECT_EMAIL 换成你的公司(正确)邮箱;
  • 该命令不能在命令提示符( cmd )中运行,因为 cmd 不支持换行命令,否则会出现如下错误:

如果执行正常,将会出现:

此时,运行gitk命令将看到:

可见,所有“私人邮箱” sdflysha@qq.com 都正确地替换成为了“公司邮箱” sdflysha@starworks.cc 了。

替换文件中的敏感信息(不删除文件)

命令:

bfg --replace-text "C:\Users\sdfly\Desktop\to-be-replaced.txt" --no-blob-protection

其中 to-be-replaced.txt 格式如下:

pwiCZSMCIcM6+q+h==>REPLACED
861YUaeCHqzaS5OX+OmAK1XD37kmQhA2==>REPLACED

其中左边是需要替换的值(这里为AWS相关的key),右边为替换之后的值。

命令执行后,可以运行 gitk ,可以看到 历史记录 中,东西真的被替换了:

删除敏感文件

命令:

bfg --delete-files appsettings.Production.json --no-blob-protection

将其中 appsettings.Production.json 文件替换成你的文件名即可。

注意:删除文件不能带路径名,只能匹配文件本身。

删除敏感文件夹

命令:

bfg --delete-folders userSecrets --no-blob-protection

userSecrets 文件夹替换成你的敏感文件夹即可。

删除二进制大文件

命令:

git gc
bfg --strip-blobs-bigger-than 150K --no-blob-protection

150K 换成你的二进制文件大小即可。

注意:删除大二进制文件前,运行 git gc 命令是 必须 的,否则会报这个错:

Warning : no large blobs matching criteria found in packfiles - does the repo need to be packed?`

关于 --no-blob-protection

--no-blob-protection 是指将历史中删除的记录,放到最新一次未签入的修改中:

PS C:\Users\sdfly\Desktop\sensitive-repo-demo> git status
On branch master
Your branch and 'origin/master' have diverged,
and have 9 and 9 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   Program.cs
        new file:   appsettings.Production.json
        new file:   bin/Program.exe
        deleted:    bin/Program.exe.REMOVED.git-id
        new file:   userSecrets/admin-password.json
        new file:   userSecrets/user-password.json

这些都是敏感信息或者大文件,根据你的实际情况,可以先备份一下,然后删除:

git reset --hard

推送到远程/其他人获取代码

此时可以通过:

git push --set-upstream origin master --force

来推送到远程以完成(该命令可能需要你的上级帮你执行,或临时开个权限)。

注意,简单地执行 git push (不带 --force )是无法推送的,此时会报如下错误:

组内其它成员则可以删除原先的主分支,然后重新拉一个主分支:

git fetch origin
git checkout -b temp-branch
git branch -D master
git checkout origin/master
git checkout -b master

最后的效果

(已脱密) https://github.com/sdcb/sensitive-repo-demo/tree/cleaned

对比:

(原版) https://github.com/sdcb/sensitive-repo-demo

总结

我们签入 Git 时应该小心谨慎,但一旦出现问题,只要引起重视,也是可以尽早补救的。上述这些命令可能会中断其它组员的工作,因此一旦出现问题应该尽早汇报给上级,大概率需要上级来配合来恢复 Git 的使用。

当然,提高信息安全意识才是最重要的,事后诸葛亮是费力不讨好。希望各位提高警惕,不要在 Git 的使用中翻车。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章