aws-bedrock-action-group-lambda-redirect

Redirect a Bedrock Agent action group's backing Lambda to an attacker-controlled Lambda, injecting code into the agent's execution path.

derived aws emits CanModifyCode

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanModifyConfiguration {'agent': None}

where

node_type(?agent) == GenericCompute ?agent.provider_type == 'AWS::Bedrock::Agent' ?principal has EFFECTIVE bedrock:UpdateAgentActionGroup on ?agent ?principal has EFFECTIVE bedrock:PrepareAgent on ?agent

emit

source typeIdentity
target typeCompute
source?principal
target?agent
permissionsbedrock:UpdateAgentActionGroup bedrock:PrepareAgent
conditionsiam_permission
state logicACTIVE when the principal holds both bedrock:UpdateAgentActionGroup and bedrock:PrepareAgent on the Agent (the change requires PrepareAgent to take effect); CONDITIONAL(iam_permission) if PrepareAgent is missing or scope is ambiguous. An SCP or explicit deny on either action makes this BLOCKED. Note: an existing InvokeAgent trigger means the redirected Lambda fires on the next agent turn without further attacker action (run path established).

Narrative

{principal.name} can redirect Bedrock Agent {agent.name}'s action group to point at an attacker-controlled Lambda (bedrock:UpdateAgentActionGroup + bedrock:PrepareAgent); when the Agent runs, it invokes that Lambda, executing attacker code in the action-group Lambda's execution role. See lambda rules for the full CanExecuteAs derivation.

Raw rule rules/derived/aws/bedrock.yaml

id: aws-bedrock-action-group-lambda-redirect
emits: CanModifyCode
description: Redirect a Bedrock Agent action group's backing Lambda to an attacker-controlled Lambda,
  injecting code into the agent's execution path.
match:
- - principal: null
  - CanModifyConfiguration
  - agent: null
where:
- node_type(?agent) == GenericCompute
- ?agent.provider_type == 'AWS::Bedrock::Agent'
- ?principal has EFFECTIVE bedrock:UpdateAgentActionGroup on ?agent
- ?principal has EFFECTIVE bedrock:PrepareAgent on ?agent
emit:
  source_type: Identity
  target_type: Compute
  source: ?principal
  target: ?agent
  permissions:
  - bedrock:UpdateAgentActionGroup
  - bedrock:PrepareAgent
  conditions:
  - iam_permission
  state_logic: 'ACTIVE when the principal holds both bedrock:UpdateAgentActionGroup and bedrock:PrepareAgent
    on the Agent (the change requires PrepareAgent to take effect); CONDITIONAL(iam_permission) if PrepareAgent
    is missing or scope is ambiguous. An SCP or explicit deny on either action makes this BLOCKED. Note:
    an existing InvokeAgent trigger means the redirected Lambda fires on the next agent turn without further
    attacker action (run path established).'
  confidence: min(contributing_confidences) * 0.9
  derived_from:
  - <CanModifyConfiguration edge_id for ?principal -> ?agent>
  false_positive_note: "Changing only the action group's OpenAPI schema (not the Lambda ARN field) does\
    \ NOT yield code control \u2014 do not emit this edge for schema-only changes. Verify that the principal's\
    \ effective permissions cover the Lambda ARN field in UpdateAgentActionGroup (the API updates the\
    \ whole action group object, so IAM-level this is all-or-nothing, but check SCP/boundary restricting\
    \ the call). PrepareAgent is required to deploy the draft; without it the change sits in DRAFT state\
    \ and the agent continues running the old action group. Escalation to the Lambda execution role: cite\
    \ aws-lambda-execute-as-via-code (lambda rules) which fires on CanModifyCode(?principal, ?lambda)\
    \ + ExecutesAs(?lambda, ?lambdaRole); do not re-derive CanExecuteAs here."
  narrative: '{principal.name} can redirect Bedrock Agent {agent.name}''s action group to point at an
    attacker-controlled Lambda (bedrock:UpdateAgentActionGroup + bedrock:PrepareAgent); when the Agent
    runs, it invokes that Lambda, executing attacker code in the action-group Lambda''s execution role.
    See lambda rules for the full CanExecuteAs derivation.'
move · open · esc close