gcp-firewall-org-policy-replace

compute.organizations.setFirewallPolicy lets an attacker replace org/folder-level firewall policy, opening ports across all projects in scope.

derived gcp emits CanModifyConfiguration

match (effective permission)

{ "action": "compute.organizations.setFirewallPolicy", "resource_type": [ "compute.googleapis.com/Organization", "compute.googleapis.com/Folder" ] }

emit

source typeIdentity
target typeFirewall
source<principal (Identity)>
target<Firewall policy node (Firewall class) bound to the organization or folder>
permissionscompute.organizations.setFirewallPolicy
conditionsiam_permission
state logicACTIVE if compute.organizations.setFirewallPolicy effective on the org/folder resource and attacker controls a replacement policy; CONDITIONAL(scp_or_org_policy) if org policy restricts setFirewallPolicy; POTENTIAL if attacker can create a new policy but has not yet created one.

Narrative

{principal.name} can replace the firewall policy at the organization/folder level (compute.organizations.setFirewallPolicy), allowing substitution of a restrictive policy with an attacker-controlled one that opens ports to all networks and projects under that administrative boundary.

Raw rule rules/derived/gcp/firewall.yaml

id: gcp-firewall-org-policy-replace
emits: CanModifyConfiguration
description: compute.organizations.setFirewallPolicy lets an attacker replace org/folder-level firewall
  policy, opening ports across all projects in scope.
applies_to:
- gcp
match_effective_permission:
  action: compute.organizations.setFirewallPolicy
  resource_type:
  - compute.googleapis.com/Organization
  - compute.googleapis.com/Folder
emit:
  source_type: Identity
  target_type: Firewall
  source: <principal (Identity)>
  target: <Firewall policy node (Firewall class) bound to the organization or folder>
  permissions:
  - compute.organizations.setFirewallPolicy
  conditions:
  - iam_permission
  state_logic: ACTIVE if compute.organizations.setFirewallPolicy effective on the org/folder resource
    and attacker controls a replacement policy; CONDITIONAL(scp_or_org_policy) if org policy restricts
    setFirewallPolicy; POTENTIAL if attacker can create a new policy but has not yet created one.
  false_positive_note: compute.organizations.setFirewallPolicy is a high-severity primitive because it
    replaces protection at organization or folder scope (affecting all projects under that node). The
    attacker must either control an existing FirewallPolicy resource (CanModifyConfiguration on that policy)
    or be able to create one (compute.firewallPolicies.create). Verify that the replacement policy is
    attacker-controlled or creatable before rating this as ACTIVE. The blast radius is all projects and
    networks under the org/folder scope.
  narrative: '{principal.name} can replace the firewall policy at the organization/folder level (compute.organizations.setFirewallPolicy),
    allowing substitution of a restrictive policy with an attacker-controlled one that opens ports to
    all networks and projects under that administrative boundary.'
  derived_from:
  - '<iam_permission: compute.organizations.setFirewallPolicy on org/folder>'
  evidence:
    narrative_template: IAM effective permission compute.organizations.setFirewallPolicy on org/folder
      {scope.name} grants {principal.name} the ability to replace the firewall policy that governs all
      projects and networks under that administrative boundary.
move · open · esc close