azure-swa-sourcecontrols-write

Repoint SWA's source repository to an attacker-controlled repo, modifying build code.

derived azure emits CanModifyCode

match (effective permission)

{ "action": "Microsoft.Web/staticSites/sourcecontrols/write", "scope_type": "resource|resourceGroup|subscription" }

where

?swa is the SWA (node_type == ApplicationPlatform) ?runner exists: a BuildWorker or the SWA's default build runner (CI/CD platform)

emit

source typeIdentity
target typeCompute
source<principal>
target?swa
conditionsservice_state trigger_exists
state logicACTIVE when the principal effectively holds sourcecontrols/write, the SWA's build is configured for continuous deployment (linked repo with auto-sync), and a trigger will pull the attacker repo. CONDITIONAL(trigger_exists, service_state) when the permission is present but continuous deployment is not enabled or build is paused. BLOCKED if a deny assignment covers this action or if source control integration is disabled on the SWA.

Narrative

{principal.name} can repoint the source control of Static Web App {swa.name} to an attacker-controlled repository (Microsoft.Web/staticSites/sourcecontrols/write). On the next build, the SWA will pull and deploy code from the attacker repository.

Raw rule rules/derived/azure/staticwebapps.yaml

id: azure-swa-sourcecontrols-write
emits: CanModifyCode
description: Repoint SWA's source repository to an attacker-controlled repo, modifying build code.
applies_to:
- azure
match_effective_permission:
  action: Microsoft.Web/staticSites/sourcecontrols/write
  scope_type: resource|resourceGroup|subscription
where:
- ?swa is the SWA (node_type == ApplicationPlatform)
- '?runner exists: a BuildWorker or the SWA''s default build runner (CI/CD platform)'
emit:
  source_type: Identity
  target_type: Compute
  source: <principal>
  target: ?swa
  permissions: []
  conditions:
  - service_state
  - trigger_exists
  state_logic: ACTIVE when the principal effectively holds sourcecontrols/write, the SWA's build is configured
    for continuous deployment (linked repo with auto-sync), and a trigger will pull the attacker repo.
    CONDITIONAL(trigger_exists, service_state) when the permission is present but continuous deployment
    is not enabled or build is paused. BLOCKED if a deny assignment covers this action or if source control
    integration is disabled on the SWA.
  confidence: 0.95
  derived_from:
  - Microsoft.Web/staticSites/sourcecontrols/write effective permission
  false_positive_note: Only exploitable when the SWA has continuous deployment enabled and will pull from
    the linked repository on next sync. A manual-only SWA with no auto-deploy remains CONDITIONAL(trigger_exists)
    unless the attacker can also trigger the build. A rotated/removed source-control link invalidates
    this edge. Requires the source repository to be accessible to the SWA build agent (not a hard guarantee
    for cross-provider repos; model as POTENTIAL if cross-org).
  narrative: '{principal.name} can repoint the source control of Static Web App {swa.name} to an attacker-controlled
    repository (Microsoft.Web/staticSites/sourcecontrols/write). On the next build, the SWA will pull
    and deploy code from the attacker repository.'
move · open · esc close