Back to blog
AzureBest PracticesCloud SecurityNetworking

Azure Front Door Has No WAF Policy: Why It Matters and How to Fix It

Azure Front Door without a WAF policy exposes your apps to injection, XSS, and bot attacks. Learn how to attach a WAF policy and prevent the gap with policy-as-code.

TL;DR

This check flags any Azure Front Door profile that ships traffic without a Web Application Firewall (WAF) policy attached, leaving your apps exposed to common web attacks. Create a WAF policy in Prevention mode and associate it with your Front Door security policy to close the gap.

Azure Front Door sits at the edge of your network, routing user traffic to your backends across regions. Because it terminates HTTP/HTTPS connections and acts as a global entry point, it is the natural place to inspect and filter requests before they ever reach your application. Without a WAF policy attached, Front Door becomes a fast, well-engineered pipe that happily forwards SQL injection attempts, cross-site scripting payloads, and bot traffic straight to your origin.

The frontdoor_nowaf check looks at each Front Door profile and verifies that a WAF policy is associated with its security policies. If none is found, the check fails.


What this check detects

The check inspects your Azure Front Door (both the classic and Standard/Premium tiers) and determines whether a WAF policy is linked to the front-end endpoints. In the newer Front Door Standard/Premium model, this association happens through a security policy that ties a WAF policy to one or more domains. In the classic model, the WAF policy is associated directly with the front-end host.

A failing result means HTTP traffic is reaching your backends with no inspection layer at the edge. There may be a network security group or an application-level firewall further down the stack, but nothing is filtering Layer 7 attacks at the global front door.

Note: A WAF policy on Front Door operates at the edge, before traffic is routed to a backend pool. This is different from Azure Application Gateway WAF, which runs regionally. The two can coexist, but Front Door WAF is your first line of defense for globally distributed apps.


Why it matters

A public-facing endpoint without a WAF is one of the most common ways web applications get compromised. The risks are not theoretical:

  • Injection attacks. Without managed rule sets, requests carrying SQL injection or command injection payloads pass through untouched. A vulnerable parameter in your app is all an attacker needs.
  • Cross-site scripting (XSS). Reflected and stored XSS attempts are not filtered, so any input-handling weakness becomes directly exploitable.
  • Bots and credential stuffing. The Front Door WAF includes a managed bot protection rule set. Without it, scrapers and brute-force tools hit your login and API endpoints unthrottled.
  • Layer 7 DDoS. Front Door provides infrastructure DDoS protection, but application-layer floods (think repeated expensive queries) need WAF rate limiting to mitigate.
  • Compliance gaps. Frameworks like PCI DSS expect a WAF or equivalent in front of cardholder-data environments. A missing policy can turn into an audit finding.

The business impact is straightforward. A single unfiltered injection vulnerability can lead to data exfiltration, and the cleanup, disclosure, and reputation costs dwarf the few dollars per month a WAF policy adds to your bill.

Warning: Front Door WAF on the Premium tier includes managed rule sets and bot protection that the Standard tier does not. If you are on Standard, you can still attach a custom WAF policy, but you will not get the Microsoft-managed Default Rule Set. Factor tier into your remediation plan.


How to fix it

Remediation has two steps: create a WAF policy, then associate it with your Front Door. The exact commands differ between the classic and Standard/Premium tiers. The examples below cover Front Door Standard/Premium, which is the current default.

Step 1: Create a WAF policy

Using the Azure CLI with the front-door extension:

az extension add --name front-door

az network front-door waf-policy create \
  --resource-group my-rg \
  --name myWafPolicy \
  --sku Premium_AzureFrontDoor \
  --mode Prevention \
  --disabled-state false

Setting --mode Prevention means the WAF blocks matching requests. The alternative, Detection, only logs them. Start in Detection if you are worried about false positives, then switch to Prevention once you have tuned the rules.

Step 2: Add a managed rule set (Premium tier)

az network front-door waf-policy managed-rules add \
  --resource-group my-rg \
  --policy-name myWafPolicy \
  --type Microsoft_DefaultRuleSet \
  --version 2.1 \
  --action Block

Step 3: Associate the policy with a security policy

This is the step the check actually validates. The WAF policy must be linked to your Front Door domains through a security policy:

az afd security-policy create \
  --resource-group my-rg \
  --profile-name myFrontDoorProfile \
  --security-policy-name myWafSecurityPolicy \
  --domains "/subscriptions//resourceGroups/my-rg/providers/Microsoft.Cdn/profiles/myFrontDoorProfile/afdEndpoints/myEndpoint" \
  --waf-policy "/subscriptions//resourceGroups/my-rg/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/myWafPolicy"

Warning: Switching a freshly created policy straight to Prevention mode can break legitimate traffic if your app sends payloads that look like attacks (for example, content with embedded HTML). Run in Detection mode for a few days, review the FrontDoorWebApplicationFirewallLog, and add exclusions before flipping to Prevention.

Portal steps

  1. Go to Front Door and CDN profiles and open your profile.
  2. Under Security, select Web application firewall.
  3. Click + Add, then either select an existing WAF policy or create a new one.
  4. Choose the domains the policy should protect and save.

Terraform example

If you manage Front Door as code, attach the WAF policy directly in your configuration so it never drifts:

resource "azurerm_cdn_frontdoor_firewall_policy" "waf" {
  name                = "myWafPolicy"
  resource_group_name = azurerm_resource_group.rg.name
  sku_name            = "Premium_AzureFrontDoor"
  enabled             = true
  mode                = "Prevention"

  managed_rule {
    type    = "Microsoft_DefaultRuleSet"
    version = "2.1"
    action  = "Block"
  }
}

resource "azurerm_cdn_frontdoor_security_policy" "sec" {
  name                     = "myWafSecurityPolicy"
  cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.profile.id

  security_policies {
    firewall {
      cdn_frontdoor_firewall_policy_id = azurerm_cdn_frontdoor_firewall_policy.waf.id

      association {
        domain {
          cdn_frontdoor_domain_id = azurerm_cdn_frontdoor_endpoint.endpoint.id
        }
        patterns_to_match = ["/*"]
      }
    }
  }
}

Tip: Keep one well-tuned WAF policy and reuse it across multiple Front Door endpoints rather than creating a new policy per app. Centralizing the policy means your rule exclusions and rate limits live in one place, which is far easier to audit and update.


How to prevent it from happening again

Fixing one profile is good. Making sure the next Front Door someone spins up cannot ship without a WAF is better. A few layers work well together:

Azure Policy

Use a built-in or custom Azure Policy to audit or deny Front Door resources that lack a WAF association. Assign it at the subscription or management group scope so it covers every team:

{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Cdn/profiles/securityPolicies"
      },
      {
        "field": "Microsoft.Cdn/profiles/securityPolicies/parameters.wafPolicy.id",
        "exists": "false"
      }
    ]
  },
  "then": {
    "effect": "audit"
  }
}

Start with audit to find existing gaps, then move to deny once teams have remediated.

CI/CD gates

If your Front Door definitions live in Terraform or Bicep, run a policy-as-code scan in the pipeline before apply. Tools like Checkov, tfsec, or a custom OPA policy can fail the build when a Front Door has no associated firewall policy.

# Example: fail the pipeline if Checkov finds a missing WAF
checkov -d ./infra --check CKV_AZURE_121 --hard-fail-on HIGH

Tip: Pair the pipeline scan with continuous monitoring in Lensix so that even manually created or click-ops Front Door profiles get caught. Pipeline checks only cover what flows through the pipeline, and edge resources have a habit of being created in a hurry during an incident.


Best practices

  • Run in Prevention mode in production. Detection mode is for tuning, not for steady state. A WAF that only logs is a smoke detector with no alarm.
  • Enable the Microsoft Default Rule Set and Bot Manager. On Premium, these managed rules cover the OWASP Top 10 and known bad bots with minimal effort.
  • Add rate limiting on sensitive paths. Custom rules that throttle requests to login, signup, and password-reset endpoints blunt credential stuffing and brute-force attacks.
  • Geo-filter where it makes sense. If your app only serves specific countries, block traffic from regions you never expect to see legitimate users from.
  • Ship WAF logs to Log Analytics. Send FrontDoorWebApplicationFirewallLog to a workspace so you can alert on blocked attack spikes and review false positives.
  • Tune exclusions deliberately. When a managed rule blocks legitimate traffic, add a narrow exclusion for that specific field rather than disabling the whole rule.

Note: A WAF policy is not a substitute for fixing application-level vulnerabilities. Treat it as defense in depth, a layer that buys you time and blocks opportunistic attacks while your developers patch the underlying issues.

Attaching a WAF policy to Front Door is one of the highest-value, lowest-effort security wins available in Azure. It takes minutes to set up, costs little, and closes off an entire class of attacks at the edge. If this check is failing, it is worth bumping to the top of your list.