🔐

AWSとGithub ActionsのOIDC連携における設定ミス

2024/12/17に公開

AWSとGitHub ActionsのOIDC連携における設定ミス

多くの企業がCI/CDパイプラインにおいてGitHub ActionsなどのCI/CDサービスとAWSの連携にOIDC(OpenID Connect)を採用しています。この方式は、長期的な認証情報を保存する必要がなく、セキュリティ面で優れています。

しかし、DEFCON32の講演(Aviad Hahami - OH-MY-DC - Abusing OIDC all the way to your cloud.pdf, Nick Frichette - Kicking in the Door to the Cloud - Exploiting Cloud Provider Vulnerabilities for Initial Access)で触れられているように、この連携における設定ミスが新たなセキュリティリスクを生む可能性があります。この記事では、AWSとGitHub ActionsのOIDC連携を例に、OIDCの役割や連携の流れを簡単に振り返りながら講演で触れられていた設定ミスとその対策について紹介します。

OIDC連携の概要

CI/CDパイプラインからAWSリソースにアクセスする場合、AWSのアクセスキーとシークレットキーをCI/CDの環境変数として設定する方法が一般的でした。しかし、この方法には以下のような問題があります。

  • 長期的な認証情報を保存する必要がある
  • 認証情報のローテーションが煩雑
  • 細かいアクセス権限の制御が難しい

過去にはCodecovの事例のように、CI/CDパイプライン上で利用するサービスに起因してクレデンシャルが漏洩するような事例もありました。

OIDCを使用した連携はこれらの課題を解決することができます。OIDCを利用することで、CI/CDパイプラインは一時的なトークンを使用してAWSリソースにアクセスできます。

OIDC連携の認証認可の流れ

本題の設定ミスについて説明する前に、GitHub actionsとAWSのOIDC連携の認証認可の流れを簡単に振り返ります。

https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect#getting-started-with-oidc より引用

  1. GitHub actionsがアクセスするための事前設定としてAWSにてIDプロバイダー及びロールの設定をユーザーが行います
  2. GitHub actionsのジョブ実行時に、GitHubが対象ジョブにIDトークンを払い出します
  3. GitHub actionsからAWSのリソースにアクセスするために、発行されたIDトークンを利用してassume roleします
  4. 事前に設定された条件に従いIDトークンの中身を検証し、問題がなければアクセストークンが返されAWSのリソースにアクセスすることが可能になります

設定ミスの例

1. サブジェクト(sub)の検証不足

最初の設定ミスは、IAMロールの信頼ポリシーにおいてIDトークンのサブジェクト(sub)の検証が不足しており、以下のようなIAMロールの信頼されたエンティティにて以下のような設定になっているケースです。これはOIDC連携の認証認可の流れにおける1.の段階での設定ミスとなります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

IDトークンにおいて、subはサブジェクト(subject)の略で、OIDCでは”Client に利用される前提で, Issuer のローカルでユニークであり再利用されない End-User の識別子” として定義されています。GitHub Actionsのsubjectにはリポジトリやワークフローの情報が含まれます。一方、audはオーディエンス(audience)の略で、”ID Token の想定されるオーディエンス”として定義されており、そのトークンを処理する対象を示します。AWSと連携する場合はsts.amazonaws.comとなります。

上記の設定では、sub(subject)を検証するConditionが設定されていないため、任意のOrganizationのGitHub Actionsがこのロールを引き受けることができ、そのロールでアクセスできるリソースにアクセスすることができます。

2. カスタムサブクレームの不適切な使用

GitHub Actionsでは発行されるIDトークンのサブジェクトクレーム(sub)に含める値をカスタマイズすることができます。この機能はより細かくアクセス制御するために提供されています。しかし、カスタマイズする際にworkflowと他のクレーム(例えばrepo等)の順序を誤って設定した場合、攻撃者が偽装したワークフロー名を使用して不正アクセスを行う可能性があります。


Aviad Hahami - OH-MY-DC - Abusing OIDC all the way to your cloud 86ページから抜粋

workflowはユーザ入力に基づく値が含まれるため、subのフォーマットとしてworkflowを先頭にしてしまうことでsubに含まれる値が全てユーザ入力によって偽装できるようになり、攻撃者は攻撃者自身のworkflow名にrepo名の文字列を含めることで正規のCI/CDからのアクセスに偽装することができます。

適切な設定方法

これらの問題を防ぐために、以下のような観点で設定を見直してください。

1. 適切なサブジェクト条件の設定

例えば以下のようにaudの条件を追加し、<GitHubOrg>/<GitHubRepo><GitHubBranch>のに適切な値を設定することで指定されたGitHub Organization、Repository及びブランチからのアクセスに限定することができます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:sub": "repo:<GitHubOrg>/<GitHubRepo>:ref:refs/heads/<GitHubBranch>"
        }
      }
    }
  ]
}

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html#idp_oidc_Create_GitHub に設定例が記載されているので、参考にしてください。

2. カスタムサブクレームの適切な設定

カスタムサブクレームを使用する場合は、workflowのようなユーザ入力に依存するような項目の順番に注意してください。例えばworkflowの前にrepoを置くことで、ユーザ入力だけでは偽装できないようにすることができます。

おわりに

OIDCを使用したCI/CDとAWSの連携は、セキュリティを向上させることができますが、適切な設定を行わないと、新たなセキュリティリスクを生む可能性があります。

設定時には必ずAWSとGitHub Actionsの公式ドキュメントを参照し、セキュリティのベストプラクティスを確認しましょう。また、定期的な設定の見直しも重要です。

Cloudbaseでは、noteでも様々な記事を公開しておりますので、ぜひご覧ください。

https://note.com/cloudbase

Discussion