IAMは「城の門」だ。その鍵を適当に配るな
現場を見ていると、多くのエンジニアが「動くこと」を優先して、IAMポリシーに Resource: "*" と書き込み、Action: "*" を付与している。正直に言おう。それは「鍵をかけたまま扉を全開にして放置している」のと同じだ。
AWSやGCPでクラウドを運用する際、最も致命的なインシデントは「権限の過剰付与」から始まる。攻撃者は、たった一つの脆弱なWebサーバーのSSRF(Server-Side Request Forgery)からIAMロールを奪い取り、そこから環境全体を蹂躙する。今日は、その「最悪のシナリオ」を未然に防ぐための、プロとしてのシミュレーション手法を叩き込む。
—
攻撃者の視点:なぜ「権限の過剰付与」が狙われるのか
攻撃者は、あなたのコードが完璧であるとは微塵も信じていない。彼らが狙うのは、アプリケーションがインフラに対して持つ「過大な権限」だ。
例えば、EC2インスタンス上で動作するPHPアプリケーションに、S3全域への読み書き権限が与えられているとする。ここで file_get_contents() などを使ったSSRF脆弱性が一つでもあれば、攻撃者はインスタンスメタデータサービス(IMDSv2)を叩いて一時的な認証情報を抜き取り、S3バケット内の機密データをすべて吸い出す。
これが現場のリアルだ。 権限が絞られていれば、攻撃者は「そのインスタンスのバックアップ」程度で足止めされるが、過剰な権限があれば「全顧客データの流出」という致命傷になる。
—
IAM Policy Simulatorを使い倒せ
「動いたからOK」でリリースするのは、プロの仕事ではない。必ず IAM Policy Simulator を使い、そのポリシーが意図した最小権限(Least Privilege)に収まっているかを確認せよ。
シミュレーションのステップ
1. 評価対象のポリシーを貼り付ける: AWSコンソール上のツールに、作成したJSONを投入する。
2. 実行アクションを選択: 開発者が想定している「許容すべきアクション(例: s3:GetObject)」を選択する。
3. コンテキストを指定: リソースのARNや、アクセス元IPアドレスなどの条件を可能な限り具体的に入力する。
4. 結果を分析: Allowed となった場合、そのアクションが本当に必要か自問せよ。もし不要なら、今すぐ削れ。
—
【実践】セキュアなIAMポリシーの定義(Terraform例)
以下は、特定のS3バケットに対する読み取りのみを許可し、かつ特定のIPアドレスからのみアクセスを許容するセキュアなIAMポリシーの定義例だ。
# セキュアなS3アクセス用IAMポリシーの定義
resource "aws_iam_policy" "web_app_s3_read_only" {
name = "WebAppS3ReadOnlyPolicy"
description = "特定のS3バケットへの読み取りのみを許可する"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowSpecificBucketAccess"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
]
# ワイルドカードを避け、リソースを限定する
Resource = [
"arn:aws:s3:::my-production-app-assets",
"arn:aws:s3:::my-production-app-assets/*"
]
# 条件句でアクセス元を制限(攻撃者が認証情報を持ち出しても別環境では使えないようにする)
Condition = {
IpAddress = {
"aws:SourceIp" = "203.0.113.0/24" # 会社のゲートウェイIP等
}
}
}
]
})
}
—
現場で守るべき「3つの鉄則」
コードを書くとき、インフラを構築するとき、以下の鉄則を忘れてはならない。
1. ワイルドカードは禁忌: Resource: "*" や Action: "s3:*" は、緊急対応時を除き、リリース前に必ず具体的な定義へ書き換えろ。
2. IMDSv2を強制せよ: EC2を利用している場合、古いメタデータサービスはSSRF攻撃に弱い。必ず MetadataHopLimit: 1 と設定し、トークンベースの認証を強制すること。
3. シミュレーションは「CI/CD」の一部にする: 手動確認に頼るな。AWS CLI の simulate-principal-policy コマンドをCIパイプラインに組み込み、過剰な権限が含まれていたらデプロイを失敗させる仕組みを作るのだ。
CIで使える検証コマンド例(シェル)
# 権限チェックを自動化するスクリプトの一例
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/MyUser \
--action-names s3:DeleteBucket \
--output text --query 'EvaluationResults[0].EvalDecision'
# ここで "allowed" が返ってきたら、CIを即座に停止させて報告させる
最後に:セキュリティは「倒れないための準備」だ
「面倒くさい」と感じるその一手間が、数億円の損害賠償や、顧客の信頼失墜を防ぐ。エンジニアとして、コードの美しさと同じくらい、「権限の美しさ」にもこだわってほしい。
何かあれば、いつでも相談に来い。ただし、IAMポリシーのJSONを丸ごと貼り付けて「これで合ってますか?」と聞くのはやめろ。まずは自分でPolicy Simulatorを通し、その結果を提示してから議論しよう。それが、プロのエンジニアの流儀だ。
コメント