GitHubのコードチェック機能として以下を試しました。
- Secret scanning
→ パスワード等の機密情報が含まれていないかチェック - Code scanning
→ 脆弱性に問題があるコードをチェック(≒静的コード解析)
以下、目次となります。
利用前提
Publicリポジトリであれば無料で使えます。
→ 安全維持のためにも普通に使っていきましょう。
ところで、Privateリポジトリで使うためには、別途GitHub Advanced Securityというオプションライセンスを購入する必要があります(結構高額でEnterpriseアカウントの費用をかなり上回ります、年間5万円以上)。
Secret scanning
次の順で試してみます。
- テスト用のPublicリポジトリを作成して、機密情報を書いたコードをコミットしておく。
- Secret scanningを有効にする。
- 結果を確認する。
機密情報としてGitHubのアクセストークン、AWSのアクセスキーを記載したファイルをコミットします。
続いてリポジトリの設定として「Code security and analysis」→「Secret scanning」をEnableに設定します。
※ところで、オプション「Push protection」はPushされる前に防ぐという機能ですが、後半で試します。
設定後(1分以内)、少し待ちます。
Securityタブを確認すると「Secret scanning」として3件上がっていることが確認出来ます。
個々の内容には「キー」「対処方法」「該当ファイル」などの情報が表示されています。対処後にチケットは閉じるようにしましょう。
◇アラートに関する補足事項
- メールでも通知されます。
- 基本的にアクティブなキーがアラート対象。
- GitHubの場合は自動的にトークンが削除された。
- AWS側でも何かしら警告が発生する。
関連するサービスによりますが、むやみやたらにアラートがあがるわけではないようです。そのキーやトークンが生きているかどうかGitHub側で読取チェックぐらいはしているのではないでしょうか。
Secret scanningのPush protectionを試す
せっかくなので「Push protection」を有効にした場合の挙動を見てみます。
設定した後、GitHub.com上でPush操作をしたところ、次の画面が表示されました。
問題なく動作しているようです。理由を選択すれば無視して反映できます。
クライアントツールの場合は?
では、今回は「GitHub Desktop」で試してみます。
Push操作で次のようなエラーメッセージが表示されました。
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 363 bytes | 363.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: error GH009: Secrets detected! This push failed.
remote:
remote: GITHUB PUSH PROTECTION
remote: ——————————————————————————————————————————————————————
remote: Resolve the following secrets before pushing again.
Pushの際にしっかりとガードしてくれました。
※仕組みとしてpre-receiveといったサーバサイドのPost事前検出フックが動いているのでしょう。今回はGitHub Desktopで試しましたが、他のGitクライアントツールでもガードしてくれそうです。
Code scanning
次の順で試してみます。
- テスト用のPublicリポジトリを作成して、脆弱性を含むコードをコミットしておく。
- Code scaningを有効にする。
- 結果を確認する。
Pythonでクロスサイトスクリプティング(XSS)の脆弱性をもつファイルをコミットします。
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def index():
user_comment = request.args.get('comment', '')
return f'<html><body><h1>User comment: {user_comment}</h1></body></html>'
if __name__ == '__main__':
app.run(port=8080)
※このPythonコードはFlaskフレームワークを使用しています。ユーザーの入力がそのままHTMLに埋め込まれており、エスケープ処理が行われていません(XSSの脆弱性あり)。
続けてリポジトリ設定よりCode scanningを有効化します。
→ CodeQL analysis → Set up → Defaultを選びます。
続いて確認画面が表示されるため「Enable CodeQL」をクリックします。
※リポジトリに何かしら検査対象のソースコードが含まれていないと有効化は出来ません。デフォルトの場合はPush及びPull Requestの際に動作するようです。
※Advandedであれば自分でymlを記述してもっときめ細かい条件を指定可能です(今回は省略)。
有効後、Actionsを見ると初回のCodeQL Setupが動き出します。
→ 今回はリポジトリ設定から有効にしましたが、ActionsからCodeQLを導入して動かすことも可能です(CodeQLはActionの1つ)。
数分後、SecurityタブのCode scanningに検出として表示されました。
意図した通りにXSSに関する警告が表示されています。
以後、デフォルト設定の場合はPushやPull Requestの度に動作します。コードを修正してプッシュした場合、セキュリティは自動的に「Closed」となります。一方で、意図したソースコードの記述であればアラートチケットを「問題ない」などとして閉じましょう。
開発初期からCodeQLを有効にしておけば、初期の段階から脆弱性を対処したコード品質を保つことが出来そうです。
まとめ
本記事ではGitHubのコードチェック機能として「Secret scaning」「Code scaning」をご紹介しました。Publicリポジトリなら無償で使えます(有効にしているリポジトリも多いはず)。
- Secret scanningは多くのサービスが対応しています。
→ アクティブなものが基本的に対象で、検出されるとメール通知に加え、GitHubなら自動的にトークン削除も行われます。 - Code scaningは数多くの言語に対応した静的コードチェックツールです。
→ pushやpull requestの度にチェックしてくれるため、初期の段階からコード品質(脆弱性面)を担保することが出来ます。
最後までご覧頂きありがとうございました!
コメント