Slide 1

Slide 1 text

Session Title 社内用GitHub Actionsの セキュリティガイドラインを作成した話 Toshiki Kawamura 株式会社メルコイン Backend Engineer

Slide 2

Slide 2 text

Toshiki Kawamura / @goro 2019年に大手不動産テック企業にソフトウェアエン ジニアとして入社後、スタートアアップ企業を経て 2022年6月にメルコインに入社。ビットコイン取引 サービスの立ち上げに参画し、バックエンドエンジ ニアとして開発・運用を担当。今回発表の題材にも なったGitHub Actionsガイドライン作成などの社内 横断の取り組みにも携わっている。 株式会社メルコイン Backend Engineer

Slide 3

Slide 3 text

GitHubActionsセキュリティガイドライン 社内でのGitHub Actionsの利用の広がりにあわせて、社内有志によっ て検討・策定されたセキュリティガイドライン。 「GitHub Actionsを使うにあたり、どういった点に留意すれば最低限の 安全性を確保できるか学習してもらいたい」「定期的に本ドキュメントを 見返してもらい、自分たちのリポジトリが安全な状態になっているかを 点検する際に役立ててもらいたい」などという思いに基づいて作成され ている。

Slide 4

Slide 4 text

Masahiro Wakame / @vvakame 株式会社メルペイ Solutions team 🐈💖 Motonori Iwata 株式会社メルコイン Backend Engineer 株式会社メルコイン Engineering Manager Sadaaki Hirai / sadah ガイドライン策定チーム

Slide 5

Slide 5 text

本発表の流れ ガイドラインの中身を一部紹介 01 ガイドラインの社内での活用状況 02 ガイドライン策定の裏話 03

Slide 6

Slide 6 text

ガイドラインの中身を一部紹介

Slide 7

Slide 7 text

ガイドラインの目標 「常に達成したいこと」として「外部の攻撃者からの攻撃を防ぐ」こと 01 「可能であれば考慮したいこと」として「内部と同等の権限を持つ攻撃 者からの攻撃を防ぐ」こと 02

Slide 8

Slide 8 text

ガイドラインの構成 脅威を知る 1部 脅威への対策 2部 セルフチェックリスト 3部

Slide 9

Slide 9 text

第1部 脅威を知る

Slide 10

Slide 10 text

権限設定の不備を突く攻撃 PRを契機に起動するトリガーは攻撃者がなにかを仕掛ける余地が大 きく、不注意にワークフローを構築するとシークレットを外部に送信され て攻撃を受ける可能性がある。

Slide 11

Slide 11 text

補足:ワークフローのトリガー ワークフローをトリガーするイベントには、以下のものがある。 ● ワークフローのリポジトリで発生したイベント ● GitHubの外部で発生し、GitHub上で repository_dispatch イベン トを発生させるイベント ● 時間指定での実行 ● 手動実行...etc

Slide 12

Slide 12 text

権限設定の不備を突く攻撃 権限設定の不備をついてシークレットなどを外部に送信される方法とし て考えうるもの ● ビルドスクリプトに細工をする ● 依存関係にあるライブラリを悪意のあるものに差し替えられる ● 自動実行の仕組みに相乗りされる(npmのpreinstall, postinstallな ど) ● 過去、実際に人気のライブラリでローカルファイルをスキャンする事 例があった

Slide 13

Slide 13 text

権限設定の不備を突く攻撃の影響 ● 攻撃者に、悪意のあるアクションまたは侵害されたアクションによっ てGitHub Actionsの計算リソースを不正に利用される可能性があ る ● 侵害された、または悪意のあるアクションによって、リポジトリの自 動ワークフローが中断される可能性がある ● Deployment Keyやアクセストークンなどのシークレットへの読み取 りアクセスは、攻撃者が他のリソースを侵害するために利用される 可能性がある

Slide 14

Slide 14 text

インジェクションによる攻撃 一見安全に見えるワークフローにおいてもコードやコマンドインジェク ションを引き起こす可能性がある。

Slide 15

