<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Peakhour.IO - Cloudflare WAF</title><link href="https://www.peakhour.io/" rel="alternate"></link><link href="https://www.peakhour.io/feeds/tag/cloudflare-waf.atom.xml" rel="self"></link><id>https://www.peakhour.io/</id><updated>2026-07-29T09:45:00+10:00</updated><entry><title>How to Tune Cloudflare WAF When Rule 949110 Blocks a Request</title><link href="https://www.peakhour.io/blog/how-to-tune-cloudflare-waf/" rel="alternate"></link><published>2026-07-29T09:45:00+10:00</published><updated>2026-07-29T09:45:00+10:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2026-07-29:/blog/how-to-tune-cloudflare-waf/</id><summary type="html">&lt;p&gt;Trace a Cloudflare OWASP anomaly-score block to the rules that raised the score, then choose the right override or exception.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Rule &lt;code&gt;949110&lt;/code&gt; blocked the request.&lt;/p&gt;
&lt;p&gt;In Cloudflare's OWASP managed ruleset, &lt;code&gt;949110: Inbound Anomaly Score Exceeded&lt;/code&gt; checks the total score produced by earlier detections. The rules that raised the score explain the block.&lt;/p&gt;
&lt;p&gt;Cloudflare puts that answer in Additional logs.&lt;/p&gt;
&lt;h2&gt;Start with the blocked event&lt;/h2&gt;
&lt;p&gt;Open &lt;strong&gt;Security &amp;gt; Events&lt;/strong&gt; in the Cloudflare dashboard and filter to the hostname, path, action and time of the request.&lt;/p&gt;
&lt;p&gt;Security Events shows traffic that Cloudflare acted on or flagged. Its top-level views group events by fields such as action, host, country and service. The sampled log beneath them contains a subset of individual security events, so a busy time range may hide the request you need. Narrowing the time range reduces sampling. &lt;a href="https://developers.cloudflare.com/waf/analytics/security-events/"&gt;Cloudflare documents the Security Events views and sampling behaviour&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Capture the details that identify the request:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ray ID;&lt;/li&gt;
&lt;li&gt;timestamp;&lt;/li&gt;
&lt;li&gt;hostname and path;&lt;/li&gt;
&lt;li&gt;method;&lt;/li&gt;
&lt;li&gt;WAF service and action;&lt;/li&gt;
&lt;li&gt;displayed rule ID and description;&lt;/li&gt;
&lt;li&gt;the application result reported by the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One request can produce more than one security event. Keep the Ray ID and timestamp together while you follow the detections.&lt;/p&gt;
&lt;p&gt;If the displayed description is &lt;code&gt;949110: Inbound Anomaly Score Exceeded&lt;/code&gt;, open &lt;strong&gt;Additional logs&lt;/strong&gt;. Cloudflare places the OWASP rules triggered by that request there. &lt;a href="https://developers.cloudflare.com/waf/analytics/security-events/"&gt;The Security Events documentation describes those contributing OWASP records&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Additional logs deserve a manual check in the dashboard. Cloudflare says triggered OWASP rules shown there are absent from exported Security Events JSON. A log export containing only the final event can therefore leave out the detections that built the anomaly score. &lt;a href="https://developers.cloudflare.com/waf/analytics/security-events/"&gt;The Security Events documentation records that export limitation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Find the rule that raised the score&lt;/h2&gt;
&lt;p&gt;Additional logs may show one contributing rule or several. Record each rule's description and Cloudflare rule ID.&lt;/p&gt;
&lt;p&gt;The description may begin with a familiar CRS-style number. Cloudflare's API and exception controls use Cloudflare's opaque rule ID. Use the identifier displayed by Cloudflare when you configure the rule.&lt;/p&gt;
&lt;p&gt;Group repeated matches by rule, field and route, then review each group with the application owner. A single support message containing SQL syntax may be legitimate. Different paths or different rules belong in separate investigations. The &lt;a href="/blog/how-to-tune-your-waf/"&gt;general WAF tuning guide&lt;/a&gt; explains how to classify each group and record an exception.&lt;/p&gt;
&lt;p&gt;Ask the developer who owns the route:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what input the endpoint accepts;&lt;/li&gt;
&lt;li&gt;whether the request was parsed successfully;&lt;/li&gt;
&lt;li&gt;where the matching value is stored or rendered;&lt;/li&gt;
&lt;li&gt;which validation runs at the application;&lt;/li&gt;
&lt;li&gt;whether the field can carry executable syntax by design.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Choose an override or an exception&lt;/h2&gt;
&lt;p&gt;An &lt;strong&gt;override&lt;/strong&gt; changes the configuration of a managed rule or ruleset across that deployment. You can change an action, disable selected rules or adjust settings such as the OWASP anomaly score threshold and paranoia level.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;exception&lt;/strong&gt; matches a set of requests and skips selected managed rules for those requests. Its expression can use the host, URI path, method and other Cloudflare Rules language fields.&lt;/p&gt;
&lt;p&gt;Use an override when the rule itself needs a different action across the deployment. Use an exception when a known application route needs different treatment.&lt;/p&gt;
&lt;p&gt;Cloudflare allows exceptions to skip:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;every remaining managed rule;&lt;/li&gt;
&lt;li&gt;one or more managed rulesets;&lt;/li&gt;
&lt;li&gt;one or more rules inside managed rulesets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Select the contributing rule. A whole-ruleset exception removes far more inspection from the matching request. &lt;a href="https://developers.cloudflare.com/waf/managed-rules/waf-exceptions/"&gt;Cloudflare documents the three exception types and their order of precedence&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For a false positive confined to message creation, the expression could be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http.host eq &amp;quot;api.example.com&amp;quot;
and http.request.uri.path eq &amp;quot;/v1/messages&amp;quot;
and http.request.method eq &amp;quot;POST&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Choose the Cloudflare rule ID found in Additional logs as the rule to skip.&lt;/p&gt;
&lt;p&gt;Cloudflare skips that rule for the complete matching request. Another field on &lt;code&gt;POST /v1/messages&lt;/code&gt; can trigger the same rule and receive the same exception. Record that consequence.&lt;/p&gt;
&lt;h2&gt;Place the exception before the managed ruleset&lt;/h2&gt;
&lt;p&gt;An exception works only on managed-ruleset execution rules listed after it in the same phase. Put the skip rule before the rule that executes the OWASP managed ruleset. &lt;a href="https://developers.cloudflare.com/waf/managed-rules/waf-exceptions/define-api/"&gt;Cloudflare's API documentation states that skip rules affect only later execute rules&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cloudflare can run managed rulesets at account level on Enterprise plans and at zone level. Account-level rulesets execute before zone-level rulesets. An account-level exception affects account-level rules, while a zone-level exception affects zone-level rules. A zone exception cannot prevent an account-level rule from matching first. &lt;a href="https://developers.cloudflare.com/waf/managed-rules/waf-exceptions/"&gt;Cloudflare documents this scope and evaluation order&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Find the execute rule that produced the event. Add the exception at that level and before that execution. If the OWASP ruleset runs at both levels, inspect both deployments and decide which one needs the exception.&lt;/p&gt;
&lt;p&gt;Exceptions take priority over overrides. &lt;a href="https://developers.cloudflare.com/waf/account/managed-rulesets/"&gt;Cloudflare records that precedence in its managed-ruleset documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Test the exception through Cloudflare&lt;/h2&gt;
&lt;p&gt;Send the original legitimate request through the hostname proxied by Cloudflare. An origin-only replay bypasses the configuration you are testing.&lt;/p&gt;
&lt;p&gt;Use a small test set:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the legitimate request on the exempt route;&lt;/li&gt;
&lt;li&gt;the same input on another route;&lt;/li&gt;
&lt;li&gt;a safe request that triggers the contributing rule on the exempt route;&lt;/li&gt;
&lt;li&gt;the same test outside the exception;&lt;/li&gt;
&lt;li&gt;normal traffic that should pass unchanged.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Check Security Events after each request. Confirm the Ray ID, action, contributing rules and final result.&lt;/p&gt;
&lt;p&gt;The safe trigger on the exempt route shows what the exception allows. The same trigger outside the exception should still raise the contributing rule and reach &lt;code&gt;949110&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cloudflare evaluates security products and rules in a defined sequence, and a terminating action stops later evaluation. An earlier custom-rule Block or Managed Challenge can determine the result before Managed Rules run. &lt;a href="https://developers.cloudflare.com/waf/concepts/"&gt;Cloudflare's WAF concepts guide describes this rule execution behaviour&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Set the anomaly threshold from real traffic&lt;/h2&gt;
&lt;p&gt;The OWASP anomaly threshold is the cumulative request score at which &lt;code&gt;949110&lt;/code&gt; applies the configured action. Raising it moves the block point for every request covered by that deployment.&lt;/p&gt;
&lt;p&gt;Use Security Events to see which rules contribute to normal requests before changing the threshold. A repeated false positive from one rule and one endpoint points towards an exception. A broad pattern of low-confidence detections may justify a threshold or paranoia-level review.&lt;/p&gt;
&lt;p&gt;Cloudflare supports overrides for the full ruleset, rule tags and individual rules. Tag and ruleset overrides can also affect future rules that Cloudflare adds under those selections. Individual rule overrides target the rule IDs you chose. &lt;a href="https://developers.cloudflare.com/waf/account/managed-rulesets/"&gt;The managed-ruleset documentation explains these override levels&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Test a threshold change with the same care as a rule exception. It changes when &lt;code&gt;949110&lt;/code&gt; acts across all covered traffic.&lt;/p&gt;
&lt;h2&gt;Record the exception and its rule IDs&lt;/h2&gt;
&lt;p&gt;Document:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the Ray IDs and event times reviewed;&lt;/li&gt;
&lt;li&gt;the contributing Cloudflare rule IDs and descriptions;&lt;/li&gt;
&lt;li&gt;the anomaly threshold and paranoia level;&lt;/li&gt;
&lt;li&gt;the exception expression;&lt;/li&gt;
&lt;li&gt;the account or zone deployment it belongs to;&lt;/li&gt;
&lt;li&gt;its position before the managed-ruleset execute rule;&lt;/li&gt;
&lt;li&gt;what the selected rule stops inspecting;&lt;/li&gt;
&lt;li&gt;the developer who confirmed the application behaviour;&lt;/li&gt;
&lt;li&gt;the requests used for verification;&lt;/li&gt;
&lt;li&gt;the review date.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Recheck the exception after application changes and Cloudflare managed-rule updates. A new route can need different conditions. A revised rule can remove the original false positive.&lt;/p&gt;
&lt;p&gt;Rule &lt;code&gt;949110&lt;/code&gt; applies the configured action when the anomaly score crosses the threshold. Tune the rules that supplied the false-positive score.&lt;/p&gt;</content><category term="Application Security"></category><category term="Cloudflare WAF"></category><category term="WAF"></category><category term="OWASP CRS"></category><category term="Application Security"></category><category term="False Positives"></category><category term="WAF Tuning"></category></entry></feed>