GitHubって便利ですよね。この前AWSを使ったコードを書きました。
AWSの全データセンターから最も価格の低いスポットインスタンスを検索するスクリプト
で、これ書く前、参考にGitHub漁ってたんですが、意外と「APIキーとシークレットをハードコードしてGitHubにアップロード」する人が未だにいるんだなあと思った。と同時に、「GitHubの検索が優秀すぎて簡単にAPIキーを探せる状況」であることに気付いた。
日本でもこんな事例
AWSが不正利用され300万円の請求が届いてから免除までの一部始終
が2015年から現在にかけてたまに聞きます。↑のは結構最近。
いや怖いですね。GitHubは数分前にインデックスされたソースコードもすぐに検索できますので下手するとアップロード後すぐに不正利用されてもおかしくありません。GitHubの検索が優秀すぎて逆に(悪い意味で)キー検索に便利な構造になってます。
検索
画像とかリンクは載っけません。もちろん使えるかどうか確認など、キーを不正に使うことはしてはいけません。
GitHubのソースコード検索は登録者のみ
ソースコードの詳細検索機能はGitHubアカウントにログインしている場合のみです。GitHubのトップページから検索することでグローバルな検索モードに入ることができます。
AWSのAPIキー構造が検索のしやすさに拍車
自分でAPIキー発行してても思ったのですが、少なくともEC2とS3はAWSのAPIキーは「必ずAKIAJから始まる」ようですね。シークレットはランダムなようですが、偏りがある気がします。
キーに固定値が入っていると格段に検索しやすくなるのはおわかりでしょう。なぜAWSが固定値から始めるのは謎です。何か理由があるのでしょうか。なければやめたほうがいいのではと思うのですが・・・?
APIキーがハードコードされているソースが見つかった場合は、シークレットも必然的に近くに記述されています。当然です。APIを扱うオブジェクトを生成するのにキーもシークレットも必要ですし、開発者はpublicリポジトリにソースコードをホスティングしていることに無頓着な人間です。キーだけ記述されていてシークレットがどこにも無いパターンは少ないです。
共通のライブラリが検索のしやすさに拍車
AWSに限らずTwitterやFacebookなど、APIを扱うのに定番のライブラリがありますよね。そのライブラリで使用するキーやシークレットを記述する定数名が固定である場合が多いため、検索しやすくなります。
AWSのAPIを扱う定番ライブラリはPython3だとboto3です。boto3を環境変数を使わずにキーをハードコートする場合は、オブジェクト生成時に「aws_access_key_idとaws_secret_access_key」を指定します。これらを検索対象に含めることにより検索にヒットしやすくなります。
Twitterだと、TWITTER_CONSUMER_KEYや、TWITTER_CONSUMER_SECRETがよく使われます。TWITTER_ACCESS_TOKENや、TWITTER_ACCESS_TOKEN_SECRET なんかも検索ワードとして使えます。
もちろん多くのコードは対策済み
実際は流出しているコードよりも、もっと多くのコードがAPIキー流出をしないように対策しています。
例えば.envなどの環境設定ファイルにAPIキーを記述し、.gitignoreに.envを加えたりなどです。
他にも「TWITTER_CONSUMER_KEY=YOUR_COMSUMER_KEY」にしてダミーを入れておくようなコードも見かけます。
うっかりミスを防ぐためにもキーを記述したファイルは.gitignoreに加える対策が有効ではないかと思います。
boto3などでは環境変数にキーとシークレットを設定することで、コードに記述しなくても使用できるように配慮されています。
要はハードコードダメ・ゼッタイってやつですね。