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.

26 May 2026 azurewafkqlfalse-positiveowaspapplication-gateway

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.

kusto 01-reference-event.kql
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.

kusto 02-scope-volume.kql
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.

kusto 03-triggered-field.kql
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.

text evidence-checklist.txt
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.

text decision-matrix.txt
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.