[Git] git-secretsでパスワードや機密情報の登録を禁止する

AWSなどのクラウドサービスでは、データベースやファイルシステムなどの各種リソースを操作するためのアカウント(IAM)を発行して権限管理を行うことがありますが、このアカウント情報をGitのリポジトリに登録してしまうと、意図せず流出し悪い人に悪用されてしまう場合があります。

定期的にネット上で話題になりますが、最終的に仮想通貨のマイニングなどに利用され多額の請求がやってくるパターンが多いようです。

このような悲劇を防ぐために、Gitのリポジトリへ特定のパターンの文字列を登録できくなくするgit-secretsを導入してみます。なおこのツールはAmazon製ということもありAWSとの相性がバッチリです。

結論

macOSでAWSのIAMのクレデンシャルをGitのリポジトリに登録したくない場合は以下のようにします。

まずはインストール。

$ brew install git-secrets

Gitのリポジトリに移動し2つコマンドを叩けば完了。たったこれだけで防ぐことができます。

$ cd (Gitのリポジトリ)
$ git secrets --install
$ git secrets --register-aws

注意点としてはプロジェクトの全員がこの設定を行う必要がありますので、開発環境を移行したり新人さんが入ってきた場合はお忘れなきよう。

より詳細な情報が知りたい方はこの先の解説をどうぞ。

インストール

Linux

Gitのリポジトリをcloneした後にmakeを実行します。make時に/usr/local/binの下にファイルがコピーされるためsudoを付けています。

$ git clone https://github.com/awslabs/git-secrets.git
$ cd git-secrets
$ sudo make install

Makefileを読むと実際にインストールされるのは本体であるBashのプログラムと、mangit helpで表示するためのドキュメントの2つのファイルがコピーされるだけのシンプルな構成のようです。

macOS

HomeBrewで一発です。簡単ですね。

$ brew install git-secrets

macの場合もLinuxと同じ挙動になるようです。git-secretsの中身は先ほどと同じBashです。

$ which git-secrets
/usr/local/bin/git-secrets

Windows

Linuxのときと同様にGitのリポジトリhttps://github.com/awslabs/git-secrets.gitをcloneした後にPowerShellを起動しインストールを行います。

ただしWindowsの設定がデフォルトのままだとセキュリティに引っかかってしまいインストール用のスクリプトが起動しません。そのため最初に設定をゆるくします。以下のコマンドを実行すると本当に実行して良いか聞かれるので「Y」を入力。

PS C:\Users\katsube> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process

あとはcloneしたリポジトリへ移動し install.ps1 を実行すれば完了です。

PS C:\Users\katsube> cd Documents\git-secrets
PS C:\Users\katsube\Documents\git-secrets> .¥install.ps1

PowerShellを閉じると先ほどゆるくしたセキュリティの設定はもとの厳しい状態に戻っています。

このあたりの設定は以下のページを参考にさせていただきました。 qiita.com

Gitリポジトリに設定する

初期設定

適当なディレクトリを作成し、Gitのリポジトリとして初期化します。もしくはgit secretsを適用したい既存のリポジトリへ移動します。

$ mkdir repos; cd repos;
$ git init

git secretsをリポジトリに適用します。

$ git secrets --install                                                                                         
✓ Installed commit-msg hook to .git/hooks/commit-msg
✓ Installed pre-commit hook to .git/hooks/pre-commit
✓ Installed prepare-commit-msg hook to .git/hooks/prepare-commit-msg

拒否するパターンを登録

各コマンド実行時に--globalオプションを追加すると~/.gitconfigに設定が記録され、付けない場合は各リポジトリの.git/configに記録されます。

ここから先の実行例ではいずれも付けていませんが、よく利用するパターンは--globalを付けておいた方が設定作業が減って楽ちんです。

AWS

Amazon製ということもありAWSのIAMで利用されているクレデンシャルのパターンを弾く専用のオプションが用意されています。

$ git secrets --register-aws

