Cloud
WAF and KQL: identify a false positive before creating an exclusion
A KQL analysis method to qualify an Azure WAF block, distinguish attack, noise and application false positive, then document the decision before any exclusion.
A WAF false positive is not declared just because a user is blocked. It is demonstrated. A request can be legitimate from a business point of view and still dangerous technically. Conversely, an OWASP rule can react to normal application content: rich JSON payload, text containing SQL reserved words, encoded parameters, paths with special characters or file uploads.
The scenario starts from an Azure WAF Application Gateway block identified in Log Analytics. The goal is to qualify the block before creating an exclusion. The right outcome is not always a rule change. It can be an application fix, frontend validation, URL normalization, custom rule or very targeted exclusion.
Running use case: a partner comment field
We continue the partner portal incident. The comment field accepts free text because partners sometimes paste query fragments, column names or error messages. Since the last release, several submissions to /partner/comment are blocked by rule 942100, while authenticated users follow a normal journey.
The analysis has a concrete goal: decide whether the comment field is really triggering a SQLi false positive, or whether the form accepts content that should be validated differently. The answer must point to the next action: fix the application, constrain the field, create a targeted exclusion or keep the block.
Isolate the reference event
Start with a precise event. You need a time, source, URI, rule and message. Without a reference event, analysis remains too generic.
let incidentTime = datetime(2026-05-26 14:32:00);
AzureDiagnostics
| where TimeGenerated between ((incidentTime - 10m) .. (incidentTime + 10m))
| where Category == "ApplicationGatewayFirewallLog"
| where action_s =~ "Blocked"
| project TimeGenerated,
clientIp_s,
hostname_s,
requestUri_s,
ruleId_s,
ruleSetType_s,
ruleSetVersion_s,
message_s,
details_message_s,
details_data_s
| order by TimeGenerated asc Keep the event in the ticket or change note. It is the basis for discussion with application and security teams.
Measure volume and scope
A real false positive often appears on a known endpoint with an identified user journey. Hostile scanning usually spans many URIs, sources or signatures. This distinction is not absolute, but volume helps.
let rule = "942100";
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where Category == "ApplicationGatewayFirewallLog"
| where ruleId_s == rule
| summarize events=count(),
clients=dcount(clientIp_s),
uris=dcount(requestUri_s),
sampleUri=any(requestUri_s),
sampleMessage=any(message_s)
by bin(TimeGenerated, 1d), hostname_s
| order by TimeGenerated desc If the rule appears suddenly after a release, compare with the application change. If it appears on hundreds of URIs from many sources, attack or scan hypotheses should remain primary.
Find the triggering parameter or area
Log details may indicate the part of the request involved: argument, cookie, header, body or another field depending on the available format. The goal is to identify exactly what an exclusion would affect.
AzureDiagnostics
| where TimeGenerated > ago(24h)
| where Category == "ApplicationGatewayFirewallLog"
| where action_s =~ "Blocked"
| where ruleId_s == "942100"
| project TimeGenerated,
requestUri_s,
clientIp_s,
message_s,
details_message_s,
details_data_s
| order by TimeGenerated desc If the trigger is a standard header, known business parameter or upload area, the exclusion can sometimes be targeted. If the trigger is broad or unidentified, disabling a whole rule is rarely defensible.
Compare with application logs
The WAF sees the request at the edge. The application sees what actually gets through. To qualify a false positive, compare with application logs when possible: authenticated user, endpoint, expected payload, backend validation, response code on allowed requests.
Evidence to collect
WAF event with ruleId and action
Affected application endpoint
Suspect parameter, header or area
Expected user journey
Possible recent application change
Application team feedback
Security decision: fix, exclude, disable or monitor For the comment field, the application team can confirm that the user is authenticated, the comment is never executed, the backend enforces a maximum length, and the value is stored as text. If that evidence is missing, the exclusion is premature: the application behavior must be hardened or clarified first.
Decide with a simple matrix
The decision must be proportionate. A rule can stay active with a parameter-level exclusion. A rule can be temporarily disabled on a route if risk is understood. A request can also remain blocked if it reveals an application weakness.
Observed case
One rule blocks a known business parameter on a precise endpoint
Likely decision
Per-rule and per-variable exclusion, limited to what is necessary
Observed case
Several SQLi/XSS rules trigger on many URIs
Likely decision
No global exclusion, security investigation first
Observed case
An upload route triggers body inspection rules
Likely decision
Review limits, inspection, application validation and targeted exclusion if justified Granularity is essential. The wider the exclusion, the more protection it removes.
Conclusion
Identifying a WAF false positive requires more than a ruleId. You need time evidence, volume, scope, a triggering field and application understanding. KQL builds that evidence before configuration changes.
The useful question is not only which rule blocks. It is what that rule protects, which part of the request triggers it, whether that is expected for the application, and whether the exception can be minimized. A documented exclusion is a control. An urgent exclusion quickly becomes security debt.