ロールの連鎖は「特権の密輸」だ。IAMセッションポリシーで権限を封じ込めろ
現場でインシデント対応をしていると、決まって遭遇するのが「便利さの代償」だ。特にAWSやGCPのようなクラウド環境で、アカウントAからアカウントBへ、さらにアカウントCへとIAMロールを連鎖(Role Chaining)させている構成。これ、一見すると「認証の統合」に見えるが、攻撃者からすれば「特権の密輸ルート」に他ならない。
今日は、なぜロールの連鎖が危険なのか、そしてそれをどうやって「セッションポリシー」で物理的に封じ込めるのか、泥臭い実務の話をしよう。
1. なぜ「ロールの連鎖」がハッカーの踏み台になるのか
まず、基本的な攻撃シナリオを理解してくれ。例えば、Webサーバー(A)が、分析用アカウント(B)のS3バケットにアクセスするためにロールを引き受けているとする。
もし、Webサーバーのアプリケーションに脆弱性があり、攻撃者が一時的な認証情報(AccessKey/SecretKey/SessionToken)を盗み出した場合、攻撃者はそのロールが持っている権限をそのまま行使できる。
ここで恐ろしいのは、「連鎖の先にある権限まで奪取できてしまう」ことだ。IAMロールのポリシーに sts:AssumeRole が許可されている場合、攻撃者は奪った権限を使って別の強力なロールをAssumeし、権限を際限なく拡大(Privilege Escalation)していく。これが「ロールの連鎖による権限拡大」の正体だ。
2. 攻撃者の視点:PoCのロジック
攻撃者は、盗み出した認証情報を使って以下のようなCLIコマンドを叩く。
# 奪った権限で、さらに強力な「Administrator」ロールをAssumeしに行く
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/SuperAdminRole \
--role-session-name "HackSession"
もし、元のロールに sts:AssumeRole が付与されていたら、防御壁は一枚も残っていない。これを防ぐには、「どの範囲までAssumeを許可するか」を、ロールそのもののポリシーではなく、「セッションポリシー」で動的に絞る必要がある。
3. セッションポリシーによる封じ込め(防御の実装)
セッションポリシーとは、ロールを引き受ける瞬間に動的に適用される「権限の足枷」だ。いくらロール自体が広範な権限を持っていても、セッションポリシーがそれを制限していれば、そのセッション内では「最小権限」でしか動けなくなる。
以下は、Python(Boto3)を使って、安全にロールを引き受けるための実装サンプルだ。
import boto3
import json
def get_restricted_session():
sts_client = boto3.client('sts')
# セッションポリシーを定義:このセッションでは特定のバケットのReadのみを許可する
# これにより、たとえロールに書き込み権限があっても、このセッションでは実行できない
session_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::my-secure-bucket/*"]
}
]
}
# ロールを引き受ける際にポリシーを注入する
assumed_role = sts_client.assume_role(
RoleArn='arn:aws:iam::123456789012:role/TargetRole',
RoleSessionName='RestrictedAppSession',
Policy=json.dumps(session_policy) # ここが重要!動的な権限絞り込み
)
return assumed_role['Credentials']
# これで取得した認証情報を使ってS3にアクセスする
# 仮に攻撃者が認証情報を盗んでも、書き込みや削除は一切できない
4. セキュリティチーフからのアドバイス:現場で守るべきルール
コードをコピペするだけでは不十分だ。以下の運用ルールを徹底してくれ。
sts:AssumeRoleの許可範囲を絞る: IAMポリシーでResourceをワイルドカード(*)にするな。絶対に。「誰が」「どのロールを」Assumeできるかを明確に定義(Condition句で送信元IPやMFAの有無を制限する)すること。- セッションポリシーを「最後の砦」にする: アプリケーション側で、必要最小限の操作しか行わないよう、引き受けるロールに常にセッションポリシーを上書き適用する設計にしろ。
- 不要なロールの削除: 運用担当者が「とりあえず全部見られるロール」を作って放置しているケースが多すぎる。週に一度は
IAM Access Advisorを見て、使われていない権限を削ぎ落とせ。
終わりに:泥臭い検証こそが最強の防壁
セキュリティは教科書通りにはいかない。特にクラウドのIAMは、設定が複雑になればなるほど「暗黙の許可」が生まれる。
今日紹介したセッションポリシーによる制限は、攻撃者が「想定外のコマンド」を叩こうとした瞬間に AccessDenied を返す。この一瞬の拒絶こそが、システムを守る唯一の確実な方法だ。
コードを実装したら、必ず「あえて権限外の操作をして弾かれるか」をテストしてくれ。綺麗なコードを書くことよりも、「自分の書いたコードが、想定外の権限を拒絶する様子をテストすること」。これこそが、一流のエンジニアの流儀だ。
コメント