git-secretsを使用してAWSアクセスキーのコミットを防ぐ方法の紹介

2023.02.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部Delivery部のアベシです。

この記事ではgit-secrets使用してAWSアクセスキーのコミットを防止する仕組みの導入方法について紹介します。

弊社の以下のブログにあるような実際の出来事では、アクセスキーが流出してから10分程度でマイニングに不正利用されてます。※ 弊社作業による流出ではありません。

このように、アクセスキーは流出するとすぐに利用されてしまうほど狙われやすい認証情報となっています。
このような被害を無くすために、AWSを使う方には是非今回のような対策をしていただけたらなと思います。

git-secretsについて

git-secretsに登録したパターンに合致するシークレット情報が、コードに含まれていないかチェックできます。

実装方法の概要

今回、実装方法として以下2通り紹介します

  1. リポジトリ単位でAWSアクセスキーのパターンを登録することで、git-secretsのみでコミットの際のコードチェックを走らせる。
  2. git-secretsのグローバル設定にAWSアクセスキーのパターンを登録します。huskyを併用しコミットの際にgit-secretsのコードスキャンコマンドを実行する。

git-secretsのみで実装するパターン

インストール

いずれの方法においてもまず以下のコマンド実行してgit-secretsのインストールします。

$ brew install git-secrets

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

AWS アクセスキーのパターンを登録

以下のコマンドで登録します

$ git secrets --register-aws
// 正常に登録されるとOKと出力されます
OK

登録されたパターンは以下のコマンドで見ることができます。

$ git secrets --list

先程登録したAWSアクセスキーのパターンが以下のように出力されます。

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

下2行のsecrets.allowedは例外として登録された値となっています。この値対してはgit-secretsが働かなくなります。現在入っている値はAWSが公式ドキュメントで使っているサンプルです。

動作確認

それでは、実際にパターンに合致する文字列をハードコードした変更がコミットできなくなるか確認します。 secrets.allowedに登録されているアクセスキーのサンプルの一文字変えたものでテストします。

パターンに合致する文字列を含んだファイルを作ります

$ cat <<'EOL' >> test.txt
… heredoc ❯ AKIAIOSFODNN7EXAMPLD
… heredoc ❯ EOL

コミットします

$ git add .
$ git commit -m "test"

以下のように出力されてコミットが防がれました

$ git commit -m "test"
test.txt:1:AKIAIOSFODNN7EXAMPLD

[ERROR] Matched one or more prohibited patterns

Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive

git-secretsとhuskyを組み合わせるパターン

こちらのパターンではhuskyを一緒に使います。

huskyについて

コミットをトリガーしてコマンドを実行させることができます。
コードの静的解析やtestなどを走らすといった使い方もできます。

AWSアクセスキーのパターンをglobalに登録

git-secretsのみの場合は適応したいリポジトリにセットアップしましたが、このやり方ではパターンをglobalに登録して特定のリポジトリに限定しません。

抑制したいパターンは以下のコマンドのようにglobalオプションを付けて登録します。

$ git secrets --register-aws --global

登録したパターンは~/.gitconfigに記載されます。

リポジトリにhuskyの導入

リポジトリのプロジェクトルートで以下実行すると簡単に導入できます。

$ npx husky-init && npm install //npmの場合

作成された.husky/pre-commitにgit-secretsのスキャン実行コマンドを記載します。

.husky/pre-commit

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

git secrets --scan // ここにgit-secretsのスキャン実行コマンドを書きます。

動作確認

git-secretsのみの場合と同様にAWSアクセスキーのパターンに合致する文字列を含んだファイルを作成しコミットします。

$ git commit -m "test"
test.txt:1:AKIAIOSFODNN7EXAMPLD

[ERROR] Matched one or more prohibited patterns

Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive
husky - pre-commit hook exited with code 1 (error) //huskyの動作によりexitしていることが確認できます。

期待通り、コミットが防がれました。

参考

以上。