AWS Lambdaの「万能IAMロール」は死を招く:最小権限の原則を現場で叩き込む
「Lambdaなんてただのスクリプトだし、とりあえず AdministratorAccess 付与して動かしておけばいいか」
もし君のチームでそんな会話が聞こえてきたら、即座に耳を塞いでそのPCをシャットダウンさせるべきだ。セキュリティの現場で「とりあえず」という言葉は、爆弾の安全装置を外すのと同じ意味を持つ。
今日は、暗号理論の堅牢性(AESやRSA)以前の、現代のクラウドインフラにおける「侵入経路の遮断」について、LambdaのIAM分離という観点から語ろう。
1. なぜ「万能ロール」が攻撃者のパラダイスなのか
攻撃者は、Lambdaのコード内に存在する小さな脆弱性(例えば、依存ライブラリのRCE:リモートコード実行)を見逃さない。一度Lambdaの実行環境を掌握されたらどうなるか?
権限が過剰なIAMロールが付与されていた場合、攻撃者はそのLambdaから:
- S3バケットの全データを窃取する
- DynamoDBの顧客情報をダンプする
- 他のEC2インスタンスを乗っ取るためのIAMクレデンシャルを生成する
これが「水平展開(Lateral Movement)」だ。Lambda一つを侵されただけで、インフラ全体が芋づる式に崩壊する。これを防ぐ唯一の防御策が「関数ごとの権限分離」である。
2. 楕円曲線暗号(ECC)を語る前に、IAMポリシーの「暗号」を解く
ここで少し暗号の話を挟もう。TLS通信で使われるRSAやECC(楕円曲線暗号)は、通信経路の「完全性」と「機密性」を保証する。しかし、LambdaのIAMは、いわば「操作の論理境界」を決定する鍵だ。
AESでデータを暗号化していても、LambdaがS3のs3:GetObject権限を持っていれば、攻撃者はその暗号化されたファイルをそのまま盗み出せる。鍵(IAM)が盗まれていれば、どれほど強力な暗号も無意味だ。だからこそ、IAMの設計は「最も強固な鍵管理」として扱うべきなんだ。
3. 実践:最小権限のIAMポリシー設計
例えば、S3の特定のフォルダにログを出力するだけのLambdaなら、他の権限は一切不要だ。以下のIAMポリシーをテンプレートとして参考にしてほしい。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificS3PutOnly",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-secure-log-bucket/logs/*"
}
]
}
このポリシーのポイントは、Actionをs3:PutObjectに限定し、Resourceも特定のパスまで絞り込んでいることだ。もし攻撃者がこのLambdaを乗っ取ったとしても、既存のログを読み取る(s3:GetObject)ことさえできない。
4. 【コード実装】Node.jsにおける環境変数とSDKの分離
Lambdaのコード内でSDKを使う際も、グローバルに認証情報を渡さず、特定の権限を意識した実装が必要だ。
// AWS SDK v3 を使用したセキュアな設計
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
// クライアントを関数外で初期化することで、実行環境の再利用時にセッションを維持
// ただし、権限はIAMロールにより「そのLambdaが実行可能な範囲」に物理的に制限されている
const s3Client = new S3Client({ region: "ap-northeast-1" });
exports.handler = async (event) => {
try {
const params = {
Bucket: "my-secure-log-bucket",
Key: `logs/${Date.now()}.json`,
Body: JSON.stringify(event)
};
// 特定のバケットのみに書き込む最小限の操作
await s3Client.send(new PutObjectCommand(params));
return { statusCode: 200, body: "Logged successfully" };
} catch (err) {
// 攻撃者に詳細なエラーを返さない(情報漏洩の防止)
console.error("Internal Error");
return { statusCode: 500, body: "Internal Server Error" };
}
};
5. 後輩エンジニアへ:明日からやるべきこと
1. IAMの棚卸し: AWSマネジメントコンソールを見て、「AdministratorAccess」や「PowerUserAccess」がついているLambdaがないか確認しろ。
2. IAM Access Analyzerの活用: どの権限が実際に使われているかを分析し、使われていない権限を削除する。
3. 環境変数の分離: データベースのパスワードやAPIキーをLambdaの環境変数に直書きしてはいけない。AWS Systems Manager Parameter StoreやSecrets Managerを使い、Lambdaには「読み取り専用」の権限だけを与える。
セキュリティとは、「完璧な防御」を目指すことではなく、「侵入された後の被害をいかに局所化するか」というデザインの問題だ。
君たちが書く一行のコード、設定する一行のJSONが、顧客の信頼を支えている。その重みを忘れず、明日のデプロイメントに臨んでほしい。質問があればいつでも来い。現場からは以上だ。
コメント