Slide 15 text

インジェクションによる攻撃例1 ● 以下のようなコードにはインジェクションの脆弱性がある。 ● コメントに {{ 1 + 1 }} のような二重中括弧が含まれていた場合、 Actionは内部で{{ }}の値を補間するためにlodashを使っているた め、node.jsコードが実行され出力が2になる。 uses: foo/[email protected] with: comment: | Comment created by {{ event.comment.user.login }} {{ event.comment.body }}

Slide 16

Slide 16 text

インジェクションによる攻撃例2 ワークフローのインラインスクリプトに直接インジェクションを配置するシ ナリオもある。また、ブランチ名やメールアドレスへのコマンドインジェク ションもできる。

Slide 17

Slide 17 text

インジェクションによる攻撃例2 以下のようなコードは内部の式 ${{ }} が評価され、結果の値に置き換 えられるため、コマンドインジェクションに対して脆弱になる可能性があ る - name: Check PR title run: | title="${{ github.event.pull_request.title }}" if [[ $title =~ ^octocat ]]; then echo "PR title starts with 'octocat'" exit 0 else echo "PR title did not start with 'octocat'" exit 1 fi

Slide 18

Slide 18 text

インジェクションによる攻撃例2 ● 攻撃者は「 a"; ls $GITHUB_WORKSPACE"」 といったタイトルの PRを作成する可能性がある ● その場合" を使用して title="${{github.event.pull_request.title }}" ステートメントを中断し、ランナーでコマンドを実行できるようにす る。そうすると以下のようにlsコマンドの出力を確認できる。 > Run title="a"; ls $GITHUB_WORKSPACE"" README.md code.yml example.js

Slide 19

Slide 19 text

インジェクションによる攻撃の影響 ● インジェクションをされると攻撃者は任意のコマンドを実行できるた め、外部のサーバーにシークレットを送信するHTTPリクエストを行 うことが可能になる ● リポジトリへのアクセストークンを取得してもワークフローが完了す ると失効するので攻撃は簡単ではない。しかし、攻撃者が自動化 し、管理するサーバーにトークンを呼び出して、コンマ数秒で攻撃 を実行することは可能となる。 ○ その場合GitHub APIを利用してリリースを含むリポジトリのコ ンテンツを変更するなどの影響が考えられる

Slide 20

Slide 20 text

インジェクションによる攻撃の影響 ● 攻撃者は悪意のあるコンテンツをGitHub Context経由で追加でき るので、潜在的に信頼できない入力として扱う必要がある

Slide 21

Slide 21 text

第2部 対策を考える

Slide 22

Slide 22 text

最小権限の原則に従う ● 最小権限の原則は、ソフトウェアがタスクを達成するために必要な 最小限の権限セットで実行されるべきであるという原則 ● これは、ワークフローで利用可能な シークレット の権限と、ワーク フロートリガーの種類に基づいて自動的に提供される一時的なリポ ジトリトークンの両方に当てはまる。

Slide 23

Slide 23 text

最小権限の原則に従う ● GitHub の推奨するセキュリティ対策に則るとGITHUB_TOKEN の 権限のデフォルト設定を「読み取りと書き込み」権限から「読み取り 専用」に変更すべきである ● 設定はGitHubの対象リポジトリの Settings > Actions > General から変更できる。

Slide 24

Slide 24 text

最小権限の原則に従う ● GitHubActionsの権限はワークフロー単位でも設定できるが、Job 単位で設定を行うことで権限を最小化できる jobs: job_name: ... permissions: issues: write

Slide 25

Slide 25 text

シークレットの利用について ● Long-Lived tokenを利用しない ● Workload identity federationを用いたSecret Managerの利用を 検討する ● 構造化データ(JSON, XML, YAMLなど)をシークレットにしない ○ GitHub Actionsは全文をマスクデータとして扱ってくれるが部 分文字列はマスクされないため

Slide 26

Slide 26 text