任意のパターン

egrepで利用される正規表現を用いたパターンを登録できます。以下ではpasswordから始まる文字列の登録を禁止します。

$ git secrets --add '^password'

例外パターンを登録

例えばVISAカードのクレジットカード番号(4[0-9]{15})は拒否したいが、テスト用のカード番号4111111111111111は許可したいといった場合には以下のように--allowedオプションで指定します。

$ git secrets --add '4[0-9]{15}'
$ git secrets --add --allowed '4111111111111111'

登録済みパターンの一覧

--listオプションで現在のリポジトリに登録されているすべてのパターンが表示されます。

$ git secrets --list
secrets.providers git secrets --aws-provider
secrets.patterns (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
secrets.patterns ("|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)("|')?\s*(:|=>|=)\s*("|')?[A-Za-z0-9/\+=]{40}("|')?
secrets.patterns ("|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')?\s*(:|=>|=)\s*("|')?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}("|')?
secrets.allowed AKIAIOSFODNN7EXAMPLE
secrets.allowed wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
secrets.patterns 4[0-9]{15}
secrets.allowed 4111111111111111

登録済みパターンを編集・削除する

git secretsで登録したパターンは各リポジトリの.git/configまたは、--globalオプションを付けて実行した場合は~/.gitconfigに記録されていますので、これらのファイルを開いて直接編集することで変更や削除が行なえます。

$ cat .git/config                                                                                               [core]
        (中略)
[secrets]
    providers = git secrets --aws-provider
    patterns = (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}
    patterns = (\"|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(\"|')?\\s*(:|=>|=)\\s*(\"|')?[A-Za-z0-9/\\+=]{40}(\"|')?
    patterns = (\"|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(\"|')?\\s*(:|=>|=)\\s*(\"|')?[0-9]{4}\\-?[0-9]{4}\\-?[0-9]{4}(\"|')?
    allowed = AKIAIOSFODNN7EXAMPLE
    allowed = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    patterns = ^password
    patterns = 4[0-9]{15}
    allowed = 4111111111111111

試してみる

ここではgit secrets --add '^password'が実行されているとして実験します。

エラーになることを確認

では必ずNGになる内容のファイルを用意します。

$ echo 'password' > foo.txt

そしてGitへcommitしようとすると無事にエラーを出してリポジトリへの登録を防いでくれました。

$ git add .
$ git commit -m 'secrets test'
foo.txt:1:password
[ERROR] Matched one or more prohibited patterns

ここからリカバリするには?

まだステージ上に登録されたままですので、いったんresetしてから修正します。

$ git reset

エラーにならない文字列に修正し、もう一度commitします。

$ echo 'not-password' > foo.txt
$ git add .
$ git commit -m 'secrets test'
[master (root-commit) 63155d0] commit
 1 file changed, 1 insertion(+)
 create mode 100644 foo.txt

今度は無事にcommitされましたね! 同様の方法でAWSのクレデンシャルも拒否することが可能です。

その他

一時的に無効にしたい

commit時に--no-verifyオプションを付けるとgit secretsのチェックを無効にすることができます。

$ git commit -m '強制的にcommitしたいでござる' --no-verify

既存のリポジトリをスキャンする

現在のファイル

--scanオプションを付けて実行すると、リポジトリ内のすべてのファイルをその場でチェックしてくれます。途中からgit secretを導入する場合に活躍してくれそうですね。

$ git secrets --scan 

以下のように特定のファイルやディレクトリのみを対象としたり、

$ git secrets --scan file.txt

標準入力から渡すことも可能です。

$ cat *.ini | git secrets --scan  

すべての履歴

--scan-historyオプションの場合は、過去の履歴をすべてスキャンしてくれます。問題があった場合はハッシュ値とファイル名が表示されます。

$ git secrets --scan-history

9f49d13c48d7de921549417be0faf1506d7cceb3:card.txt:1:4111111111111112

[ERROR] Matched one or more prohibited patterns

参考ページ