azure-containerapps-identity-endpoint-token

Attacker-controlled code in a container can mint a bearer token for each reachable bound managed identity via the local identity endpoint.

derived azure emits CanRetrieveToken

match

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

{'app': None} ExecutesAs {'mi': None}

emit

source<containerApp>
target<managed identity reachable from the running container>

Narrative

Attacker code running in {app.name} can request a bearer token for {mi.name} from the local identity endpoint ($IDENTITY_ENDPOINT, X-IDENTITY-HEADER) with no container credential.

Raw rule rules/derived/azure/containerapps.yaml

id: azure-containerapps-identity-endpoint-token
emits: CanRetrieveToken
description: Attacker-controlled code in a container can mint a bearer token for each reachable bound
  managed identity via the local identity endpoint.
match:
- - app: null
  - ExecutesAs
  - mi: null
emit:
  source: <containerApp>
  target: <managed identity reachable from the running container>
  permissions: []
  note: 'In-container: GET $IDENTITY_ENDPOINT?resource=<aud>&api-version=2019-08-01 with header X-IDENTITY-HEADER:
    $IDENTITY_HEADER. NOT IMDS 169.254.169.254. Also emits ExposesCredential(app -> mi).'
  false_positive_note: 'Only fires when the app has a managed identity AND that MI is reachable from the
    executing container: honor identitySettings.lifecycle (an MI with lifecycle None (ACR-pull/scale only)
    or Init is NOT reachable from the main container). No MI => do NOT emit.'
  narrative: Attacker code running in {app.name} can request a bearer token for {mi.name} from the local
    identity endpoint ($IDENTITY_ENDPOINT, X-IDENTITY-HEADER) with no container credential.
move · open · esc close