← All field notes
gcpcloud armorfor responders

When the WAF vanishes: Cloud Armor policy tampering

An attacker with securityAdmin can quietly edit a Cloud Armor policy to strip the WAF and expose a backend. Restore the whole policy from IaC, not the one rule you noticed.

Not every attack adds something. Some quietly remove a defense, and the only outward sign is traffic that used to be blocked suddenly getting through.

How the attack works

An attacker holding the compute.securityAdmin role edits a Cloud Armor security policy attached to a production backend service. They delete a deny or WAF rule and insert a permissive allow rule ahead of the default deny, so requests the WAF previously dropped now reach the backend unfiltered. With the protective layer gone, they probe the exposed backend for application weaknesses. The change is a quiet control-plane edit, recorded in the Cloud Audit Logs Admin Activity entries for compute.securityPolicies.patch, addRule, and removeRule, while the Cloud Armor request logs show the newly admitted traffic. This maps to T1562, Impair Defenses, and T1190, Exploit Public-Facing Application.

Why it works

The securityAdmin role was held too broadly and policy changes were not gated through review. Because editing the policy weakens protection silently, nothing breaks and no alert fires unless you are watching for the change itself.

How to fix it

Manually re-adding the one rule you spotted is a trap: the policy may have had several edits, and rule ordering matters, so you risk leaving the attacker’s allow or its position intact. The non-obvious move is to treat the policy as infrastructure-as-code and re-apply the entire known-good definition from source, which restores every rule and the ordering deterministically and catches edits you never noticed. Then revoke the editing principal’s securityAdmin. Durably, restrict securityAdmin to a minimal set, require policy changes through reviewed IaC, and alert on any out-of-band securityPolicies change.

Practice it

We built this as a GraphLattice Range scenario so responders learn to restore the full policy from IaC and scope the exposure window.