An Azure service that provides protection for web apps.
The behavior difference is explained by how geo-filtering works in current WAF custom rules and by best-practice changes that affect internal/private IPs.
Key points from the current WAF behavior:
- Geo-filtering is based on
RemoteAddr→ country mapping- Geo-filtering custom rules work by mapping each request’s IP address to a country/region.
- When creating geomatch rules with PowerShell/ARM, the match variable must be
RemoteAddrand the operatorGeomatch. - If the IP cannot be mapped to a country/region, it’s treated as “Unknown”.
“Geo-filtering works based on mapping each request's IP address to a country or region. There might be some IP addresses in the data set that aren't yet mapped to a country or region. To avoid accidentally blocking legitimate users, Application Gateway's WAF allows requests from unknown IP addresses.”
- The ZZ (Unknown) country code is now required in geo rules
- Current guidance explicitly calls out that ZZ must be included whenever geo-filtering is used:
If the new Terraform-based WAF policy’s geomatch rules do not include“Include the country code ZZ whenever you use geo-filtering. The ZZ country code (or Unknown country/region) captures IP addresses that aren't yet mapped to a country or region in our dataset. This avoids false positives.”
ZZin the allowlist, any IPs that resolve to “Unknown” (which often includes private/VNet address space or newly added ranges) can be blocked, resulting inAccess denied with code 403. Found condition 0 in RemoteAddr. The older, manually created policy may:- Have been created before this stricter guidance, or
- Implicitly allowed unknown IPs, or
- Have a slightly different custom-rule ordering or conditions that effectively bypassed this issue.
- Custom rules run before managed rules and are decisive
- WAF policies consist of custom rules and managed rule sets.
- Custom rules are evaluated first and in priority order; once a match is found, lower-priority rules are not processed.
If the Terraform deployment created a custom geomatch rule with a“When both types of rules are present, the WAF processes custom rules before it processes the rules in a managed rule set… After the WAF matches a rule with a request, it applies the corresponding action… After the WAF processes such a match, it doesn't process rules that have lower priorities.”
BLOCKaction that:- Uses
RemoteAddrwithGeomatch, and - Does not include
ZZin the allowed list,
- Why the old and new policies differ despite “same configuration”
Even with nominally identical configuration, differences can arise from:
- Updated geo-IP datasets: IPs that previously mapped to a specific country may now map to “Unknown” or vice versa.
- Changes in WAF engine/ruleset behavior: newer ruleset versions and engine improvements can change how unknown IPs are treated unless
ZZis explicitly handled. - Slight differences in custom rule definitions or priorities between the portal-created policy and the Terraform-created policy.
ZZin geo-filtering rules. If the new policy’s geomatch rule is structured as an allowlist (allow specific countries, block everything else) withoutZZ, internal addresses can be unintentionally blocked.
Practical remediation steps based on current guidance:
- Review the geomatch custom rules in the new WAF policy
- Confirm that the match variable is
RemoteAddrand operator isGeomatch. - Check the list of countries/regions in the allowlist.
- Confirm that the match variable is
- Add
ZZto the geomatch rule- Ensure the geomatch rule explicitly includes the ZZ country code in the allowed set so that unknown/private/VNet IPs are not blocked.
- Verify rule priority and action
- Confirm that the geomatch rule’s priority and action (
ALLOWvsBLOCK) are aligned with the original working policy. - Ensure that any
BLOCKgeomatch rules are not inadvertently catching internal traffic before anALLOWrule can match.
- Confirm that the geomatch rule’s priority and action (
- Run in Detection mode when changing rules
- As recommended, run the WAF in Detection mode temporarily when adjusting rules to collect logs and confirm that internal/VNet traffic is no longer being flagged before switching back to Prevention mode.
“Run a newly deployed WAF in detection mode for a short period in a production environment… before transitioning to prevention mode. It also helps reduce the occurrence of unexpected blocked traffic.”
These differences in how unknown/“ZZ” IPs are handled in geomatch rules explain why the older policy continues to work while the newly provisioned Terraform-based policy geo-blocks VNet IPs.
References: