【入門編】 クラウド環境におけるサーバーレス関数(Lambda)の権限昇格 – オフェンシブセキュリティ & リバースエンジニアリング防御ガイド

こんにちは!クラウドの裏側をのぞく冒険へようこそ。

皆さんは普段、AWSのLambda(ラムダ)のような「サーバーレス関数」を使ったことはありますか? 「サーバーの管理をしなくていいから、コードを書くだけで動いて超便利!」ですよね。私も開発の現場でよく使っています。

でも、この「サーバーレス」という仕組み、実はちょっとした「防犯上の落とし穴」が隠れていることがあるんです。今回は、このLambdaの中でこっそり行われる「権限の乗っ取り(権限昇格)」の仕組みと、それを防ぐための賢い対策について、身近な防犯にたとえながら優しく紐解いていきましょう!

—

1. サーバーレス関数(Lambda)って、家で例えるとどんな場所?

まず、Lambdaの仕組みを私たちの生活にたとえてみましょう。

Lambdaの関数は、いわば「自動販売機付きの小さなレンタルボックス」のようなものです。
あなたが「ジュースがほしいな」とボタンを押す(リクエストを送る)と、ボックスの中の小さなロボット(Lambda)がパッと目覚めて、ジュースを取り出し、あなたに渡してくれます。仕事が終わると、ロボットはすぐに消えちゃいます。

すごく便利ですが、ここで問題になるのが「そのロボット、どれくらいのお金や鍵を持たされているの?」という点です。

もし、このロボットが「お店全体の金庫の鍵」まで持っていたらどうでしょう? 万が一、悪巧みをしている人にロボットが操られてしまったら、金庫の中身が全部盗られてしまいますよね。

クラウドの世界でもこれと同じことが起きます。Lambdaが動くとき、そのプログラムにはAWSのリソースを触るための「お墨付き(権限=IAMロール)」が与えられているのですが、ここが強すぎると、大変なことになってしまうんです。

—

2. 攻撃者はどうやってLambdaを乗っ取るの?(環境変数の罠)

さて、ここから少しスリリングなお話です。レッドチーム(攻撃側)の視点になって、彼らがどうやってLambdaの裏をかくのかを見てみましょう。

攻撃者は、私たちが書いたコードの中にほんの小さな「隙(脆弱性)」を見つけ出します。例えば、外部からの入力をそのまま信用して処理してしまうようなプログラムです。

ここからが、今回のテーマの核心です。

ターゲットは「環境変数」と「一時ファイル」

Lambdaの実行環境(ロボットの中身)には、プログラムを動かすために「環境変数」という秘密のメモ帳が置かれています。ここには、データベースのパスワードや、秘密のAPIキーなどが書かれがちです。

さらに、Lambdaには /tmp という「ちょっとした荷物置き場(一時フォルダ)」が用意されています。

もし攻撃者がコードの隙をついて、この環境変数や一時フォルダをこっそり覗き見ることができたらどうなるでしょうか?

1. 環境変数から秘密の鍵をゲットする
LambdaがAWSの別のサービス(例えば、顧客データが入っているデータベース)にアクセスするための「合言葉」が環境変数にベタ書きされていた場合、攻撃者はそれをそっくりそのまま盗み出します。
2. 一時ファイルに悪意あるプログラムを仕込む
/tmp フォルダに書き込み権限がある場合、攻撃者はそこに自分が作った別のプログラム(バックドア)をこっそりダウンロードして実行させます。

「ちょっと待って! 私のコードは安全に作っているから大丈夫だよ」と思いましたか?
でも、もし使っている外部ライブラリ(npmパッケージなど)の中に、こっそり裏で悪いことをするコードが混ざっていたら……? 気づかないうちに、あなたのLambdaは内側から乗っ取られてしまうのです。

—

3. 実践!安全なLambdaを作るための防御テクニック

「うわ、怖くなってきた……どうすればいいの?」
大丈夫です!一歩ずつ、しっかり対策を学んでいけば怖くありません。ここからは、実務ですぐに使える具体的な防御策を見ていきましょう。

対策①:IAMロールは「最小限の権限」にする(お小遣い制にする)

一番大切なのは、Lambdaに持たせる「鍵(IAMロール)」を必要最小限にすることです。
先ほどのたとえで言えば、自動販売機のロボットには「ジュースを買うためのお札1枚分」だけを持たせ、金庫の鍵は絶対に持たせないようにします。

例えば、S3(ファイルの保存場所)の特定のフォルダを読むだけのLambdaなら、他のデータには一切触れないようなポリシーを設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SpecificFolderReadAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::your-company-bucket/public-images/*"
            /* 許可するのは特定の画像フォルダだけ。バケット全体へのアクセスは絶対に避ける! */
        }
    ]
}

このように、権限をギッチリ絞っておけば、万が一Lambdaが乗っ取られても、被害を最小限(爆風の範囲を狭く)に抑えることができます。

対策②:環境変数に秘密情報を直接書かない

「データベースのパスワード」や「APIの秘密鍵」を、Lambdaの環境変数にそのまま(平文で)書いていませんか? これは、玄関の鍵を植木鉢の下に隠すようなものです。

AWSには AWS Secrets Manager や AWS Systems Manager Parameter Store という、秘密情報を安全に金庫にしまっておく仕組みがあります。

コード側では、環境変数そのものではなく「金庫の場所(パラメータ名)」だけを持ち、実行する瞬間に取りにいくようにしましょう。

Node.js(JavaScript)を例に、安全に秘密情報を取得するコードの書き方を見てみましょう。

const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");

// クライアントの初期化(AWSの公式ツールを使用)
const client = new SecretsManagerClient({ region: "ap-northeast-1" });

exports.handler = async (event) => {
    try {
        // 金庫(Secrets Manager)からパスワードを取り出す命令
        const command = new GetSecretValueCommand({ SecretId: "my-database-password" });
        const response = await client.send(command);
        
        // 秘密情報を安全に変数に格納
        const dbPassword = response.SecretString;
        
        // ここでデータベース接続処理を行う(パスワードはコードや環境変数に直接書かない!)
        console.log("安全に秘密情報を取得できました!");
        
        return { statusCode: 200, body: "成功!" };
    } catch (error) {
        console.error("秘密情報の取得に失敗しました", error);
        throw error;
    }
};

対策③:一時フォルダ(/tmp)の扱いを見直す

/tmp フォルダは一時的な計算やファイルのダウンロードによく使われますが、ここに不審なファイルが書き込まれていないか、また、不要になったファイルがそのまま残っていないか注意が必要です。
プログラム内で外部から受け取ったファイル名をそのまま /tmp のパスに結合してしまうと、悪意あるファイル名(例: ../../etc/passwd のようなパストラバーサル攻撃)によって、意図しない場所が書き換えられる危険性があります。ファイル名を扱うときは、必ず安全な名前に置き換える(サニタイジングする)処理を挟みましょう。

—

4. まとめ:今日からできるセキュリティの一歩

サーバーレス関数(Lambda)の権限昇格は、一見すると難しそうなサイバー攻撃に見えますが、本質は「ロボットに強すぎる権限を持たせないこと」と「秘密の鍵を安全な場所にしまうこと」の2つに尽きます。

1. IAMロールは最小限の権限(お小遣い制)にする
2. パスワードや秘密鍵は環境変数にベタ書きせず、Secrets Managerを使う
3. 外部からの入力を信用せず、コードと一時フォルダを綺麗に保つ

セキュリティ対策は、一度にすべてを完璧にする必要はありません。「あ、うちの環境変数、パスワードがそのまま入ってるかも……」と思った方は、明日さっそくそこを見直すことから始めてみてくださいね。

一歩ずつ、安全なクラウドライフを作っていきましょう!

コメント

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