AWS Access Keyを外部に公開してしまった話

こんにちは。テクノロジーセンター・SRE Unitのイ・グンジェです。

今回、AWS Access Keyを誤ってGithubにPushしてしまった事故(?)があり、
それに対する備忘録と再発防止対策についてお話したいと思います。

やらかしたこと

medibaではサービスごとにAWS Accountを分けているため、
複数のAWS 環境が存在しています。

全てのAWS環境にあるEC2の情報を一目で把握したかった私は
全てのAWS環境からEC2の情報を取得するPython Scriptを書くことに決めました。

Boto3 SDKを利用して、EC2情報を取得するScriptを作成した私はテストのため、
テストScriptを作り、AWS Access Keyを書き込んで動作確認をしていました。

作業途中、もっと大きいモニターがあるPCで作業したくなって、
Githubにコードを上げて自由に作業環境を切り替えるのを考えました。

コードを上げるためにGitHub Repositoryを準備し、
.gitignoreファイルに用意してテストScriptは除外されるようにしてからGithubにコードをPushしました。 (テストで書いたScriptにはAWS Access Keyが書き込んでいるため)

しかし、何と。。誤字が入ってしまい、
テストScriptもPushされてAWS Access Key公開されてしまいました。。。!

AWSによる漏洩通知と対応内容

GithubにAccess Keyの情報を上げるバカなことのやったのは12/17 21:55頃。

その後、AWSからAccess Keyが外部に公開されたというメールが届いていました。
メールには不正アクセスによる課金などを防ぐために隔離ポリシーを対象Userに付与したという内容も書いてありました。

CloudTrailからもAWSCompromisedKeyQuarantineポリシー付与のログが確認できて、
UserやRole、EC2インスタンを作成する権限が全部拒否されていました。

さらにこのポリシーは"iam:DetachUserPolicy"を持っているため、
付与されたUserが直接Detachするのもできない状態でした。

また、AWSのサポートチケットがOpenされたとのメールも届いていました。

AWSからの通知後にやったこと

まずはAccess Keyが無効化されているのを確認して削除しました。

そして、公開されてから悪用の行為はなかったのかCloudTrailでログを確認してみました。

12/17 21:55頃Access Keyの公開が認識され、AWSCompromisedKeyQuarantineポリシーが
Attacheされた以降、特にUserとかRoleが作成されてリソースが追加された履歴はありませんでした。 (12/18の履歴は私が挫折して彷徨した履歴です。)

悪用の履歴はなかったため、他のチームメンバーにお願いして
AWSCompromisedKeyQuarantineポリシーをDetachし、新しいAccess Keyを作成しました。

再発防止策としてのgit-secrets導入

この事故で迷惑をかけてしまった私は恥ずかしいと思いながら、
今後同じ事故を防ぐためにどのような対策があるか考えてみました。

言うまでもなく当たり前なことですが、コードに直接Access KeyとSecret Access Keyを
書き込まないとか.gitignoreでRepositoryに上げるファイルを制限する方法などがあると思いましたが、 今回の事故のように誤字を入力するなどの人災により.gitignoreの制限が無効化される場合があるため、 もっと確実な方法が必要だと思いました。

その時、優れたスキルを持っていつも色んな情報を共有してくれていたメンバーが
git-secretsについて紹介してくれました。(ありがとうございました!)

git-secretsはcommitやcommit messagesをScanして
正規式にMatchされるのパターンがあればcommitをrejectしてくれるツールです。

参考 : git-secrets

また、Classmethodの記事にもgit-secretsを紹介していて、
導入した内容もあったので参考しながらgit-secretsを導入してみました。

git-secrets基本設定

  1. git-secretsをインストール
# brew install git-secrets
  1. git-secret messageをhookするためにgit hookをインストール
# cd /path/to/my/repository

# 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
  1. gitの設定にgit-secretsパターンを追加
# git secrets --register-aws

# view .git/config

[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

git-secrets高度な設定

上記の設定方法はrepositoryがあるDirectoryのLocal設定を参照するため、
他のrepositoryはgit-secretsが効かないです。

全てのrepositoryにgit-secretsを適用したい場合は--globalのOptionを付けてGlobal設定から参照できるようにする必要があります。
(これで既存のrepositoryはもちろん、今後新しくCloneするrepositoryも適用されます。)

# git secrets --register-aws

# view .git/config

↓

# git secrets --register-aws --global

# view ~/.gitconfig

また、git hookは以下のコマンドでglobal設定しておくと、
新しいrepositoryができたらtemplateDirからhookを持って来るので自動的にhookの設定もできます。

# git secrets --install ~/.git-templates/git-secrets
# git config --global init.templateDir ~/.git-templates/git-secrets

最後に、git-secretsの正規式からフィルタリングされたくない文字列がある場合は
以下のようにallowedを追加することで、無視するのもできます。

# git secrets --add --allowed (文字列)

git-secretsをテストする

インストール及び設定が完了して、repository全体をScanしてみたら、
以下のようにパターン分析を通してAccess Keyを見つけてくれました。

commitしてPushしようとしても以下のようにErrorのメッセージが出力されて、
Commitが拒否されます。

また、Visual Studio Codeでも以下の画像の通りErrorメッセージのModalが出て
Commitが拒否されます。 (Sourcetreeではgit-secretsがうまく動かないようなので、別途で対応する必要があります。)

これで、Access Keyの情報が入っているファイルを誤ってGithubに上げようとしても
git-secretsがちゃんとScanしてCommitを止めてくれることが確認できました。

これから、気づかずCommitしようとしてもgit-secretsがちゃんと止めてくれますよね。

まとめ

これで、私がAWS Access Keyを誤って公開したことから、
再発防止のためにgit-secretsを導入したことまでのお話をまとめてみました。

何よりもこの事故で驚いたのはAWS側からAccess Keyが外部に公開されたのを
すぐに検知してCustomerに通知しつつ、隔離ポリシーを対象Userに付与するまでの対応がとても早かったということです。

GithubにAccess Keyが上がってから1分内で全ての対応が完了されていて、
そのおかげで大きな情報漏れ事故に繋がらず、収束できたと思います。

git-secretsを経験することができたのも楽しかったです。
インストールも思ったより簡単ですし、設定もテンプレートで
すぐに追加できるので、誰でもすぐに使えるツールだと思いました。

やはり、個人勉強以外にも障害や事故でも学ぶことがあると思いました。

以上です。
次回は楽しい内容で戻ります。