Azure Web Application Firewall: Fix & Setup Guide
Why This Is Happening
You deployed Azure Web Application Firewall, and now one of two things has gone wrong. Either it's blocking legitimate traffic your users need , causing angry support tickets and lost revenue , or it's not blocking anything at all, sitting there in Detection mode while real attacks slip through unchallenged. I've seen both situations play out in production environments, and both of them feel terrible in different ways.
Here's the thing most tutorials skip: Azure WAF isn't a single product you install and forget. It's a policy layer that sits on top of one of three Azure services, Application Gateway, Front Door, or Azure CDN (currently in preview). The root of almost every Azure WAF configuration error I encounter comes from people treating it like a standalone firewall rather than understanding which host service they're attaching it to and how the policy association model works.
Azure WAF on Application Gateway is built on the OWASP Core Rule Set (CRS). That's a well-maintained, community-driven ruleset designed to catch the most dangerous attack patterns, SQL injection, cross-site scripting, command injection, HTTP request smuggling, HTTP response splitting, remote file inclusion, and HTTP protocol violations like missing Host or Accept headers. When those rules fire on your legitimate traffic, it's almost always because your application is doing something the CRS considers suspicious. That's not a WAF bug. That's your application behaving in a way that looks like an attack pattern.
The second big source of problems: WAF policy associations. Application Gateway supports two WAF versions, WAF_v1 and WAF_v2. Policy-level associations are only supported in WAF_v2. If you're on v1 and trying to attach a WAF policy to individual listeners or path-based routing rules, nothing will work and the Azure portal won't always make this clear. I've watched teams spend two days debugging what turns out to be a one-word version mismatch.
Then there's the Detection vs. Prevention mode split. In Detection mode, WAF logs threats but doesn't block them. Developers often leave WAF in Detection mode during testing and then push to production without switching it over. Your application is now "protected" by a firewall that waves every attacker through the door and just writes a polite note about it in the logs.
Finally, Azure WAF false positives, where real user requests get blocked because they trigger a CRS rule, are one of the most common complaints I hear. Things like authentication tokens inserted by Active Directory, certain query string formats, or multipart form data can all look suspicious to the WAF rule engine. The fix isn't to disable WAF. The fix is exclusion lists, custom rules, and understanding exactly which rule fired and why.
I know this can feel overwhelming. Azure security configuration errors don't come with friendly error messages, you get a cryptic 403 response and have to dig through logs to find the rule ID that caused it. Let's fix that. Browse all Microsoft fix guides →
The Quick Fix, Try This First
Before you tear apart your entire WAF policy configuration, check whether your WAF is actually in Prevention mode. This single setting accounts for more "my WAF isn't working" complaints than anything else I've encountered.
In the Azure portal, navigate to your Application Gateway resource. In the left-hand menu, find Web application firewall under the Settings section. On the WAF configuration page, look for the Firewall mode setting. It will say either Detection or Prevention.
If it says Detection, flip it to Prevention and hit Save. That's it. Your WAF will now actively block malicious requests instead of just logging them.
If it's already in Prevention mode and you're seeing legitimate traffic get blocked, the next fastest fix is identifying the exact rule that's firing. Go to your Application Gateway's Diagnostic settings, then open Log Analytics or navigate to the ApplicationGatewayFirewallLog log. Run this KQL query:
AzureDiagnostics
| where ResourceType == "APPLICATIONGATEWAYS"
| where Category == "ApplicationGatewayFirewallLog"
| where action_s == "Blocked"
| project TimeGenerated, requestUri_s, ruleId_s, message_s, clientIp_s
| order by TimeGenerated desc
| take 50
This pulls the last 50 blocked requests with the exact rule ID that triggered each block. Write down that rule ID, it's your thread to pull. Once you know the rule, you can either add an exclusion for the specific request attribute that's matching, or adjust the rule's action from Block to Log while you investigate further.
For Azure WAF on Front Door, the path is slightly different. Navigate to your Front Door profile, select Security policies from the left menu, then click your WAF policy name. The Policy settings tab shows the current mode.
This is the step most guides skip and the one that causes the most confusion. Azure WAF doesn't protect your Application Gateway just because you enabled WAF in the gateway's configuration. You need an actual WAF policy associated to the right resource, and this only works in WAF_v2.
In the Azure portal, go to Web Application Firewall policies (search for it in the top search bar). Select your policy. Under Overview, you'll see an Associated application gateways section. If this is empty, your WAF policy is doing absolutely nothing, it's a ruleset floating in space with no gateway attached to it.
To associate it, click + Add association. You'll be prompted to select the Application Gateway, then choose whether to associate at the gateway level, listener level, or path-based rule level. This granularity is one of Azure WAF's strongest features, you can run entirely different WAF policies for different sites hosted behind the same gateway.
Confirm you're using WAF_v2 by navigating to your Application Gateway, then Configuration in the left menu. The Tier field will show either WAF V1 or WAF V2. If you see V1, listener-level and path-rule-level policy associations won't work, you'll need to migrate to V2 or manage WAF settings at the gateway level only.
After making the association, give the portal about 60–90 seconds to propagate, then test with a known-malicious request pattern (something simple like a query string containing ?id=1 OR 1=1) to confirm the WAF is actually intercepting traffic.
You can't fix what you can't see. Azure WAF generates detailed firewall logs, but they're not turned on by default. Without these logs, you're debugging in the dark, you know requests are being blocked but you have no idea which rule caused it or which client IP is being affected.
Navigate to your Application Gateway in the Azure portal. In the left menu under Monitoring, click Diagnostic settings. Click + Add diagnostic setting.
Give the setting a name, something like waf-firewall-logs. Under Logs, check the box next to ApplicationGatewayFirewallLog. Also check ApplicationGatewayAccessLog, you'll want both. Under Destination details, select Send to Log Analytics workspace and pick your workspace. Click Save.
Now wait 5–10 minutes for the first logs to flow in. Then go to Azure Monitor → Logs, select your workspace, and run:
AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| where TimeGenerated > ago(1h)
| summarize count() by action_s, ruleId_s, ruleGroup_s
| order by count_ desc
This gives you a ranked breakdown of which rules are firing most frequently. If action_s shows Matched with mode set to Detection, those would be blocks if you switched to Prevention. If you see Blocked, those are already being stopped. This query is the single most useful diagnostic tool in your Azure WAF arsenal, bookmark it.
Once WAF logs are connected to Azure Monitor, you also unlock integration with Microsoft Defender for Cloud, which provides a central view of your security posture across all your Azure, hybrid, and multicloud resources. That's not something to skip if you're running a production workload.
False positives are the most common day-to-day pain point with Azure WAF. A false positive is when the WAF blocks a legitimate request because it matches a CRS rule. The most frequent culprit I see in enterprise environments: Active Directory authentication tokens in request headers or cookies. The token format contains characters that look like SQL injection patterns to the WAF engine. The fix is an exclusion, not disabling the rule.
In your WAF policy, go to Managed rules, then click Exclusions. Click + Add exclusion.
You'll configure three things:
- Match variable, which part of the request to exclude: Request Headers, Request Cookies, Query String Args, or Request Body Args
- Operator, how to match the variable name: Equals, StartsWith, EndsWith, Contains
- Selector, the specific attribute name (e.g., the cookie name or header name)
For an AD authentication token in a cookie named ARRAffinity, you'd set: Match variable = Request Cookies, Operator = Equals, Selector = ARRAffinity. This tells the WAF to skip evaluation of that specific cookie entirely, everything else still gets inspected.
# Azure CLI equivalent for adding an exclusion
az network application-gateway waf-policy managed-rule exclusion add \
--resource-group MyResourceGroup \
--policy-name MyWAFPolicy \
--match-variable RequestCookieNames \
--selector ARRAffinity \
--selector-match-operator Equals
Always make exclusions as narrow as possible. Excluding an entire request section (like all request headers) defeats the purpose of having WAF protection on that surface. Exclude the specific attribute, not the entire category. After adding the exclusion, test by replaying the previously blocked request, you should now see it succeed in the access log without a corresponding firewall block entry.
Azure WAF on Application Gateway uses OWASP CRS rule groups, logical collections of rules organized by attack category. Common rule groups include SQL injection rules, XSS rules, scanner detection rules, and protocol enforcement rules. Sometimes an entire rule group is too aggressive for your specific application type. You can disable individual rules or entire groups without touching the rest of the CRS.
In your WAF policy, navigate to Managed rules. You'll see the list of rule groups with the active CRS version. Expand a rule group to see individual rules. Each rule has a Rule ID, description, and current state (Enabled/Disabled). You can toggle individual rules off by clicking the rule row and selecting Disable.
Before disabling a rule, always confirm it's causing actual false positives by cross-referencing the rule ID from your firewall logs. Never disable a rule just because you think it might be causing issues. Use the log query from Step 2 to confirm the rule ID is actually in your block list before you touch it.
To disable a specific rule via PowerShell:
$policy = Get-AzApplicationGatewayFirewallPolicy `
-Name MyWAFPolicy `
-ResourceGroupName MyResourceGroup
$disabledRule = New-AzApplicationGatewayFirewallPolicyManagedRuleOverride `
-RuleId "942100" `
-State Disabled
$ruleGroupOverride = New-AzApplicationGatewayFirewallPolicyManagedRuleGroupOverride `
-RuleGroupName "REQUEST-942-APPLICATION-ATTACK-SQLI" `
-Rules $disabledRule
Set-AzApplicationGatewayFirewallPolicy `
-InputObject $policy
Rule group overrides are cumulative, you can stack multiple rule disables within the same policy update. After saving, monitor your firewall logs for another 24 hours to confirm the target false positive rate has dropped while your block rate on known-bad patterns remains stable. If legitimate attack traffic starts slipping through, re-enable the rule immediately and look for a narrower exclusion approach instead.
Two of Azure WAF's most powerful features go underused because people don't know they're there: the IP Reputation Rule Set for bot protection, and custom rules for application-specific logic. Both are available in WAF_v2 policies and require a few minutes to configure properly.
Bot Protection: In your WAF policy, go to Managed rules and scroll down to find the Microsoft_BotManagerRuleSet section (separate from the CRS rules). Enable it. This ruleset uses Microsoft's threat intelligence to identify and block known malicious bots based on IP reputation data. It works in parallel with your OWASP CRS rules, not instead of them. You can configure individual bot categories, bad bots (block), good bots like search engine crawlers (allow), and unknown bots (log or block).
Custom Rules: Custom rules let you write match conditions specific to your application. Navigate to Custom rules in your WAF policy and click + Add custom rule. Common use cases I see in enterprise environments:
- Rate limit by client IP to prevent abuse of login endpoints
- Geo-block specific countries not relevant to your user base
- Allow-list specific IP ranges for admin paths
- Block requests with specific user-agent strings you've identified as malicious
Custom rules are evaluated before managed rules, in priority order. Priority 1 runs before priority 2. If a custom rule matches and the action is Block, the request is blocked immediately, managed rules don't run. If the action is Allow, the request bypasses all managed rules entirely. Use that Allow action carefully for trusted internal IPs hitting admin endpoints where you want WAF inspection skipped.
# Example: Block requests from a specific IP range
# Set via Azure portal: Custom rules → Add
# Match type: IP Address
# Match variable: RemoteAddr
# Operator: IPMatch
# IP address/range: 203.0.113.0/24
# Action: Block
After adding custom rules, always test them in sequence. A misconfigured Allow rule with too broad a match condition can accidentally whitelist an entire IP range and make your WAF useless for those clients. Use the firewall logs to confirm custom rule hits are showing ruleGroup_s = "Custom" in the output.
Advanced Troubleshooting
When the standard steps don't resolve your Azure Web Application Firewall issues, it's time to go deeper. Here's what I reach for when I'm dealing with persistent WAF problems in enterprise or complex multi-site deployments.
Diagnosing WAF Issues Across Multiple Sites on One Gateway
An Application Gateway can host up to 40 websites behind a single WAF. Each site can have its own WAF policy, this is one of WAF_v2's best features. But if you're seeing WAF behavior that affects some sites and not others, the first thing to check is which WAF policy is associated at which level. Gateway-level policies apply to all listeners. Listener-level policies override the gateway policy for that listener. Path-based rule policies override listener policies for specific URL paths.
The effective policy precedence order is: Path Rule → Listener → Gateway. Run this in Azure CLI to see all associations at once:
az network application-gateway show \
--name MyAppGateway \
--resource-group MyResourceGroup \
--query "{listeners:httpListeners[].{name:name,wafPolicy:firewallPolicy}, routingRules:requestRoutingRules[].{name:name,wafPolicy:firewallPolicy}}" \
--output table
Investigating Specific Rule Fires in Event Viewer / Log Analytics
For deeper rule-level forensics, use this Log Analytics query to pull the full request context for a specific blocked request, including request URI, matched data, and client IP:
AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| where ruleId_s == "942100"
| project TimeGenerated, requestUri_s, Message, details_message_s, details_data_s, clientIp_s, hostname_s
| order by TimeGenerated desc
The details_data_s field shows you the exact matched string that triggered the rule. This is critical, it tells you whether the WAF is matching something in a header, query string, or request body, and exactly what value it flagged. Armed with that, you can build a precise exclusion rather than guessing.
WAF on Azure Front Door vs. Application Gateway, Key Differences
If you're running WAF on Front Door instead of Application Gateway, the policy management experience is different. Front Door WAF policies are global (not regional), and they're associated to routing rules rather than listeners. The log table is FrontdoorWebApplicationFirewallLog instead of ApplicationGatewayFirewallLog. The managed rule sets available on Front Door include the Microsoft Default Rule Set (DRS) in addition to OWASP CRS, and DRS versions update more frequently. Make sure you're checking the right log table when debugging Front Door WAF issues.
Request Size Limit Errors
Azure WAF enforces configurable request size limits with both lower and upper bounds. If large file upload requests are getting blocked, check your WAF policy's Request body inspection settings. The request body size limit can be configured up to a maximum allowed by the service tier. In your WAF policy, under Policy settings, look for Max request body size (KB) and Max file upload size (MB). Adjust these to match your application's legitimate upload requirements. Going above the maximum allowed value silently falls back to the default, it won't throw an error, which makes this a particularly sneaky issue.
Escalate to Microsoft Support when you've confirmed your WAF policy configuration is correct but you're seeing inconsistent blocking behavior, blocks that appear in logs but traffic still gets through, or blocks that occur on requests that don't match any configured rule. Also escalate if you're seeing unexpected WAF policy association failures that persist after re-associating the policy, or if your Application Gateway is in a state where the WAF configuration UI is grayed out despite having WAF_v2 tier selected. These are platform-level issues that require Microsoft's backend access to diagnose.
Prevention & Best Practices
Getting Azure Web Application Firewall right isn't a one-time setup task. It's an ongoing practice. The threat landscape changes, your application changes, and Microsoft updates the CRS rule sets. Here's how I recommend staying ahead of WAF problems before they become incidents.
Version your WAF policies in code. Store your WAF policy configuration as ARM templates or Bicep files in version control alongside your application code. When a rule change causes a production incident, you want to be able to roll back a WAF policy change in the same way you'd roll back a code deployment, with a clean audit trail of what changed and when. Bicep for WAF policy export is your friend here.
Keep your CRS version current. Microsoft regularly releases new CRS versions with improved detection accuracy and fewer false positives. Running an outdated CRS means you're missing coverage for newly discovered attack patterns and potentially suffering false positives that the newer version has already corrected. Check your WAF policy's managed rule set version in the portal under Managed rules → Rule set version and compare it against the latest available version.
Test WAF changes in a staging gateway first. Set up a separate Application Gateway (or Front Door endpoint) in your non-production environment with an identical WAF policy. Any rule changes, new exclusions, or custom rule additions go through staging before production. This catches false positives before they affect real users.
Set up WAF metric alerts in Azure Monitor. Don't wait for users to report problems. Create alert rules on the WebApplicationFirewallRequestCount metric filtered by action=Blocked. A sudden spike in blocked requests can mean you're under active attack, or that a deployment just pushed code that's triggering WAF rules. Either way, you want to know immediately, not 20 minutes later when your support queue fills up.
- Enable WAF diagnostic logs on every Application Gateway from day one, not after the first incident
- Run WAF in Detection mode for at least 48 hours before switching to Prevention in any new deployment
- Review the firewall log weekly for recurring rule IDs, recurring hits on the same rule usually signal a false positive or a genuine probe worth investigating
- Associate separate WAF policies to individual listeners when hosting multiple applications behind one gateway, never use one policy to protect apps with very different traffic patterns
Frequently Asked Questions
What is Azure Web Application Firewall and what does it actually protect against?
Azure Web Application Firewall gives you centralized protection for your web applications against the most common and dangerous attack types, SQL injection, cross-site scripting (XSS), command injection, HTTP request smuggling, HTTP response splitting, remote file inclusion, and HTTP protocol violations. Instead of patching security logic into every individual web application you run, WAF handles it at the network layer, sitting in front of your apps on Application Gateway, Front Door, or Azure CDN. The core rule engine is based on the OWASP Core Rule Set, which is one of the most widely adopted and battle-tested web security rulesets in the industry. The big win is that when a new vulnerability is discovered, you patch the WAF policy once and every application behind it is immediately protected, no code deployments needed.
What's the difference between Azure WAF on Application Gateway vs. on Front Door?
The choice between Application Gateway and Front Door depends on where your traffic originates and what your architecture looks like. Application Gateway is a regional service, it operates within a specific Azure region and is the right choice when your applications are hosted in a single region or when you need TLS termination, cookie-based session affinity, or path-based routing within a region. Azure Front Door is a global service that sits at Microsoft's edge network, making it the right choice for globally distributed applications that need low-latency entry points across multiple regions. WAF on Front Door uses the Microsoft Default Rule Set in addition to OWASP CRS, and Front Door WAF policies are global rather than region-specific. Both services are fully supported deployment targets for Azure WAF, but they're not interchangeable, you pick the one that matches your architecture, not the other way around.
Why is Azure WAF blocking legitimate users and how do I stop it without turning off protection?
WAF false positives happen when legitimate request content matches a CRS rule pattern, common causes include Active Directory authentication tokens, certain Base64-encoded payloads, multipart form submissions, and applications that use URL-encoded characters in query strings. The right fix is never to disable WAF wholesale, it's to add a targeted exclusion. Go to your WAF policy, click Managed rules, then Exclusions, and add an exclusion that targets the specific request attribute (a specific cookie name, header name, or query string parameter) that's triggering the false positive. Use the ApplicationGatewayFirewallLog in Azure Monitor to find the exact rule ID and matched data before adding any exclusion, this tells you precisely which attribute to exclude rather than guessing.
WAF policy associations aren't working on my Application Gateway, what's wrong?
This is almost always a SKU version issue. WAF policy associations at the listener level and path-based routing rule level are only supported on WAF_v2 Application Gateways. If your gateway is on WAF_v1, you can configure WAF at the gateway level only, you cannot attach separate WAF policies to individual listeners or path rules. Check your gateway's tier by going to Application Gateway → Configuration and looking at the Tier field. If it shows WAF V1 and you need per-listener or per-path WAF policies, you'll need to migrate to WAF V2. Also confirm that your WAF policy is in the same Azure subscription and region as your Application Gateway, cross-region WAF policy associations are not supported for Application Gateway.
How do I monitor Azure WAF to know if it's actually blocking attacks?
Enable the ApplicationGatewayFirewallLog diagnostic setting and send it to a Log Analytics workspace, that's your primary visibility tool. From Log Analytics, you can query blocked requests by rule, by client IP, by URI, or by time window. Set up Azure Monitor alert rules on the WebApplicationFirewallRequestCount metric with an action filter of "Blocked" so you're notified of spikes in real time rather than discovering them after the fact. The WAF is also integrated with Microsoft Defender for Cloud, which surfaces WAF findings alongside the rest of your Azure security posture, if you're already using Defender for Cloud, check the Security alerts section for WAF-sourced recommendations. Real-time WAF log monitoring is one of the core benefits Microsoft calls out explicitly in the WAF documentation, but it requires you to wire up the diagnostics first.
Can I use Azure WAF to protect against DDoS attacks?
Azure WAF provides application-layer (Layer 7) DDoS protection through its rate limiting custom rules and bot protection ruleset, but it's not a replacement for Azure DDoS Protection at the network layer. WAF operates on HTTP/HTTPS traffic and can detect and block volumetric attacks that arrive as floods of malformed web requests, scraper bots, or credential stuffing attempts, all things the IP Reputation Rule Set and bot protection managed rules handle well. For full-spectrum DDoS protection including volumetric network-layer attacks (Layer 3 and 4), you should deploy Azure DDoS Protection alongside WAF. Microsoft explicitly positions these as complementary services within the Azure network security category, WAF handles the application layer, DDoS Protection handles the network and transport layers. Running both gives you defense-in-depth across all attack surfaces.