シークレットの利用について ● ワークフロー内で使用されるすべてのシークレットをマスクするよう 登録する ● シークレットに保存されたアクセストークンの利用状況を監査する ● スコープが最小限のクレデンシャルを使用する ● 登録されたシークレットを監査およびローテーションする ● シークレットへのアクセスについてレビューを要求することを検討

Slide 27

Slide 27 text

利用すべきイベントトリガー ● リポジトリへのwriteはできないよう制限されているのでPRの処理 には pull_request イベントを使えるなら使う ● 少し制限を緩めたものとして、pull_request_targetがある ○ GitHub Actionsのワークフロー自体は pull_request_target だ と default branch のものが使われる ○ ワークフローのyamlに直接記載する場合は攻撃者によって上 書きされない ○ チェックアウトしたコードに含まれるComposite Actionを使う場 合注意が必要となる

Slide 28

Slide 28 text

補足:Composite Action ● Composite ActionはカスタムActionの一つであり、使用することで ワークフローの複数のステップを組み合わせて 1 つのアクションに することができる。 たとえば、複数の run コマンドを 1 つのアクショ ンにまとめて、そのアクションを 1 つのステップとしてワークフロー から呼び出して実行することが可能。

Slide 29

Slide 29 text

Job / Stepの単位 ● シークレットの内容を露出する単位は可能な限り狭くする ○ Job単位 より Step単位 のほうがよりよい ● Step間のファイルによるデータやりとりは全ステップから可視であ ると考える ● Jobは処理の単位によって分ける ○ 例えばテスト/ビルド/デプロイ はそれぞれJobを分けたほう がよい ○ 必要なGitHub Actions上のPermissionやクラウドプロバ イダー の権限を細かく制御できる

Slide 30

Slide 30 text

Dependabot / Renovateを利用した GitHub Actionsの更新 ● Actionsはバグ修正や新機能によって頻繁に更新される。 Dependabot、RenovateでGitHub Actionsの依存関係を最新の状 態に保つことができるため、設定を行うこと

Slide 31

Slide 31 text

サードパーティのActionを利用する際の注意点 ● サードパーティのActionを利用する場合、基本的にFull Changeset Hashに固定する

Slide 32

Slide 32 text

サードパーティのActionを利用する際の注意点 方式 書き方 特徴 Full Changeset Hash owner/action-name@26968 a09c0ea4f3e233fdddbafd11 66051a095f6 衝突の成功例はあるが困難 Short Changeset Hash owner/action-name@26968 a0 衝突に対して脆弱 Tag / Release owner/action-name@v1 タグを後で変更され、意図し ない変更が混入してしまう 可能性がある Branch Name owner/action-name@main 将来壊れる可能性がある 意図しない変更が混入して しまう可能性がある

Slide 33

Slide 33 text

サードパーティのActionを利用する際の注意点 ● 以下のようにFull Changeset Hashとバージョンコメントを記載する ことで、どのバージョンを使っているのかわかりやすくなる uses: owner/action-name@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v1.0.0

Slide 34

Slide 34 text

サードパーティのActionを利用する際の注意点 ● Actionのソースコードを監査してサードパーティのホストにシーク レットを送信するなどの疑わしいことがないか確認する ● ワークフロー内で利用しているサードパーティActionsのAction permissionsをセキュリティ観点で見直す。 ● 不要なワークフローやJobは削除する ○ 設定はしてあるが必要なくなったものは削除して依存を減らす

Slide 35

Slide 35 text

インジェクションを防ぐ ● 信頼されない式の入力値を中間環境変数に設定する。 ○ これによって${{ github.event.issue.title }}式の値はスクリプト の生成に影響するのではなく、メモリに保存されて変数として 使用される - name: print title env: TITLE: ${{ github.event.issue.title }} run: echo "$TITLE"

Slide 36

Slide 36 text

インジェクションを防ぐ ● シェル変数をダブルクォートして単語の分割を避ける(シェルスクリ プトを書く際の一般的な推奨事項) ● GitHub のカスタムアクションやワークフローを書くときは、信頼でき ない入力に対して書き込み権限でコードを実行することがよくある ことを考慮する ● 外部Actionとなるが、actionlintを利用することでインジェクション対 策ができるので、導入を検討する ● GitHub Security Labの開発するCodeQL queriesを利用する

