aws-lambda-execute-as-via-config-injection

Inject code via env/layer/handler config change, then run, as the role.

derived aws emits CanExecuteAs

match

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

{'principal': None} CanModifyConfiguration {'function': None} {'function': None} ExecutesAs {'role': None}

where

node_type(?function) == ServerlessFunction

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'principal': None} CanInvoke {'function': None}

emit

source typeIdentity
target typeIdentity
source?principal
target?role
permissionslambda:UpdateFunctionConfiguration lambda:InvokeFunction?
conditionstrigger_exists
state logicif matched(optional[0]) or trigger_exists(?function): ACTIVE else CONDITIONAL(trigger_exists)

Narrative

{principal.name} can change the configuration of {function.name} (lambda:UpdateFunctionConfiguration) to inject an attacker layer/handler, then run it as {role.name}.

Raw rule rules/derived/aws/lambda.yaml

id: aws-lambda-execute-as-via-config-injection
emits: CanExecuteAs
description: Inject code via env/layer/handler config change, then run, as the role.
match:
- - principal: null
  - CanModifyConfiguration
  - function: null
- - function: null
  - ExecutesAs
  - role: null
where:
- node_type(?function) == ServerlessFunction
optional:
- - principal: null
  - CanInvoke
  - function: null
emit:
  source_type: Identity
  target_type: Identity
  source: ?principal
  target: ?role
  permissions:
  - lambda:UpdateFunctionConfiguration
  - lambda:InvokeFunction?
  conditions:
  - trigger_exists
  state_logic: 'if matched(optional[0]) or trigger_exists(?function): ACTIVE else CONDITIONAL(trigger_exists)'
  confidence: min(contributing_confidences) * 0.8
  derived_from:
  - <CanModifyConfiguration edge_id>
  - <ExecutesAs edge_id>
  - <CanInvoke edge_id?>
  false_positive_note: UpdateFunctionConfiguration yields code execution mainly via attacker-controlled
    layers (requires lambda:PublishLayerVersion / an accessible layer) or by overwriting the handler/runtime;
    a bare env-var change is weaker (0.8 prior). Requires a run path (invoke or trigger) like the code
    rule.
  narrative: '{principal.name} can change the configuration of {function.name} (lambda:UpdateFunctionConfiguration)
    to inject an attacker layer/handler, then run it as {role.name}.'
move · open · esc close