【実務・中級編】 IAMポリシーの静的解析と権限過剰の自動検知 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

IAMの「とりあえずAdmin」が会社を滅ぼす:権限過剰をCI/CDで叩き潰す実戦的アプローチ

現場でインシデント対応をしていると、溜息が出るほど繰り返される光景がある。それは「開発スピードを優先するために、IAMロールに AdministratorAccess を付与したまま放置する」という行為だ。

君たちが書いたWebアプリのコードに脆弱性があり、万が一SSRF(サーバーサイドリクエストフォージェリ)やRCE(リモートコード実行)を許したとき、そのサーバーのIAMが「神(Admin)」だったらどうなるか。攻撃者は一瞬でクラウド環境の全権を掌握し、バックアップを消去し、顧客データを抜き出す。

「開発中だから」という言い訳は、攻撃者には通用しない。今日は、IAMの権限過剰を放置せず、CI/CDパイプラインの中で強制的に排除する泥臭い実戦技術を伝授する。

—

なぜ「静的解析」で防げないのか?

IAMポリシーをJSONで書くとき、多くのエンジニアが Action: ["s3:*"] のようなワイルドカードを使う。だが、真に恐ろしいのは、「使われていない権限」の放置だ。

例えば、当初はS3の全バケットへのアクセス権が必要だったが、半年経って特定のバケットしか使わなくなったとする。この「使わなくなった権限」が攻撃者の足場になる。手動で管理するのは不可能だ。だからこそ、AWS IAM Access Analyzerのような「分析ツール」をCI/CDに組み込む必要がある。

—

ステップ1:CI/CDでの権限チェック(Python + Boto3)

GitHub ActionsやGitLab CIのパイプラインで、ポリシーが「広すぎないか」を検証するスクリプトを走らせよう。以下は、Policy Simulatorを利用して、ポリシーが過剰に定義されていないかをチェックする基本的なロジックだ。

import boto3

def check_iam_policy_risk(policy_json):
    """
    IAMポリシーをシミュレートし、過剰な権限(Admin系)が含まれていないか判定
    """
    client = boto3.client('iam')
    
    # ここでは簡易的にワイルドカードの有無を確認
    # 本番では boto3 の simulate_principal_policy を使用するのが鉄則
    if '": "*"' in policy_json or '": ["*"]' in policy_json:
        print("[!] 警告: ワイルドカード権限が検出されました。即時修正してください。")
        return False
    
    print("[+] ポリシー構造は妥当です。")
    return True

# CI/CDパイプラインから呼び出す例
if __name__ == "__main__":
    test_policy = '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": ["s3:*"], "Resource": "*"}]}'
    if not check_iam_policy_risk(test_policy):
        exit(1) # テスト失敗としてパイプラインを止める

—

ステップ2:不要な権限を自動で見つける(AWS IAM Access Analyzer)

手書きのチェックも限界がある。AWSが提供する IAM Access Analyzer の「ポリシー生成機能」を活用するのが最も賢い。

1. アプリケーションをステージング環境で実行する。
2. その間のAPIコールをAccess Analyzerで追跡させる。
3. 実際に利用されたアクションのみを抽出して、最小権限ポリシーを自動生成する。

これを Terraform や CloudFormation のテンプレートに反映させるのが、我々プロの運用だ。

—

ステップ3:インフラ側でのガードレール(Service Control Policies)

アプリケーション層だけでなく、組織のトップレベル(AWS Organizations)で「ガードレール」を敷くことも忘れてはならない。以下の SCP は、特定のリージョン以外でのリソース作成を禁止し、かつIAMの書き換えを制限する鉄壁のルールだ。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyIAMChanges",
      "Effect": "Deny",
      "Action": [
        "iam:DeletePolicy",
        "iam:CreatePolicyVersion",
        "iam:PutRolePolicy"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotLike": {
          "aws:PrincipalArn": "arn:aws:iam::123456789012:role/SecurityAdminRole"
        }
      }
    }
  ]
}

—

現場のエンジニアへ送る最後の助言

セキュリティの要塞化とは、決して「難解なツールを導入すること」ではない。「必要最小限の権限以外はすべて拒否する」という思想を、コードとして表現し続けることだ。

  • AdministratorAccess を使っているなら、今日消せ。
  • Action: ["*"] を見つけたら、それは技術的負債ではなく「時限爆弾」だと認識しろ。
  • CI/CDが通らないポリシーは、デプロイさせない。

最初は面倒に感じるかもしれない。だが、一度この「最小権限の文化」がチームに根付けば、インシデントに怯える夜は劇的に減る。コードは嘘をつかない。君たちが書いたポリシーが、君たちのシステムを守る最後の盾になることを忘れないでほしい。

何かあれば、またいつでも相談に来るといい。現場からは以上だ。

コメント

タイトルとURLをコピーしました