Slide 37

Slide 37 text

その他 ● 完全に攻撃を防ぐことは不可能と考え、問題が発生したときに受け る影響を最小限に抑える ○ Ex. Production環境に影響を及ぼす(サービスを停止させる、 不正なImageを送り込む etc)ことがが最悪のケースとなる ● GitHub ActionがPRを作成またはオーナーとして承認しないように する

Slide 38

Slide 38 text

第3部 セルフチェックリスト

Slide 39

Slide 39 text

セルフチェックリスト ● 定期的にチェックすることでGitHub Actionsの安全な利用につなげ る。ガイドラインで学習した内容が本チェックリストでカバーされるこ とを目指している ● 第2部の内容をベースに講じて欲しい具体的なセキィリティ対策を 設定方法含め、チェックリスト形式で記載している

Slide 40

Slide 40 text

セルフチェックリストの一例 ● CODEOWNERSの設定を見直す ○ CODEOWNERSファイルで .githubディレクトリ以下に対して 適切にCode Ownerが設定されていることを確認する ○ Protected BranchでDefault BranchへのPull Requestのマー ジには、Code Ownerによる承認が必須になっていることを確 認する

Slide 41

Slide 41 text

セルフチェックリストの一例 ● ワークフロートリガーを見直す ○ コードプッシュをトリガとする場合、pull_request か、それが難 しければ pull_request_target を使う ○ on: pushをPR用に使っていたら見直す

Slide 42

Slide 42 text

さらに詳しい内容はブログをご覧ください https://engineering.mercari.com/blog/entry/20230609-gith ub-actions-guideline/

Slide 43

Slide 43 text

ガイドラインの社内での活用状況

Slide 44

Slide 44 text

Developer Documentationへの追加 Developer Documentation 主にBackend Engineerがよく参照す るPlatformの使い方がまとまった社内 ポータル

Slide 45

Slide 45 text

Secure Coding Guidelinesへの掲載 Secure Coding Guidelines Security Teamがメンテナンスする社 内基準のセキュリティルールを満たす ためのガイドライン

Slide 46

Slide 46 text

各チームでのガイドライン適用やサポート ● プロジェクトメンバーの自チームの管理するリポジトリに対してガイ ドラインの内容を適用させた ● 他チームがガイドラインを適用する際のサポートや質問を受け付け る体制を整えた

Slide 47

Slide 47 text

ガイドライン策定の裏話

Slide 48

Slide 48 text

作り方 1. GitHub Actionsのセキュリティに関連する文献、記事を読む 2. 記事には複数の記事がリンクされているのでそれらを読む 3. ガイドラインのアウトラインをまとめ a. 脅威を知る / 対策する / セルフチェックリスト 4. 参考文献の設定を試したりしながらガイドラインを書く 5. 自分たちでガイドラインをレビューする 6. セキュリティチームにレビューしてもらう 7. 修正する 8. 英訳する

Slide 49

Slide 49 text

タイムライン 2022 07 - 09 ボランティアメンバーの招集 アウトライン作成、執筆開始 2022 10 - 12 初回セキュリティレビュー実施 ガイドラインリファクタリング 2023 01 - 03 セキュリティ最終レビュー完了、正式版公開 🎉 セキュリティトレーニングコンテンツへ追加 2023 04 - 06 Developer Documentに反映 Engineering Blog公開

Slide 50

Slide 50 text

小さく始める、無理をしない 01 絶対完成させるという強い意志を持つ 02 適切な量のフィードバックをもらえるよう意識する 03 正式版を公開してから、育てていく 04 気をつけた点

Slide 51

Slide 51 text

ガイドラインは今後も適切に更新していき、 よりスムーズで安全な開発をサポートできるよう 努めていきたいと思います。

Slide 52

Slide 52 text

No content