
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Mon, 13 Apr 2026 18:26:46 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Slashing agent token costs by 98% with RFC 9457-compliant error responses]]></title>
            <link>https://blog.cloudflare.com/rfc-9457-agent-error-pages/</link>
            <pubDate>Wed, 11 Mar 2026 13:05:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare now returns RFC 9457-compliant structured Markdown and JSON error payloads to AI agents, replacing heavyweight HTML pages with machine-readable instructions. This reduces token usage by over 98%, turning brittle parsing into efficient control flow. ]]></description>
            <content:encoded><![CDATA[ <p>AI agents are no longer experiments. They are production infrastructure, making billions of HTTP requests per day, navigating the web, calling APIs, and orchestrating complex workflows.</p><p>But when these agents hit an error, they still receive the same HTML error pages we built for browsers: hundreds of lines of markup, CSS, and copy designed for human eyes. Those pages give agents clues, not instructions, and waste time and tokens. That gap is the opportunity to give agents instructions, not obstacles.</p><p>Starting today, Cloudflare returns <a href="https://www.rfc-editor.org/rfc/rfc9457">RFC 9457</a>-compliant structured Markdown and JSON error payloads to AI agents, replacing heavyweight HTML pages with machine-readable instructions.</p><p>That means when an agent sends <code>Accept: text/markdown</code>, <code>Accept: application/json</code>, or <code>Accept: application/problem+json</code> and encounters a Cloudflare error, we return one semantic contract in a structured format instead of HTML. And it comes complete with actionable guidance. (This builds on our recent <a href="https://blog.cloudflare.com/markdown-for-agents/">Markdown for Agents</a> release.)</p><p>So instead of being told only "You were blocked," the agent will read: "You were rate-limited — wait 30 seconds and retry with exponential backoff." Instead of just "Access denied," the agent will be instructed: "This block is intentional: do not retry, contact the site owner."</p><p>These responses are not just clearer — they are dramatically more efficient. Structured error responses cut payload size and token usage by more than 98% versus HTML, measured against a live 1015 ('rate-limit') error response. For agents that hit multiple errors in a workflow, the savings compound quickly.</p><p>This is live across the Cloudflare network, automatically. Site owners do not need to configure anything. Browsers keep getting the same HTML experience as before.</p><p>These are not just error pages. They are instructions for the agentic web.</p>
    <div>
      <h3>What agents see today</h3>
      <a href="#what-agents-see-today">
        
      </a>
    </div>
    <p>When an agent receives a Cloudflare-generated error, it usually means Cloudflare is enforcing customer policy or returning a platform response on the customer's behalf — not that Cloudflare is down. These responses are triggered when a request cannot be served as-is, such as invalid host or DNS routing, customer-defined access controls (WAF, geo, ASN, or bot rules), or edge-enforced limits like rate limiting. In short, Cloudflare is acting as the customer's routing and security layer, and the response explains why the request was blocked or could not proceed.</p><p>Today, those responses are rendered as HTML designed for humans:</p>
            <pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Access denied | example.com used Cloudflare to restrict access&lt;/title&gt;
&lt;style&gt;/* 200 lines of CSS */&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class="cf-wrapper"&gt;
    &lt;h1 data-translate="block_headline"&gt;Sorry, you have been blocked&lt;/h1&gt;
    &lt;!-- ... hundreds more lines ... --&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
            <p>To an agent, this is garbage. It cannot determine what error occurred, why it was blocked, or whether retrying will help. Even if it parses the HTML, the content describes the error but doesn't tell the agent — or the human, for that matter — what to do next.</p><p>If you're an agent developer and you wanted to handle Cloudflare errors gracefully, your options were limited. For Cloudflare-generated errors, structured responses existed only in configuration-dependent paths, not as a consistent default for agents.</p><p>Custom Error Rules can customize many Cloudflare errors, including some 1xxx cases. But they depend on per-site configuration, so they cannot serve as a universal agent contract across the web. Cloudflare sits in front of the request path. That means we can define a default machine response: retry or stop, wait and back off, escalate or reroute. Error pages stop being decoration and become execution instructions.</p>
    <div>
      <h3>What we did</h3>
      <a href="#what-we-did">
        
      </a>
    </div>
    <p>Cloudflare now returns RFC 9457-compliant structured responses for all 1xxx-class error paths — Cloudflare's platform error codes for edge-side failures like DNS resolution issues, access denials, and rate limits. Both formats are live: <code>Accept: text/markdown</code> returns Markdown, <code>Accept: application/json</code> returns JSON, and <code>Accept: application/problem+json</code> returns JSON with the <code>application/problem+json</code> content type.</p><p>This covers all 1xxx-class errors today. The same contract will extend to Cloudflare-generated 4xx and 5xx errors next.</p><p>Markdown responses have two parts:</p><ul><li><p>YAML frontmatter for machine-readable fields</p></li><li><p>prose sections for explicit guidance (<code>What happened</code> and <code>What you should do</code>)</p></li></ul><p>JSON responses carry the same fields as a flat object.</p><p>The YAML frontmatter is the critical layer for automation. It lets an agent extract stable keys without scraping HTML or guessing intent from copy. Fields like <code>error_code</code>, <code>error_name</code>, and <code>error_category</code> let the agent classify the failure. <code>retryable</code> and <code>retry_after</code> drive backoff logic. <code>owner_action_required</code> tells the agent whether to keep trying or escalate. <code>ray_id</code>, <code>timestamp</code>, and <code>zone</code> make logs and support handoffs deterministic.</p><p>The schema is stable by design, so agents can implement durable control flow without chasing presentation changes.</p><p>That stability is not a Cloudflare invention. <a href="https://www.rfc-editor.org/rfc/rfc9457">RFC 9457 — Problem Details for HTTP APIs</a> defines a standard JSON shape for reporting errors over HTTP, so clients can parse error responses without knowing the specific API in advance. Our JSON responses follow this shape, which means any HTTP client that understands Problem Details can parse the base members without Cloudflare-specific code:</p><table><tr><td><p><b>RFC 9457 member</b></p></td><td><p><b>What it contains</b></p></td></tr><tr><td><p><code>type</code></p></td><td><p>A URI pointing to Cloudflare's documentation for the specific error code</p></td></tr><tr><td><p><code>status</code></p></td><td><p>The HTTP status code (matching the actual response status)</p></td></tr><tr><td><p><code>title</code></p></td><td><p>A short, human-readable summary of the problem</p></td></tr><tr><td><p><code>detail</code></p></td><td><p>A human-readable explanation specific to this occurrence</p></td></tr><tr><td><p><code>instance</code></p></td><td><p>The Ray ID identifying this specific error occurrence</p></td></tr></table><p>The operational fields — <code>error_code</code>, <code>error_category</code>, <code>retryable</code>, <code>retry_after</code>, <code>owner_action_required</code>, and more — are RFC 9457 extension members. Clients that don't recognize them simply ignore them.</p><p>This is network-wide and additive. Site owners do not need to configure anything. Browsers keep receiving HTML unless clients explicitly ask for Markdown or JSON.</p>
    <div>
      <h3>What the response looks like</h3>
      <a href="#what-the-response-looks-like">
        
      </a>
    </div>
    <p>Here is what a rate-limit error (<code>1015</code>) looks like in JSON:</p>
            <pre><code>{
  "type": "https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1015/",
  "title": "Error 1015: You are being rate limited",
  "status": 429,
  "detail": "You are being rate-limited by the website owner's configuration.",
  "instance": "9d99a4434fz2d168",
  "error_code": 1015,
  "error_name": "rate_limited",
  "error_category": "rate_limit",
  "ray_id": "9d99a4434fz2d168",
  "timestamp": "2026-03-09T11:11:55Z",
  "zone": "&lt;YOUR_DOMAIN&gt;",
  "cloudflare_error": true,
  "retryable": true,
  "retry_after": 30,
  "owner_action_required": false,
  "what_you_should_do": "**Wait and retry.** This block is transient. Wait at least 30 seconds, then retry with exponential backoff.\n\nRecommended approach:\n1. Wait 30 seconds before your next request\n2. If rate-limited again, double the wait time (60s, 120s, etc.)\n3. If rate-limiting persists after 5 retries, stop and reassess your request pattern",
  "footer": "This error was generated by Cloudflare on behalf of the website owner."
}</code></pre>
            <p>The same error in Markdown, optimized for model-first workflows:</p>
            <pre><code>---
error_code: 1015
error_name: rate_limited
error_category: rate_limit
status: 429
ray_id: 9d99a39dc992d168
timestamp: 2026-03-09T11:11:28Z
zone: &lt;YOUR_DOMAIN&gt;
cloudflare_error: true
retryable: true
retry_after: 30
owner_action_required: false
---

# Error 1015: You are being rate limited

## What Happened

You are being rate-limited by the website owner's configuration.

## What You Should Do

**Wait and retry.** This block is transient. Wait at least 30 seconds, then retry with exponential backoff.

Recommended approach:
1. Wait 30 seconds before your next request
2. If rate-limited again, double the wait time (60s, 120s, etc.)
3. If rate-limiting persists after 5 retries, stop and reassess your request pattern

---
This error was generated by Cloudflare on behalf of the website owner.
</code></pre>
            <p>Both formats give an agent everything it needs to decide and act: classify the error, choose retry behavior, and determine whether escalation is required. This is what a default machine contract looks like — not per-site configuration, but network-wide behavior. The contrast is explicit across error families: a transient error like <code>1015</code> says wait and retry, while intentional blocks like <code>1020</code> or geographic restrictions like <code>1009</code> tell the agent not to retry and to escalate instead.</p>
    <div>
      <h3>One contract, two formats</h3>
      <a href="#one-contract-two-formats">
        
      </a>
    </div>
    <p>The core value is not format choice. It is semantic stability.</p><p>Agents need deterministic answers to operational questions: retry or not, how long to wait, and whether to escalate. Cloudflare exposes one policy contract across two wire formats. Whether a client consumes Markdown or JSON, the operational meaning is identical: same error identity, same retry/backoff signals, same escalation guidance.</p><p>Clients that send <code>Accept: application/problem+json</code> get <code>application/problem+json; charset=utf-8</code> back — useful for HTTP client libraries that dispatch on media type. Clients that send <code>Accept: application/json</code> get <code>application/json; charset=utf-8</code> — same body, safe default for existing consumers.</p>
    <div>
      <h3>Size reduction and token efficiency</h3>
      <a href="#size-reduction-and-token-efficiency">
        
      </a>
    </div>
    <p>That contract is also dramatically smaller than what it replaces. Cloudflare HTML error pages are browser-oriented and heavy, while structured responses are compact by design.</p><p>Measured comparison for <code>1015</code>:</p><table><tr><td><p><b>Payload</b></p></td><td><p><b>Bytes</b></p></td><td><p><b>Tokens (cl100k_base)</b></p></td><td><p><b>Size vs HTML</b></p></td><td><p><b>Token vs HTML</b></p></td></tr><tr><td><p>HTML response</p></td><td><p>46,645</p></td><td><p>14,252</p></td><td><p>—</p></td><td><p>—</p></td></tr><tr><td><p>Markdown response</p></td><td><p>798</p></td><td><p>221</p></td><td><p>58.5x less</p></td><td><p>64.5x less</p></td></tr><tr><td><p>JSON response</p></td><td><p>970</p></td><td><p>256</p></td><td><p>48.1x less</p></td><td><p>55.7x less</p></td></tr></table><p>Both structured formats deliver a ~98% reduction in size and tokens versus HTML. For agents, size translates directly into token cost — when an agent hits multiple errors in one run, these savings compound into lower model spend and faster recovery loops.</p>
    <div>
      <h3>Ten categories, clear actions</h3>
      <a href="#ten-categories-clear-actions">
        
      </a>
    </div>
    <p>Every <code>1xxx</code> error is mapped to an <code>error_category</code>. That turns error handling into routing logic instead of brittle per-page parsing.</p><table><tr><td><p><b>Category</b></p></td><td><p><b>What it means</b></p></td><td><p><b>What the agent should do</b></p></td></tr><tr><td><p><code>access_denied</code></p></td><td><p>Intentional block: IP, ASN, geo, firewall rule</p></td><td><p>Do not retry. Contact site owner if unexpected.</p></td></tr><tr><td><p><code>rate_limit</code></p></td><td><p>Request rate exceeded</p></td><td><p>Back off. Retry after retry_after seconds.</p></td></tr><tr><td><p><code>dns</code></p></td><td><p>DNS resolution failure at the origin</p></td><td><p>Do not retry. Report to site owner.</p></td></tr><tr><td><p><code>config</code></p></td><td><p>Configuration error: CNAME, tunnel, host routing</p></td><td><p>Do not retry (usually). Report to site owner.</p></td></tr><tr><td><p><code>tls</code></p></td><td><p>TLS version or cipher mismatch</p></td><td><p>Fix TLS client settings. Do not retry as-is.</p></td></tr><tr><td><p><code>legal</code></p></td><td><p>DMCA or regulatory block</p></td><td><p>Do not retry. This is a legal restriction.</p></td></tr><tr><td><p><code>worker</code></p></td><td><p>Cloudflare Workers runtime error</p></td><td><p>Do not retry. Site owner must fix the script.</p></td></tr><tr><td><p><code>rewrite</code></p></td><td><p>Invalid URL rewrite output</p></td><td><p>Do not retry. Site owner must fix the rule.</p></td></tr><tr><td><p><code>snippet</code></p></td><td><p>Cloudflare Snippets error</p></td><td><p>Do not retry. Site owner must fix Snippets config.</p></td></tr><tr><td><p><code>unsupported</code></p></td><td><p>Unsupported method or deprecated feature</p></td><td><p>Change the request. Do not retry as-is.</p></td></tr></table><p>Two fields make this operationally useful for agents:</p><ul><li><p><code>retryable</code> answers whether a retry can succeed</p></li><li><p><code>owner_action_required</code> answers whether the problem must be escalated</p></li></ul><p>You can replace brittle "if status == 429 then maybe retry" heuristics with explicit control flow. Parse the frontmatter once, then branch on stable fields. A simple pattern is:</p><ul><li><p>if <code>retryable</code> is <code>true</code>, wait <code>retry_after</code> and retry</p></li><li><p>if <code>owner_action_required</code> is <code>true</code>, stop and escalate</p></li><li><p>otherwise, fail fast without hammering the site</p></li></ul><p>Here is a minimal Python example using that pattern:</p>
            <pre><code>import time
import yaml


def parse_frontmatter(markdown_text: str) -&gt; dict:
    # Expects: ---\n&lt;yaml&gt;\n---\n&lt;body&gt;
    if not markdown_text.startswith("---\n"):
        return {}
    _, yaml_block, _ = markdown_text.split("---\n", 2)
    return yaml.safe_load(yaml_block) or {}


def handle_cloudflare_error(markdown_text: str) -&gt; str:
    meta = parse_frontmatter(markdown_text)

    if not meta.get("cloudflare_error"):
        return "not_cloudflare_error"

    if meta.get("retryable"):
        wait_seconds = int(meta.get("retry_after", 30))
        time.sleep(wait_seconds)
        return f"retry_after_{wait_seconds}s"

    if meta.get("owner_action_required"):
        return f"escalate_owner_error_{meta.get('error_code')}"

    return "do_not_retry"</code></pre>
            <p>This is the key shift: agents are no longer inferring intent from HTML copy. They are executing explicit policy from structured fields.</p>
    <div>
      <h3>How to use it</h3>
      <a href="#how-to-use-it">
        
      </a>
    </div>
    <p>Send <code>Accept: text/markdown</code>, <code>Accept: application/json</code>, or <code>Accept: application/problem+json</code>.</p><p>For quick testing, you can hit any Cloudflare-proxied domain directly at <code>/cdn-cgi/error/1015</code> (or replace <code>1015</code> with another <code>1xxx</code> code).</p>
            <pre><code>curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015"
</code></pre>
            <p>Example with another error code:</p>
            <pre><code>curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1020"
</code></pre>
            <p>JSON example:</p>
            <pre><code>curl -s --compressed -H "Accept: application/json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015" | jq .
</code></pre>
            <p>RFC 9457 Problem Details example:</p>
            <pre><code>curl -s --compressed -H "Accept: application/problem+json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015" | jq .
</code></pre>
            <p>The behavior is deterministic — the first explicit structured type wins:</p><table><tr><td><p><b>Accept header</b></p></td><td><p><b>Response</b></p></td></tr><tr><td><p><code>application/json</code></p></td><td><p>JSON</p></td></tr><tr><td><p><code>application/json; charset=utf-8</code></p></td><td><p>JSON</p></td></tr><tr><td><p><code>application/problem+json</code></p></td><td><p>JSON (application/problem+json content type)</p></td></tr><tr><td><p><code>application/json, text/markdown;q=0.9</code></p></td><td><p>JSON</p></td></tr><tr><td><p><code>application/json, text/markdown</code></p></td><td><p>JSON (equal q, first-listed wins)</p></td></tr><tr><td><p><code>text/markdown</code></p></td><td><p>Markdown</p></td></tr><tr><td><p><code>text/markdown, application/json</code></p></td><td><p>Markdown (equal q, first-listed wins)</p></td></tr><tr><td><p><code>text/markdown, */*</code></p></td><td><p>Markdown</p></td></tr><tr><td><p><code>text/*</code></p></td><td><p>Markdown</p></td></tr><tr><td><p><code>*/*</code></p></td><td><p>HTML (default)</p></td></tr></table><p>Wildcard-only requests (<code>*/*</code>) do not signal a structured preference; clients must explicitly request Markdown or JSON.</p><p>If the request succeeds, you get normal origin content. The header only affects Cloudflare-generated error responses.</p>
    <div>
      <h3>Real-world use cases</h3>
      <a href="#real-world-use-cases">
        
      </a>
    </div>
    <p>There are a number of situations where structured error responses help immediately:</p><ol><li><p>Agent blocked by WAF rule (<code>1020</code>). The agent parses <code>error_code</code>, records <code>ray_id</code>, and stops retrying. It can escalate with useful context instead of looping.</p></li><li><p>MCP (Model Context Protocol) tool hitting geo restriction (<code>1009</code>). The tool gets a clear, machine-readable reason, returns it to the orchestrator, and the workflow can choose an alternate path or notify the user.</p></li><li><p>Rate-limited crawler (<code>1015</code>). The agent reads <code>retryable</code>: true and <code>retry_after</code>, applies backoff, and retries predictably instead of hammering the endpoint.</p></li><li><p>Developer debugging with <code>curl</code>. The developer can reproduce exactly what the agent sees, including frontmatter and guidance, without reverse-engineering HTML.</p></li><li><p>HTTP client libraries that understand RFC 9457. Any client that dispatches on <code>application/problem+json</code> or parses Problem Details objects can handle Cloudflare errors without Cloudflare-specific code.</p></li></ol><p>In each case, the outcome is the same: less guessing, fewer wasted retries, lower model cost, and faster recovery.</p>
    <div>
      <h3>Try it now</h3>
      <a href="#try-it-now">
        
      </a>
    </div>
    <p>Send a structured <code>Accept</code> header and test against any Cloudflare-proxied domain:</p>
            <pre><code>curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015"
</code></pre>
            
            <pre><code>curl -s --compressed -H "Accept: application/json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015" | jq .
</code></pre>
            
            <pre><code>curl -s --compressed -H "Accept: application/problem+json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "&lt;YOUR_DOMAIN&gt;/cdn-cgi/error/1015" | jq .
</code></pre>
            <p>Error pages are the first conversation between Cloudflare and an agent. This launch makes that conversation structured, standards-compliant, and cheap to process.</p><p>To make this work across the web, agent runtimes should default to explicit structured <code>Accept</code> headers, not bare <code>*/*</code>. Use <code>Accept: text/markdown, */*</code> for model-first workflows and <code>Accept: application/json, */*</code> for typed control flow. If you maintain an agent framework, SDK, or browser automation stack, ship this default and treat bare <code>*/*</code> as legacy fallback.</p><p>And it is only the first layer. We are building the rest of the agent stack on top of it: <a href="https://developers.cloudflare.com/ai-gateway/"><u>AI Gateway</u></a> for routing, controls, and observability; <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Workers AI</u></a> for inference; and the identity, security, and access primitives agents will need to operate safely at Internet scale.</p><p>Cloudflare is helping our customers deliver content in agent-friendly ways, and this is just the start. If you're building or operating agents, start at <a href="http://agents.cloudflare.com"><u>agents.cloudflare.com</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Edge Computing]]></category>
            <guid isPermaLink="false">46xdz0GQfFtpCKRKNbfj3b</guid>
            <dc:creator>Sam Marsh</dc:creator>
        </item>
        <item>
            <title><![CDATA[AI Security for Apps is now generally available]]></title>
            <link>https://blog.cloudflare.com/ai-security-for-apps-ga/</link>
            <pubDate>Wed, 11 Mar 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare AI Security for Apps is now generally available, providing a security layer to discover and protect AI-powered applications, regardless of the model or hosting provider. We are also making AI discovery free for all plans, to help teams find and secure shadow AI deployments. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare’s <a href="https://www.cloudflare.com/demos/protect-ai-apps/"><u>AI Security for Apps</u></a> detects and mitigates threats to AI-powered applications. Today, we're announcing that it is generally available.</p><p>We’re shipping with new capabilities like detection for custom topics, and we're making AI endpoint discovery free for every Cloudflare customer—including those on Free, Pro, and Business plans—to give everyone visibility into where AI is deployed across their Internet-facing apps.</p><p>We're also announcing an expanded collaboration with IBM, which has chosen Cloudflare to deliver AI security to its cloud customers. And we’re partnering with Wiz to give mutual customers a unified view of their AI security posture.</p>
    <div>
      <h2>A new kind of attack surface</h2>
      <a href="#a-new-kind-of-attack-surface">
        
      </a>
    </div>
    <p>Traditional web applications have defined operations: check a bank balance, make a transfer. You can write deterministic rules to secure those interactions. </p><p>AI-powered applications and agents are different. They accept natural language and generate unpredictable responses. There's no fixed set of operations to allow or deny, because the inputs and outputs are probabilistic. Attackers can manipulate large language models to take unauthorized actions or leak sensitive data. Prompt injection, sensitive information disclosure, and unbounded consumption are just a few of the risks cataloged in the <a href="https://genai.owasp.org/llm-top-10/"><u>OWASP Top 10 for LLM Applications</u></a>.</p><p>These risks escalate as AI applications become agents. When an AI gains access to tool calls—processing refunds, modifying accounts, providing discounts, or accessing customer data—a single malicious prompt becomes an immediate security incident.</p><p>Customers tell us what they’re up against. "Most of Newfold Digital's teams are putting in their own Generative AI safeguards, but everybody is innovating so quickly that there are inevitably going to be some gaps eventually,” says Rick Radinger, Principal Systems Architect at Newfold Digital, which operates Bluehost, HostGator, and Domain.com. </p>
    <div>
      <h2>What AI Security for Apps does</h2>
      <a href="#what-ai-security-for-apps-does">
        
      </a>
    </div>
    <p>We built AI Security for Apps to address this. It sits in front of your AI-powered applications, whether you're using a third-party model or hosting your own, as part of Cloudflare's <a href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/"><u>reverse proxy</u></a>. It helps you (1) discover AI-powered apps across your web property, (2) detect malicious or off-policy behavior to those endpoints, and (3) mitigate threats via the familiar WAF rule builder. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5xpmckBUupzELjYOSx5bAF/cace1ab2ed2dd54d8d7a7ff60587ef65/BLOG-3128_2.png" />
          </figure>
    <div>
      <h3>Discovery — now free for everyone</h3>
      <a href="#discovery-now-free-for-everyone">
        
      </a>
    </div>
    <p>Before you can protect your LLM-powered applications, you need to know where they're being used. We often hear from security teams who don’t have a complete picture of AI deployments across their apps, especially as the LLM market evolves and developers swap out models and providers. </p><p>AI Security for Apps automatically identifies LLM-powered endpoints across your web properties, regardless of where they’re hosted or what the model is. Starting today, this capability is free for every Cloudflare customer, including Free, Pro, and Business plans. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2dBKhU5VNbzAePDAnaHkTK/3f6a569e495e03c3e2afca4d6183e02d/image4.png" />
          </figure><p><sup><i>Cloudflare’s dashboard page of web assets, showing 2 example endpoints labelled as </i></sup><code><sup><i>cf-llm</i></sup></code></p><p>Discovering these endpoints automatically requires more than matching common path patterns like <code>/chat/completions</code>. Many AI-powered applications don't have a chat interface: think product search, property valuation tools, or recommendation engines. We built a <a href="https://blog.cloudflare.com/take-control-of-public-ai-application-security-with-cloudflare-firewall-for-ai/#discovering-llm-powered-applications"><u>detection system that looks at how endpoints behave</u></a>, not what they're called. To confidently identify AI-powered endpoints, <a href="https://developers.cloudflare.com/api-shield/security/api-discovery/#requirements"><u>sufficient valid traffic</u></a> is required.</p><p>AI-powered endpoints that have been discovered will be visible under <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/web-assets"><u>Security → Web Assets</u></a>, labeled as <code>cf-llm</code>. For customers on a Free plan, endpoint discovery is initiated when you first navigate to the <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/web-assets/discovery"><u>Discovery page</u></a>. For customers on a paid plan, discovery occurs automatically in the background on a recurring basis. If your AI-powered endpoints have been discovered, you can review them immediately.</p>
    <div>
      <h3>Detection</h3>
      <a href="#detection">
        
      </a>
    </div>
    <p>AI Security for Apps detections follow the <a href="https://developers.cloudflare.com/waf/detections/"><u>always-on approach</u></a> for traffic to your AI-powered endpoints. Each prompt is run through multiple detection modules for prompt injection, PII exposure, and sensitive or toxic topics. The results—whether the prompt was malicious or not—are attached as metadata you can use in custom WAF rules to enforce your policies. We are continuously exploring ways to leverage our global network, which sees traffic from roughly <a href="https://w3techs.com/technologies/history_overview/proxy/all"><u>20% of the web</u></a>, to identify new attack patterns across millions of sites before they reach yours.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7oGjcaUL5L9zlAkz8lSmXv/4354a9555135e19de5c93d3d113e6790/BLOG-3128_4.png" />
          </figure>
    <div>
      <h4>New in GA: Custom topics detection</h4>
      <a href="#new-in-ga-custom-topics-detection">
        
      </a>
    </div>
    <p>The product ships with built-in detection for common threats: prompt injections, <a href="https://blog.cloudflare.com/take-control-of-public-ai-application-security-with-cloudflare-firewall-for-ai/#detecting-prompts-designed-to-leak-pii"><u>PII extraction</u></a>, and <a href="https://blog.cloudflare.com/block-unsafe-llm-prompts-with-firewall-for-ai/"><u>toxic topics</u></a>. But every business has its own definition of what's off-limits. A financial services company might need to detect discussions of specific securities. A healthcare company might need to flag conversations that touch on patient data. A retailer might want to know when customers are asking about competitor products.</p><p>The new custom topics feature lets you define these categories. You specify the topic, we inspect the prompt and output a relevance score that you can use to log, block, or handle however you decide. Our goal is to build an extensible tool that flexes to your use cases.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1WzPhy11ZmUXDGZjft4sY1/7ebfafaf2114eaba83a829694837fc2c/image1.png" />
          </figure><p><sup><i>Prompt relevance score inside of AI Security for Apps</i></sup></p>
    <div>
      <h4>New in GA: Custom prompt extraction</h4>
      <a href="#new-in-ga-custom-prompt-extraction">
        
      </a>
    </div>
    <p>AI Security for Apps enforces guardrails before unsafe prompts can reach your infrastructure. To run detections accurately and provide real-time protection, we first need to identify the prompt within the request payload. Prompts can live anywhere in a request body, and different LLM providers structure their APIs differently. OpenAI and most providers use <code>$.messages[*].content</code> for chat completions. Anthropic's batch API nests prompts inside <code>$.requests[*].params.messages[*].content</code>. Your custom property valuation tool might use <code>$.property_description</code>.</p><p>Out of the box, we support the standard formats used by OpenAI, Anthropic, Google Gemini, Mistral, Cohere, xAI, DeepSeek, and others. When we can't match a known pattern, we apply a default-secure posture and run detection on the entire request body. This can introduce false positives when the payload contains fields that are sensitive but don't feed directly to an AI model, for example, a <code>$.customer_name</code> field alongside the actual prompt might trigger PII detection unnecessarily.</p><p>Soon, you'll be able to define your own JSONPath expressions to tell us exactly where to find the prompt. This will reduce false positives and lead to more accurate detections. We're also building a prompt-learning capability that will automatically adapt to your application's structure over time.</p>
    <div>
      <h3>Mitigation</h3>
      <a href="#mitigation">
        
      </a>
    </div>
    <p>Once a threat is identified and scored, you can block it, log it, or deliver custom responses, using the same WAF rules engine you already use for the rest of your application security. The power of Cloudflare’s shared platform is that you can combine AI-specific signals with everything else we know about a request, represented by <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/"><u>hundreds of fields</u></a> available in the WAF. A prompt injection attempt is suspicious. A prompt injection attempt from an IP that’s been probing your login page, using a browser fingerprint associated with previous attacks, and rotating through a botnet is a different story. Point solutions that only see the AI layer can’t make these connections.</p><p>This unified security layer is exactly what they need at Newfold Digital to discover, label, and protect AI endpoints, says Radinger: “We look forward to using it across all these projects to serve as a fail-safe."</p>
    <div>
      <h2>Growing ecosystem</h2>
      <a href="#growing-ecosystem">
        
      </a>
    </div>
    <p>AI Security for Applications will also be available through Cloudflare's growing ecosystem, including through integration with IBM Cloud. Through <a href="https://www.ibm.com/products/cloud-internet-services"><u>IBM Cloud Internet Services (CIS)</u></a>, end users can already procure advanced application security solutions and manage them directly through their IBM Cloud account. </p><p>We're also partnering with Wiz to connect AI Security for Applications with <a href="https://www.wiz.io/solutions/ai-spm"><u>Wiz AI Security</u></a>, giving mutual customers a unified view of their AI security posture, from model and agent discovery in the cloud to application-layer guardrails at the edge.</p>
    <div>
      <h2>How to get started</h2>
      <a href="#how-to-get-started">
        
      </a>
    </div>
    <p>AI Security for Apps is available now for Cloudflare’s Enterprise customers. Contact your account team to get started, or see the product in action with a <a href="https://www.cloudflare.com/demos/protect-ai-apps/"><u>self-guided tour</u></a>.</p><p>If you're on a Free, Pro, or Business plan, you can use AI endpoint discovery today. Log in to your dashboard and navigate to <b>Security → Web Assets</b> to see which endpoints we've identified. Keep an eye out — we plan to make all AI Security for Apps capabilities available for customers on all plans soon.</p><p>For configuration details, see our <a href="https://developers.cloudflare.com/waf/detections/firewall-for-ai/"><u>documentation</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[Application Services]]></category>
            <guid isPermaLink="false">4MBDCV6FV61Xbyav3cW8Xy</guid>
            <dc:creator>Liam Reese</dc:creator>
            <dc:creator>Zhiyuan Zheng</dc:creator>
            <dc:creator>Catherine Newcomb</dc:creator>
        </item>
        <item>
            <title><![CDATA[Always-on detections: eliminating the WAF “log versus block” trade-off]]></title>
            <link>https://blog.cloudflare.com/attack-signature-detection/</link>
            <pubDate>Wed, 04 Mar 2026 15:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is introducing Attack Signature Detection and Full-Transaction Detection to provide continuous, high-fidelity security insights without the manual tuning of traditional WAFs. By correlating request payloads with server responses, we can now identify successful exploits and data exfiltration while minimizing false positives. ]]></description>
            <content:encoded><![CDATA[ <p>Traditional Web Application Firewalls typically require extensive, manual tuning of their rules before they can safely block malicious traffic. When a new application is deployed, security teams usually begin in a logging-only mode, sifting through logs to gradually assess which rules are safe for blocking mode. This process is designed to minimize false positives without affecting legitimate traffic. It’s manual, slow and error-prone.</p><p>Teams are forced into a trade-off: visibility in log mode, or protection in block mode. When a rule blocks a request, evaluation stops, and you lose visibility into how other signatures would have assessed it — valuable insight that could have helped you tune and strengthen your defenses.</p><p>Today, we’re solving this by introducing the next evolution of our managed rules: Attack Signature Detection.</p><p>When enabled, this detection inspects every request for malicious payloads and attaches rich detection metadata before any action is taken. You get complete visibility into every signature match, without sacrificing protection or performance. Onboarding becomes simple: traffic is analyzed, data accumulates, and you see exactly which signatures fire and why. You can then build precise mitigation policies based on past traffic, reducing the risk of false positives.</p><p>But we’re going one step further. We’re moving beyond request-only analysis to something far more powerful: Full-Transaction Detection.</p><p>Instead of looking at just the incoming request, this new detection correlates the entire HTTP transaction: request and response. By analyzing the full context, we dramatically reduce false positives compared to traditional request-only signature engines. More importantly, we uncover threats others miss, such as reflective SQL injection, subtle data exfiltration patterns, and dangerous misconfigurations that only reveal themselves in the response. </p><p>Attack Signature Detection is available now in Early Access — <a href="https://www.cloudflare.com/lp/attack-detection/"><u>sign up here</u></a> to express interest. Full-Transaction Detection is under development; <a href="https://www.cloudflare.com/lp/full-transaction-detection/"><u>register here</u></a> to be among the first to try it when it’s ready.</p>
    <div>
      <h2>The always-on framework</h2>
      <a href="#the-always-on-framework">
        
      </a>
    </div>
    <p>To provide full visibility on your traffic without slowing down the Internet, we had to change how we think about the request lifecycle. For customers who opt in, Attack Signature detection is now "always on." This means that as soon as traffic is proxied, all detection signatures are executed on every request, and the results are immediately visible in Security Analytics.</p><p>This "always-on" framework separates detection from mitigation. Detections run continuously, enriching analytics with metadata about triggered detections. This metadata is also added to the request as a new field, which customers can use to create custom policies within security rules. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Vx8m4KODWR1lqusEdBtUj/8339eea7b73eb79bae416ef7fe01b60b/image9.png" />
          </figure><p><sup><i>Separating the detection of malicious payloads from the actions taken by security rules is the core of the always-on framework. This approach enhances the analytics experience and increases confidence when deploying new protections.</i></sup></p><p>Our existing Bot Score and Attack Score detections already follow this method. Attack Signature Detection provides the same coverage as our Managed Rules product but operates within this new framework.</p><p>Does this introduce additional latency to the request? No — this model is designed for efficiency. If a customer has not created a blocking rule based on a detection, the detection can be executed <i>after</i> the request has been sent to the origin server, ensuring that the detection itself introduces no additional latency to the traffic. Therefore, upon onboarding, the detection is enabled by default but does not impact traffic performance. When a rule is created, the detection is moved in-line with the request that might experience additional latency. The exact value depends on the traffic profile of the application. </p>
    <div>
      <h2>Attack Signature Detection</h2>
      <a href="#attack-signature-detection">
        
      </a>
    </div>
    <p>Compared to traditional, rule-based systems like the Cloudflare Managed Ruleset, the new detection offers a substantial advancement in web application security. This approach makes identifying malicious web payloads and deploying security rules significantly more user-friendly.</p><p>The Cloudflare Managed Ruleset is where our analyst team develops detections for common attack vectors, including <a href="https://www.cloudflare.com/learning/security/threats/sql-injection/"><u>SQL injection (SQLi)</u></a>, <a href="https://www.cloudflare.com/learning/security/threats/cross-site-scripting/"><u>Cross Site Scripting (XSS)</u></a>, <a href="https://www.cloudflare.com/learning/security/what-is-remote-code-execution/"><u>Remote Code Execution (RCE)</u></a>, and specific Common Vulnerabilities and Exposures (CVEs). Analysts typically release new rules weekly, with emergency releases deployed for high-profile vulnerabilities (such as the recent <a href="https://react2shell.com/"><u>React2Shell</u></a> <a href="https://blog.cloudflare.com/waf-rules-react-vulnerability/"><u>release</u></a>). Currently, over 700 managed rules are active in our Managed Ruleset. The new detections are also known as <i>signature rules</i> or simply <i>signatures</i>. They employ the same heuristics as Managed Rules but do not directly apply actions to traffic.</p><p>Each signature is uniquely identified by a Ref ID (similar to the Rule ID for the Managed Ruleset) and is tagged with both <i>category</i> and <i>confidence</i>. The category specifies the attack vectors the signature targets, while the confidence level indicates the likelihood of a false positive (a trigger on legitimate traffic). A rule can have only one confidence level but may have multiple categories. </p><p>Category indicates what attack vector the rule refers to. The list of categories is long, but includes tags like SQLi, XSS, RCE or specific CVE with its number.</p><p>The confidence field is divided into two values, based on whether at least one signature from the corresponding group matches the traffic.</p><table><tr><td><p><b>Confidence</b></p></td><td><p><b>Description</b></p></td></tr><tr><td><p>High</p></td><td><p>These signatures aim for high true positives and low false positives, typical for CVEs where payloads are identifiable without blocking legitimate traffic. They function like the Managed Ruleset’s default configuration.</p></td></tr><tr><td><p>Medium</p></td><td><p>These signatures, which are turned off by default in the Managed Ruleset, may cause false positives based on your traffic. Before blocking traffic matching these rules, assess their potential application impact.</p></td></tr></table><p>
The detection's analysis of a request populates three fields. These fields are accessible in Security Analytics and Edge Rules Engine, our core engine for Security Rules.</p><table><tr><td><p>Field</p></td><td><p>Description</p></td><td><p>Where can be used</p></td></tr><tr><td><p><code>cf.waf.signature.request.</code><code><b>confidence</b></code></p></td><td><p>Array. Aggregate the confidence scores associated with the matching signatures.</p></td><td><p>Analytics and Security Rules</p></td></tr><tr><td><p><code>cf.waf.signature.request.</code><code><b>categories</b></code></p></td><td><p>Array. Aggregate the categories associated with the matching signatures.</p></td><td><p>Analytics and Security Rules</p></td></tr><tr><td><p><code>cf.waf.signature.request.</code><code><b>ref</b></code></p></td><td><p>Array. Aggregates the Ref IDs of the matching signatures, up to 10.</p></td><td><p>Analytics and Security Rules</p></td></tr></table>
    <div>
      <h3>Analyzing your data in Security Analytics</h3>
      <a href="#analyzing-your-data-in-security-analytics">
        
      </a>
    </div>
    <p>Security Analytics is at the core of the Cloudflare Application Security toolbox, providing a comprehensive, data-driven view of how signatures interact with your web traffic. It gives you the tools necessary to understand, measure, and optimize your web protection. Common use cases for combining Analytics with signatures include: design a security posture during the onboarding process, verify the most frequent attack attempts and create exceptions to handle false positives.</p><p>Once a new application is proxied through Cloudflare, Attack Signature Detection begins populating your dashboard with data. The initial step is to examine the aggregated matches, categorized by type and signature, to confirm that all potential attacks are being blocked. Analysts can do this by reviewing the top statistics for signatures, filtering the data to show whether requests were blocked, served from the cache, or permitted to reach the origin server. If any malicious requests are found to have reached the origin, analysts can quickly implement security rules. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Flwiq3kVd2vHnIT7w30Op/2c9564f636b5e1169228711cd7ff5c15/image6.png" />
          </figure><p><sup><i>A breakdown of the total request volume matching attack signatures, categorized by their corresponding Category or Signature.</i></sup></p><p>Analytics provides insights into attack patterns, such as the most frequent CVEs based on traffic volume over time. This capability is designed for quickly identifying the dominant attack payloads targeting applications and verifying the efficacy of current protections against related CVEs. For example, analysts can monitor the attack frequency targeting a specific part of the application, like <code>/api/</code>, or confirm if known malicious payloads, such as React2Shell, are reaching a particular endpoint, such as the <code>POST /_next/</code> Node.js path. Both the Analytics filters and the Attack Analysis tool can be used to perform this type of investigation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/PswhIBA7AXI5y6BaH4Rq6/aafe3e2f272d8077ed1454066600da51/image5.png" />
          </figure><p><sup><i>A visualization within Security Analytics offers a time-series view of malicious payloads targeting the /api/ endpoint. This view groups the data to highlight the top five CVEs by volume.</i></sup></p><p>Analytics also help create exceptions and identifying false positives. An increase in matches for a specific rule, for instance, may suggest false positives rather than active exploitation. For example, an application that allows users to submit rich HTML content (such as a Content Management Systems or support ticketing system) may legitimately include markup that matches more generic XSS signatures. In these cases, a scoped exception can be applied to the affected endpoint, while keeping the protection enabled across the rest of the application. </p><p>This approach is especially useful for evaluating medium-confidence signatures, which balance aggressive blocking with false-positive risk. The tool allows "what-if" scenarios against historical traffic to empirically determine production performance. This process helps determine if a medium-confidence signature is appropriate for the overall traffic profile, or if a high rate of false positives requires limiting its deployment to specific URLs or request types. </p><p>Generally, signatures that have a very low match rate on historical traffic can be more safely deployed in block mode without significant disruption to legitimate traffic. To achieve this level of confidence, Security Analytics provides the tools for in-depth forensics investigations.</p><p>Beyond immediate detection, a crucial aspect of defense management is the ability to customize your security posture. The user interface offers a searchable catalog of all security signatures, allowing you to browse the full list and understand the specific threat each is designed to address. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6enXCjehRa8ibfhOoUfnRv/330231e1e7cc96cb1450f0f450d33aab/Screenshot_2026-03-04_at_17.17.59.png" />
          </figure><p><sup><i>A searchable catalog of signatures is available, providing more detail on critical detections to help customers understand the threats and the remediation actions.</i></sup></p>
    <div>
      <h3>Creating security rules</h3>
      <a href="#creating-security-rules">
        
      </a>
    </div>
    <p>After analyzing your data and establishing confidence in how the signatures performed against your past traffic, you can easily create custom rules to handle traffic based on the detections. For example, if you want to create a policy that blocks requests matching high confidence signatures you can create the following rule:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/55sYmYsoMh9effxtmxG65j/2ca91e74188ad69a908b5ae69571225c/image1.png" />
          </figure><p><sup><i>Creating a rule to block requests matching with high confidence signatures.</i></sup></p><p>This is equivalent to the Cloudflare Managed Ruleset default deployment.</p><p>If you want to block all requests matching at least one rule, you will add the Medium confidence tag. This is equivalent to enabling all rules of Cloudflare Managed Ruleset. Alternatively, you can configure multiple rules, applying a more stringent action (like "Block") for detections with High confidence and a less strict action (such as "Challenge") for those with Medium confidence.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3JhVPtrx2ZRhsNgRQHCaLc/ca3f597d8b794fd5a2eb1ddfc1362288/image8.png" />
          </figure><p><sup><i>By selecting both High and Medium confidence you can trigger a rule if any signature matches.</i></sup></p><p>To create a rule blocking a specific CVE or attack vector, you will use Categories. The rule builder allows you to combine attack vector category tags with all existing HTTP request data. This enables you to create granular rules (or exceptions) and tailor your security posture to different parts of your application. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/wEf21sGlDdKkO7Mgt1pVn/01bd915ae33d931ca33bd0b2d04fc9e8/image7.png" />
          </figure><p><sup><i>Customers can create rules to block (or allow) requests matching specific CVEs or attack categories.</i></sup></p><p>To create rules based on a specific Signature, you can use Ref ID. You can find the right Ref ID within the rule builder by exploring the available Attack Signature rules. This is especially useful if you want to create exceptions to manage false positives.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LQ93vHMecuHS8xNbL0RTz/b805072b739f1ded6f4383c13f2cfb5a/image3.png" />
          </figure><p><sup><i>Customers can browse signature rules directly from the rule builder.</i></sup></p>
    <div>
      <h3>What happens to Cloudflare Managed Ruleset?</h3>
      <a href="#what-happens-to-cloudflare-managed-ruleset">
        
      </a>
    </div>
    <p>All customers continue to have access to our classic Managed Ruleset. When Attack Signature Detection is broadly available, customers will be able to choose the deployment model that best suits their needs, whether that is Attack Signature Detection or Managed Rules. Our analyst teams ensure that new detections are released simultaneously across both the Managed Ruleset and Attack Signature Detection.</p>
    <div>
      <h2>Full-Transaction Detection</h2>
      <a href="#full-transaction-detection">
        
      </a>
    </div>
    <p>Traditional web attack detection primarily focuses on the "ask": the HTTP request. However, the request only tells half the story. To know if an attack actually succeeded, you have to look at the "answer": the HTTP response.</p><p>By combining request and response metadata into a single detection event, we can dramatically reduce false positives and identify successful exploits that request-only systems miss.</p><p>For example, consider a request containing a common SQL injection string in a query parameter.</p><blockquote><p><code>GET /user?id=1' UNION SELECT username, password FROM users--</code></p></blockquote><p>A traditional WAF will see the <code>UNION SELECT</code> pattern and block it. However, if the application isn't actually vulnerable, this might be a false positive — for instance a security researcher testing their own site.</p><p>With Full-Transaction Detection, the system notes the SQLi signature in the request but waits for the response. If the origin responds with a <code>500 Internal Server Error</code> or a standard <code>404</code>, the confidence of a "successful exploit" is low. If the origin responds with a <code>200 OK</code> and a body containing a string that matches a "sensitive data" signature (like a list of usernames), the system flags a Successful Exploit Confirmation.</p><p>To start, we are rolling out a few detection categories and plan to expand this list over time. Here are the three areas we are currently focused on, and some of the flags you’ll see:</p><ul><li><p><b>Exploit attempts. </b>The detection provides web attack detections by inspecting the entire HTTP request-to-response cycle. It focuses on three key areas: identifying input exploitation like XSS and SQLi via malicious signatures, stopping automated abuse such as vulnerability probing, and confirming successful exploits by correlating suspicious requests with unusual server responses.</p></li></ul><ul><li><p><b>Data exposure and exfiltration signals. </b>This framework also allows us to catch data exfiltration that looks like legitimate traffic on the way in. A request for /api/v1/export is a standard administrative action. But if that specific request triggers a response containing 5,000 credit card numbers (for example identified via Luhn algorithm signatures), the transaction is flagged as Data Exposure. </p></li></ul><ul><li><p><b>Misconfigurations. </b>Exposed admin interfaces are often attack vectors. Traditional security checks miss this misconfiguration because the traffic itself looks valid (real endpoints or admin pages). The issue isn't the traffic but its public accessibility. We prioritize detection based on common real-world misconfigurations seen in customer data, such as public unauthenticated Elasticsearch clusters, Internet reachable admin panels, and exposed Apache sensitive endpoints.</p></li></ul><p>The detection, much like Attack Signatures, will store the results in two specific fields. These fields are accessible in our dashboard and logged within Security Analytics.</p><table><tr><td><p>Field</p></td><td><p>Description</p></td><td><p>Where can be used</p></td></tr><tr><td><p><code>cf.waf.signature.response.</code><code><b>categories</b></code></p></td><td><p>Array. Aggregate the categories associated with the matching signatures.</p></td><td><p>Security Analytics </p></td></tr><tr><td><p><code>cf.waf.signature.response.</code><code><b>ref</b></code></p></td><td><p>Array. Aggregates the Ref IDs of the matching signatures, up to 10.</p></td><td><p>Security Analytics </p></td></tr></table><p>Initially, we are focused on offering visibility into matching requests via analytics. By surfacing events on potential exploits, we provide customers information that can be used for incident response through targeted remediations across their infrastructure and software stack. Our future plans include extending Security Rules to the response phase, which will empower customers to block responses based on these detections by allowing policy creation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3uUoiHlxC6qEjBNU1AA5Rg/1402f5be8f412443cf3b9ff39e8d0700/image4.png" />
          </figure><p><sup><i>A diagram illustrating the execution locations and corresponding populated fields for both Attack Signature Detection and Full-Transaction Detection.</i></sup></p>
    <div>
      <h2>Sign up to get access</h2>
      <a href="#sign-up-to-get-access">
        
      </a>
    </div>
    <p>Attack Signature detection is in Early Access while Full-Transaction Detection is under development. <a href="https://www.cloudflare.com/lp/attack-detection"><u>Sign up here</u></a> to get access to Attack Signature, and <a href="https://www.cloudflare.com/lp/full-transaction-detection/"><u>here to express interest</u></a> for Full-Transaction. We’ll gather feedback in the coming months as we prepare these features for General Availability.</p> ]]></content:encoded>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[WAF Rules]]></category>
            <category><![CDATA[Managed Rules]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[Security Analytics]]></category>
            <guid isPermaLink="false">1oOFMFJ55pkBU09IKiw8fm</guid>
            <dc:creator>Daniele Molteni</dc:creator>
        </item>
        <item>
            <title><![CDATA[The most-seen UI on the Internet? Redesigning Turnstile and Challenge Pages]]></title>
            <link>https://blog.cloudflare.com/the-most-seen-ui-on-the-internet-redesigning-turnstile-and-challenge-pages/</link>
            <pubDate>Fri, 27 Feb 2026 06:00:00 GMT</pubDate>
            <description><![CDATA[ We serve 7.6 billion challenges daily. Here’s how we used research, AAA accessibility standards, and a unified architecture to redesign the Internet’s most-seen user interface. ]]></description>
            <content:encoded><![CDATA[ <p>You've seen it. Maybe you didn't register it consciously, but you've seen it. That little widget asking you to verify you're human. That full-page security check before accessing a website. If you've spent any time on the Internet, you've encountered Cloudflare's Turnstile widget or Challenge Pages — likely more times than you can count.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5YaxxmA9nz7AufmcJmhagL/0db6b65ec7456bc8091affc6beaf3ec2/Image_1_-_Turnstile.png" />
          </figure><p><sup><i>The Turnstile widget – a familiar sight across millions of websites</i></sup></p><p>When we say that a large portion of the Internet sits behind Cloudflare, we mean it. Our Turnstile widget and Challenge Pages are served 7.67 billion times every single day. That's not a typo. Billions. This might just be the most-seen user interface on the Internet.</p><p>And that comes with enormous responsibility.</p><p>Designing a product with billions of eyeballs on it isn't just challenging — it requires a fundamentally different approach. Every pixel, every word, every interaction has to work for someone's grandmother in rural Japan, a teenager in São Paulo, a visually impaired developer in Berlin, and a busy executive in Lagos. All at the same time. In moments of frustration.</p><p>Today we’re sharing the story of how we redesigned Turnstile and Challenge Pages. It's a story told in three parts, by three of us: the design process and research that shaped our decisions (Leo), the engineering challenge of deploying changes at unprecedented scale (Ana), and the measurable impact on billions of users (Marina).</p><p>Let's start with how we approached the problem from a design perspective.</p>
    <div>
      <h2>Part 1: The design process</h2>
      <a href="#part-1-the-design-process">
        
      </a>
    </div>
    
    <div>
      <h3>The problem</h3>
      <a href="#the-problem">
        
      </a>
    </div>
    <p>Let's be honest: nobody likes being asked to prove they're human. You know you're human. I know I'm human. The only one who doesn't seem convinced is that little widget standing between you and the website you're trying to access. At best, it's a minor inconvenience. At worst? You've probably wanted to throw your computer out the window in a fit of rage. We've all been there. And no one would blame you.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/640zjNaqDcNdJy4mYN6H14/ce184df68c9612d77f0767726bf27822/2.png" />
          </figure><p><sup><i>Turnstile integrated into a login flow</i></sup></p><p>As the world warms up to what appears to be an inevitable AI revolution, the need for security verification is only increasing. At Cloudflare, we've seen a significant rise in bot attacks — and in response, organizations are investing more heavily in security measures. That means more challenges being issued to more end users, more often.</p><p>The numbers tell the story:</p><p>2023: 2.14B daily</p><p>2024: 3B daily</p><p>2025: 5.35B daily</p><p>That's a 58.1% average increase in security checks, year over year. More security checks mean more opportunities for end user frustration. The more companies integrate these verification systems to protect themselves and their customers, the higher the chance that someone, somewhere, is going to have a bad experience.</p><p>We knew it was time to take a hard look at our flagship products and ask ourselves: Are we doing right by the billions of people who encounter these experiences? Are we fulfilling our mission to build a better Internet — not just a more secure one, but a more human one?</p><p>The answer, we discovered, was: we could do better.</p>
    <div>
      <h3>The design audit</h3>
      <a href="#the-design-audit">
        
      </a>
    </div>
    <p>Before redesigning anything, we needed to understand what we were working with. We started by conducting a comprehensive audit of every state, every error message, and every interaction across both Turnstile and Challenge Pages.</p><p>What we found wasn't the best.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1g1exDgeRH9QlApBXItcfL/fb0051d1dabaa6c91cf976ef64793502/3.png" />
          </figure><p><sup><i>The state of inconsistency in the Turnstile widget. Multiple states with no unified approach</i></sup></p><p>The inconsistencies were glaring. We had no unified approach across the multitude of different error scenarios. Some messages were overly verbose and technical ("Your device clock is set to a wrong time or this challenge page was accidentally cached by an intermediary and is no longer available"). Others were too vague to be helpful ("Timed out"). The visual language varied wildly — different layouts, different hierarchies, different tones of voice.</p><p>We also examined the feedback we'd received online. Social media, support tickets, community forums — we read it all. The frustration was palpable, and much of it was avoidable.</p><p>Take our feedback mechanism, for example. We offered users feedback options like "The widget sometimes fails" versus "The widget fails all the time." But what's the difference, really? And how were they supposed to know how often it failed? We were asking users to interpret ambiguous options during their most frustrated moments. The more we left open to interpretation, the less useful the feedback became — and the more frustration we saw across social channels.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5xKRSM0FfDZikEECwgHoof/ad55208973698cb237444c21d384aff8/4.png" />
          </figure><p><sup><i>The previous feedback screen: "The widget sometimes fails" vs "The widget fails all the time" — what's the difference?</i></sup></p><p>Our Challenge Pages — the full-page security blocks that appear when we detect suspicious activity or when site owners have heightened security settings — had similar issues. Some states were confusing. Others used too much technical jargon. Many failed to provide actionable guidance when users needed it most.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5JUxHjJ4VG13F7QfLONJEQ/fa443e5dd24f10d0c256864cd3f42734/5.png" />
          </figure><p><sup><i>The state of inconsistency on the Challenge pages. Multiple states with no unified approach</i></sup></p><p>The audit was humbling. But it gave us a clear picture of where we needed to focus.</p>
    <div>
      <h2>Mapping the user journey</h2>
      <a href="#mapping-the-user-journey">
        
      </a>
    </div>
    <p>To design better experiences, we first needed to understand every possible path a user could take. What was the happy path? Was there even one? And what were the unhappy paths that led to escalating frustration?</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1oTbFZoRu7guIxzoe64qcm/4f579fe2e70d6225a51504b3de10030f/6.png" />
          </figure><p><sup><i>Mapping the complete user journey — from initial encounter through error scenarios, with sentiment tracking</i></sup></p><p>This was a true cross-functional effort. We worked closely with engineers like Ana who knew the technical ins and outs of every edge case, and with Marina on the product side who understood not just how the product worked, but how users felt about it — the love and the hate we'd see online.</p><p>We have some of the smartest people working on bot protection at Cloudflare. But intelligence and clarity aren't the same thing. There's a delicate balance between technical complexity and user simplicity. Only when these two dance together successfully can we communicate information in a way that actually makes sense to people.</p><p>And here's the thing: the messaging has to work for everyone. A person of any age. Any mental or physical capability. Any cultural background. Any level of technical sophistication. That's what designing at scale really means — you can’t ignore edge cases, since, at such scale, they are no longer edge cases.</p>
    <div>
      <h2>Establishing a unified information architecture</h2>
      <a href="#establishing-a-unified-information-architecture">
        
      </a>
    </div>
    <p>One of the most influential books in UX design is Steve Krug's <a href="https://sensible.com/dont-make-me-think/"><u>Don't Make Me Think</u></a>. The core principle is simple: every moment a user spends trying to interpret, understand, or decode your interface is a moment of friction. And friction, especially in moments of frustration, leads to abandonment.</p><p>Our audit revealed that we were asking users to think far too much. Different pieces of information occupied the same space in the UI across different states. There was no consistent visual hierarchy. Users encountering an error state in Turnstile would find information in a completely different place than they would on a Challenge Page.</p><p>We made a fundamental decision: <b>one information architecture to rule them all</b>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3runU0ihKhNpgdw3LxNZUv/aa4bd76efb5847fde0659bccdae7242d/7.png" />
          </figure><p><sup><i>Visual diagram displaying a unified information architecture with a consistent structure across Turnstile widget and Challenge pages</i></sup></p><p>Both Turnstile and Challenge Pages would now follow the same structural pattern. The same visual hierarchy. The same placement for actions, for explanatory text, for links to documentation.</p><p>Did this constrain our design options? Absolutely. We had to say no to a lot of creative ideas that didn't fit the framework. But constraints aren't the enemy of good design — they're often its best friend. By limiting our options, we could go deeper on the details that actually mattered.</p><p>For users, the benefit is profound: they don't need to re-learn what each piece of the UI means. Error states look consistent. Help links are always in the same place. Once you understand one state, you understand them all. That's cognitive load reduced to a minimum — exactly where it should be during a security verification.</p>
    <div>
      <h2>What user research taught us</h2>
      <a href="#what-user-research-taught-us">
        
      </a>
    </div>
    <p>How do you keep yourself accountable when redesigning something that billions of people see? You test. A lot.</p><p>We recruited 8 participants across 8 different countries, deliberately seeking diversity in age, digital savviness, and cultural background. We weren't looking for tech-savvy early adopters — we wanted to understand how the redesign would work for everyone.</p><p>Our approach was rigorous: participants saw both the current experience and proposed changes, without knowing which was "old" or "new." We counterbalanced positioning to eliminate bias. And we did not just test our new ideas, but also challenged our assumptions about what needed changing in the first place.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/59mmLHihbM9TewXmlYQwbO/e5db88efca948de1b31e9dc499195eb8/8.png" />
          </figure><p><sup><i>Two different versions of a Turnstile being tested in an A/B test</i></sup></p>
    <div>
      <h3>Some things didn’t need fixing</h3>
      <a href="#some-things-didnt-need-fixing">
        
      </a>
    </div>
    <p>One hypothesis: should we align with competitors? Most CAPTCHA providers show "I am human" across all states. We use distinct content — "Verify you are human," then "Verifying...," then "Success!"</p><p>Were we overcomplicating things? We tested it head-to-head.</p><p>Our approach won decisively. For the interactivity state, "Verify you are human" scored 5 out of 8 points versus just 3 for "I am human." For the verifying state, it was even more dramatic — 7.5 versus 0.5. Users wanted to know what was happening, not just be told what they were.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6ke1kO0i7EZxZm6voQBpyn/f489bef9b66d1221aa89adb5746559b7/9.png" />
          </figure><p><sup><i>User testing results: users strongly favored our approach over the competitor-style design</i></sup></p><p>This experiment didn't ship as a feature, but it was invaluable. It gave us confidence we weren't just being different for the sake of it. Some things were already right.</p>
    <div>
      <h3>But these needed to change</h3>
      <a href="#but-these-needed-to-change">
        
      </a>
    </div>
    <p>The research surfaced four areas where we were failing users:</p><p><b>Help, not bureaucracy</b>. When users encountered errors, we offered "Send Feedback." In testing, they were baffled. "Who am I sending this to? The website? Cloudflare? My ISP?" More importantly, we discovered something fundamental: at the moment of maximum frustration, people don't want to file a report — they want to fix the problem. We replaced "Send Feedback" with "Troubleshoot" — a single word that promises action rather than bureaucracy.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2jN2reUR55qCbssCDFTZfB/fb5396ec853ee549ebfec5d0d94b901f/10.png" />
          </figure><p><sup><i>The problematic "Send Feedback" prompt: users didn't know who they were sending feedback to</i></sup></p><p><b>Attention, not alarm</b>. We'd used red backgrounds liberally for errors. The reaction in testing was visceral — participants felt they had failed, felt powerless. Even for simple issues that would resolve with a retry, users assumed the worst and gave up. Red at full saturation wasn't communicating "Here's something to address." It was communicating "You have failed, and there's nothing you can do." The fix: red only for icons, never for text or backgrounds.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5seE6Xcrj9lvSpBYDEkk6N/7f0c1c17fd86b05397d35b685b0addfb/11.png" />
          </figure><p><sup><i>The evolution: from the states with unclear error state description in red to much clearer and concise error communication in neutral-color text.</i></sup></p><p><b>Scannable, not verbose</b>. We'd tried to be thorough, explaining errors in technical detail. It backfired. Non-technical users found it alienating. Technical users didn't need it. Everyone was trying to read it in the tiny real estate of a widget. The lesson: less is more, especially in constrained spaces during stressful moments.</p><p><b>Accessible to everyone</b>. Our audit revealed 10px fonts in some states. Grey text that technically met AA (at least 4.5:1 for normal text and 3:1 for large text) compliance but was difficult to read in practice. "Technically compliant" isn't good enough when you're serving the entire Internet.</p><p>We set a clear goal: to meet the <a href="https://www.w3.org/TR/WCAG22/"><u>WCAG 2.2 AAA</u></a> standard— the highest and most stringent level of web accessibility compliance, designed to make content accessible to the broadest range of users, including those with severe disabilities. Throughout the redesign, when visual consistency conflicted with readability, readability won. Every time.</p><p>This extended beyond vision. We designed for screen reader users, keyboard-only navigators, and people with color vision variations — going beyond what automated compliance tools can catch.</p><p>And accessibility isn't just about impairments — it's about language. What fits in English, overflows in German. What's concise in Spanish is ambiguous in Japanese. Supporting over 40 languages forced us to radically simplify. The same "Unable to connect to website / Troubleshoot" pattern now works across English, Bulgarian, Danish, German, Greek, Japanese, Indonesian, Russian, Slovak, Slovenian, Serbian, Filipino, and many more.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6e4pvgMUS4BUXsPqi1qV6l/b6ffdc0d5f1e8e90394169db7162d10c/12.png" />
          </figure><p><sup><i>The redesigned error state across 12 languages — consistent layout despite varying text lengths </i></sup></p>
    <div>
      <h2>Final redesign</h2>
      <a href="#final-redesign">
        
      </a>
    </div>
    <p>So what did we actually ship?</p><p>First, let's talk about what we didn't change. The happy path — "Verify you are human" → "Verifying..." → "Success!" — tested exceptionally well. Users understood what was happening at each stage. The distinct content for each state, which we'd worried might be overcomplicating things, was actually our competitive advantage.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2R4QJ04uz9r1TVZjuqsHG9/61c1023eaa105b4841456258f3370220/13.png" />
          </figure><p><i><sup> The happy path: Verify you are human → Verifying → Success! These states tested well and remained largely unchanged</sup></i></p><p>But for the states that needed work, we made significant changes guided by everything we learned.</p>
    <div>
      <h3>Simplified, scannable content</h3>
      <a href="#simplified-scannable-content">
        
      </a>
    </div>
    <p>We radically reduced the amount of text in error states. Instead of verbose explanations like "Your device clock is set to a wrong time or this challenge page was accidentally cached by an intermediary and is no longer available," we now show:</p><ol><li><p>A clear, simple state name (e.g., "Incorrect device time")</p></li><li><p>A prominent "Troubleshoot" link</p></li></ol><p>That's it. The detailed guidance now lives in a dedicated modal screen that opens when users need it — giving them room to actually read and follow troubleshooting steps.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ZYjlJgw6DOiTuJBFXpewn/5d714c3a19723dfe9fa9802d0d5926b8/14.png" />
          </figure><p><sup><i>The troubleshooting modal: detailed guidance when users need it, without cluttering the widget</i></sup></p><p>The troubleshooting modal provides context ("This error occurs when your device's clock or calendar is inaccurate. To complete this website’s security verification process, your device must be set to the correct date and time in your time zone."), numbered steps to try, links to documentation, and — only after the user has tried to resolve the issue — an option to submit feedback to Cloudflare. Help first, feedback second.</p>
    <div>
      <h3>AAA accessibility compliance</h3>
      <a href="#aaa-accessibility-compliance">
        
      </a>
    </div>
    <p>Every state now meets WCAG 2.2 AAA standards for contrast and readability. Font sizes have established minimums. Interactive elements are clearly focusable and properly announced by screen readers.</p>
    <div>
      <h3>Unified experience across Turnstile and Challenge pages</h3>
      <a href="#unified-experience-across-turnstile-and-challenge-pages">
        
      </a>
    </div>
    <p>Whether users encounter the compact Turnstile widget or a full Challenge Page, the information architecture is now consistent. Same hierarchy. Same placement. Same mental model.</p><p>Challenge Pages now follow a clean structure: the website name and favicon at the top, a clear status message (like "Verification successful" or "Your browser is out of date"), and actionable guidance below. No more walls of orange or red text. No more technical jargon without context.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4PuWePTOaLihpfqm2iimJW/e34c4a009c36524a6d72c15ae0f78d00/15.png" />
          </figure><p><sup><i>Re-designed Challenge page states with clear troubleshooting instructions.</i></sup></p>
    <div>
      <h3>Validated across languages</h3>
      <a href="#validated-across-languages">
        
      </a>
    </div>
    <p>Every piece of content was tested in over 40 supported languages. Our process involved three layers of validation:</p><ol><li><p>Initial design review by the design team</p></li><li><p>Professional translation by our qualified vendor</p></li><li><p>Final review by native-speaking Cloudflare employees</p></li></ol><p>This wasn't just about translation accuracy — it was about ensuring the visual design held up when content length varied dramatically between languages.</p>
    <div>
      <h3>The complete picture</h3>
      <a href="#the-complete-picture">
        
      </a>
    </div>
    <p>The result is a security verification experience that's clearer, more accessible, less frustrating, and — crucially — just as secure. We didn't compromise on protection to improve the experience. We proved that good design and strong security aren't in conflict.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5t6FRRzLamGaTbEiZqVpnf/92b688679d1c8265ba3c6fd4159061bf/16.png" />
          </figure><p><sup><i>Re-designed Turnstile widgets on the left and a re-designed Challenge page on the right</i></sup></p><p>But designing the experience was only half the battle. Shipping it to billions of users? That's where Ana comes in.</p>
    <div>
      <h2>Part 2: Shipping to billions</h2>
      <a href="#part-2-shipping-to-billions">
        
      </a>
    </div>
    
    <div>
      <h4><b>Beyond centering a div</b></h4>
      <a href="#beyond-centering-a-div">
        
      </a>
    </div>
    <p>Some may say the hardest part of being a Frontend Engineer is centering a div. In reality, the real challenge often lies much deeper, especially when working close to the platform primitives. Building a critical piece of Internet infrastructure using native APIs forces you to think differently about UI development, tradeoffs, and long-term maintainability.</p><p>In our case, we use Rust to handle the UI for both the Turnstile widget and the Challenge page. This decision brought clear benefits in terms of safety and consistency across platforms, but it also increased frontend complexity. Many of us are used to the ergonomics of modern frameworks like React, where common UI interactions come almost for free. Working with Rust meant reimplementing even simple interactions using lower level constructs like <i>document.getElementById</i>, <i>createElement</i>, and <i>appendChild</i>.</p><p>On top of that, compile times and strict checks naturally slowed down rapid UI iteration compared to JavaScript based frameworks. Debugging was also more involved, as the tooling ecosystem is still evolving. These constraints pushed us to be more deliberate, more thoughtful, and ultimately more disciplined in how we approached UI development.</p>
    <div>
      <h4><b>Small visual changes, big global impact</b></h4>
      <a href="#small-visual-changes-big-global-impact">
        
      </a>
    </div>
    <p>What initially looked like small visual tweaks such as padding adjustments or alignment changes quickly revealed a much bigger challenge: internationalization.</p><p>Once translations were available, we had to ensure that content remained readable and usable across 38 languages and 16 different UI states. Text length variability alone required careful design decisions. Some translations can be 30 to 300 percent longer than English. A short English string like “Stuck?” becomes “Tidak bisa melanjutkan?” in Indonesian or “Es geht nicht weiter?” in German, dramatically changing layout requirements.</p><p>Right-to-left language support added another layer of complexity. Supporting Arabic, Persian or Farsi, and Hebrew meant more than flipping text direction. Entire layouts had to be mirrored, including alignment, navigation patterns, directional icons, and animation flows. Many of these elements are implicitly designed with left-to-right assumptions, so we had to revisit those decisions and make them truly bidirectional.</p><p>Ordered lists also required special care. Not every culture uses the Western 1, 2, 3 numbering system, and hardcoding numeric sequences can make interfaces feel foreign or incorrect. We leaned on locale-aware numbering and fully translatable list formats to ensure ordering felt natural and culturally appropriate in every language.</p>
    <div>
      <h4><b>Building confidence through testing</b></h4>
      <a href="#building-confidence-through-testing">
        
      </a>
    </div>
    <p>As we started listing action points in feedback reports, correctness became even more critical. Every action needed to render properly, trigger the right flow, and behave consistently across states, languages, and edge cases.</p><p>To get there, we invested heavily in testing. Unit tests helped us validate logic in isolation, while end-to-end tests ensured that new states and languages worked as expected in real scenarios. This testing foundation gave us confidence to iterate safely, prevented regressions, and ensured that feedback reports remained reliable and actionable for users.</p>
    <div>
      <h4><b>The outcome</b></h4>
      <a href="#the-outcome">
        
      </a>
    </div>
    <p>What began as a set of technical constraints turned into an opportunity to build a more robust, inclusive, and well-tested UI system. Working with fewer abstractions and closer to the browser primitives forced us to rethink assumptions, improve our internationalization strategy, and raise the overall quality bar.</p><p>The result is not just a solution that works, but one we trust. And that trust is what allows us to keep improving, even when centering a div turns out to be the easy part.</p>
    <div>
      <h2>Part 3: The impact</h2>
      <a href="#part-3-the-impact">
        
      </a>
    </div>
    <p>Designing for billions of people is a responsibility we take seriously. At this scale, it is essential to leverage measurable data to tell us the real impact of our design choices. As we prepare to roll out these changes, we are focusing on <b>five key metrics</b> that will tell us if we’ve truly succeeded in making the Internet’s most-seen UI more human.</p>
    <div>
      <h4><b>1. Challenge Completion Rate</b></h4>
      <a href="#1-challenge-completion-rate">
        
      </a>
    </div>
    <p>Our primary north star is the <b>Challenge Solve Rate: </b>the percentage of issued challenges that are successfully completed. By moving away from technical jargon like "intermediary caching" and toward simple, actionable labels like "Incorrect device time," we expect a significant uptick in CSR. A higher CSR doesn't mean we're being easier on bots; it means we’re removing the hurdles that were accidentally tripping up legitimate human users.</p>
    <div>
      <h4><b>2. Time to Complete</b></h4>
      <a href="#2-time-to-complete">
        
      </a>
    </div>
    <p>Every second a user spends on a challenge page is a second they aren't getting the information that they need. Our research showed that users were often paralyzed by choice when seeing a wall of red text. With our new scannable, neutral-color design, we are tracking <b>Time to Complete</b> to ensure users can identify and resolve issues in seconds rather than minutes.</p>
    <div>
      <h4><b>3. Abandonment Rate Changes</b></h4>
      <a href="#3-abandonment-rate-changes">
        
      </a>
    </div>
    <p>In the past, our liberal use of "saturated red" caused a visceral reaction: users felt they had failed and simply gave up. By reserving red only for icons and using a unified architecture, we aim to reduce Abandonment Rates. We want users to feel empowered to click Troubleshoot rather than feeling powerless and clicking away.</p>
    <div>
      <h4><b>4. Support Ticket Volume</b></h4>
      <a href="#4-support-ticket-volume">
        
      </a>
    </div>
    <p>One of the bigger shifts from a product perspective is our new Troubleshooting Modal. By providing clear, numbered steps directly within the widget, we are building self-service support into the UI. We expect this to result in a measurable decrease in support ticket volume for both our customers and our own internal teams.</p>
    <div>
      <h4><b>5. Social Sentiment</b></h4>
      <a href="#5-social-sentiment">
        
      </a>
    </div>
    <p>We know that security challenges are rarely loved, but they shouldn't be hated because they are confusing. We are monitoring <b>Social Sentiment</b> across community forums, feedback reports, and social channels to see if the conversation shifts from "this widget is broken" to "I had an issue, but I fixed it".</p><p>As a Product Manager, my goal is often invisible security — the best challenge is the one the user never sees. But when a challenge <i>must</i> be seen, it should be an assistant, not a bouncer. This redesign proves that <b>AAA accessibility</b> and <b>high-security standards</b> aren't in competition; they are two sides of the same coin. By unifying the architecture of Turnstile and Challenge Pages, we’ve built a foundation that allows us to iterate faster and protect the Internet more humanely than ever before.</p>
    <div>
      <h2>Looking ahead</h2>
      <a href="#looking-ahead">
        
      </a>
    </div>
    <p>This redesign is a foundation, not a finish line.</p><p>We're continuing to monitor how users interact with the new experience, and we're committed to iterating based on what we learn. The feedback mechanisms we've built into the new design — the ones that actually help users troubleshoot, rather than just asking them to report problems — will give us richer insights than we've ever had before.</p><p>We're also watching how the security landscape evolves. As bot attacks grow more sophisticated, and as AI continues to blur the line between human and automated behavior, the challenge of verification will only get harder. Our job is to stay ahead — to keep improving security without making the human experience worse.</p><p>If you encounter the new Turnstile or Challenge Pages and have feedback, we want to hear it. Reach out through our <a href="https://community.cloudflare.com/"><u>community forums</u></a> or use the feedback mechanisms built into the experience itself.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Turnstile]]></category>
            <category><![CDATA[Challenge Page]]></category>
            <category><![CDATA[Design]]></category>
            <category><![CDATA[Product Design]]></category>
            <category><![CDATA[User Research]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Engineering]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Accessibility]]></category>
            <guid isPermaLink="false">19fiiQAG0XsaS9p0daOBus</guid>
            <dc:creator>Leo Bacevicius</dc:creator>
            <dc:creator>Ana Foppa</dc:creator>
            <dc:creator>Marina Elmore</dc:creator>
        </item>
        <item>
            <title><![CDATA[How we mitigated a vulnerability in Cloudflare’s ACME validation logic]]></title>
            <link>https://blog.cloudflare.com/acme-path-vulnerability/</link>
            <pubDate>Mon, 19 Jan 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[ A vulnerability was recently identified in Cloudflare’s automation of certificate validation. Here we explain the vulnerability and outline the steps we’ve taken to mitigate it.  ]]></description>
            <content:encoded><![CDATA[ <p><i>This post was updated on January 20, 2026.</i></p><p>On October 13, 2025, security researchers from <a href="https://fearsoff.org/"><u>FearsOff</u></a> identified and reported a vulnerability in Cloudflare's ACME (Automatic Certificate Management Environment) validation logic that disabled some of the <a href="https://developers.cloudflare.com/waf/"><u>WAF</u></a> features on specific ACME-related paths. The vulnerability was reported and validated through Cloudflare’s <a href="https://hackerone.com/cloudflare?type=team"><u>bug bounty</u></a> program.</p><p>The vulnerability was rooted in how our edge network processed requests destined for the ACME HTTP-01 challenge path (<code><i>/.well-known/acme-challenge/*</i></code>). </p><p>Here, we’ll briefly explain how this protocol works and the action we took to address the vulnerability. </p><p><b>Cloudflare has patched this vulnerability and there is no action necessary for Cloudflare customers.</b> There is no evidence of any malicious actor abusing this vulnerability.</p>
    <div>
      <h3>How ACME works to validate certificates</h3>
      <a href="#how-acme-works-to-validate-certificates">
        
      </a>
    </div>
    <p>ACME is a protocol used to <a href="https://www.cloudflare.com/application-services/solutions/certificate-lifecycle-management/">automate the issuance, renewal, and revocation</a> of <a href="https://www.cloudflare.com/application-services/products/ssl/"><u>SSL/TLS certificates</u></a>. When an HTTP-01 challenge is used to validate domain ownership, a Certificate Authority (CA) will expect to find a validation token at the HTTP path following the format of <i>http://{customer domain}/.well-known/acme-challenge/{token value}</i>. </p><p>If this challenge is used by a certificate order managed by Cloudflare, then Cloudflare will respond on this path and provide the token provided by the CA to the caller. If the token provided does not correlate to a Cloudflare managed order, then this request would be passed on to the customer origin, since they may be attempting to complete domain validation as a part of some other system. Check out the flow below for more details — other use cases are discussed later in the blog post.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6myH4sEuRj4hhBPYiITWsB/9be3e62bdd7001ab1ef9b01db094de5b/BLOG-3067_2.png" />
          </figure>
    <div>
      <h3>The underlying logic flaw </h3>
      <a href="#the-underlying-logic-flaw">
        
      </a>
    </div>
    <p>Certain requests to<i> /.well-known/acme-challenge/*</i> would cause the logic serving ACME challenge tokens to disable WAF features on a challenge request, and allow the challenge request to continue to the origin when it should have been blocked.</p><p>Previously, when Cloudflare was serving a HTTP-01 challenge token, if the path requested by the caller matched a token for an active challenge in our system, the logic serving an ACME challenge token would disable WAF features, since Cloudflare would be directly serving the response. This is done because those features can interfere with the CA’s ability to validate the token values and would cause failures with automated certificate orders and renewals.</p><p>However, in the scenario that the token used was associated with a different zone and not directly managed by Cloudflare, the request would be allowed to proceed onto the customer origin without further processing by WAF rulesets.</p>
    <div>
      <h3>How we mitigated this vulnerability</h3>
      <a href="#how-we-mitigated-this-vulnerability">
        
      </a>
    </div>
    <p>To mitigate this issue, a code change was released. This code change only allows the set of security features to be disabled in the event that the request matches a valid ACME HTTP-01 challenge token for the hostname. In that case, Cloudflare has a challenge response to serve back.</p>
    <div>
      <h3>Cloudflare customers are protected</h3>
      <a href="#cloudflare-customers-are-protected">
        
      </a>
    </div>
    <p>As we noted above,<b> Cloudflare has patched this vulnerability and Cloudflare customers do not need to take any action.</b> In addition, there is no evidence  of any malicious actor abusing this vulnerability.</p>
    <div>
      <h3>Moving quickly with vulnerability transparency</h3>
      <a href="#moving-quickly-with-vulnerability-transparency">
        
      </a>
    </div>
    <p>As always, we thank the external researchers for responsibly disclosing this vulnerability. We encourage the Cloudflare community to submit any identified vulnerabilities to help us continually improve the security posture of our products and platform. </p><p>We also recognize that the trust you place in us is paramount to the success of your infrastructure on Cloudflare. We consider these vulnerabilities with the utmost concern and will continue to do everything in our power to mitigate impact. We deeply appreciate your continued trust in our platform and remain committed not only to prioritizing security in all we do, but also acting swiftly and transparently whenever an issue does arise. </p> ]]></content:encoded>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Network Services]]></category>
            <guid isPermaLink="false">lHLq8aIK0VMgRiInLXnrw</guid>
            <dc:creator>Hrushikesh Deshpande</dc:creator>
            <dc:creator>Andrew Mitchell</dc:creator>
            <dc:creator>Leland Garofalo</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare WAF proactively protects against React vulnerability]]></title>
            <link>https://blog.cloudflare.com/waf-rules-react-vulnerability/</link>
            <pubDate>Wed, 03 Dec 2025 14:20:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare offers protection against a new high profile vulnerability for React Server Components: CVE-2025-55182. All WAF customers are automatically protected as long as the WAF is deployed. ]]></description>
            <content:encoded><![CDATA[ <p></p><p><br /></p><p>Cloudflare has deployed a new protection to address a vulnerability in React Server Components (RSC). <b>All Cloudflare customers are automatically protected, including those on free and paid plans, as long as their React application traffic is proxied through the Cloudflare Web Application Firewall (WAF).</b></p><p>Cloudflare Workers are inherently immune to this exploit. React-based applications and frameworks deployed on Workers are not affected by this vulnerability.</p><p>We strongly recommend that customers immediately update their systems to the most recent version of React, despite our WAF being designed to detect and prevent this exploit.</p>
    <div>
      <h3>What you need to know</h3>
      <a href="#what-you-need-to-know">
        
      </a>
    </div>
    <p>Cloudflare has been alerted by its security partners to a Remote Code Execution (RCE) vulnerability impacting Next.js, React Router, and other React frameworks (security advisory CVE-2025-55182, rated CVSS 10.0). Specifically, React version 19.0, 19.1, and 19.2, and Next.js from version 15 through 16 were found to insecurely deserialize malicious requests, leading to RCE.</p><p><b>In response, Cloudflare has deployed new rules across its network, with the default action set to Block. </b>These new protections are included in both the Cloudflare Free Managed Ruleset (available to all Free customers) and the standard Cloudflare Managed Ruleset (available to all paying customers). More information about the different rulesets can be found in our <a href="https://developers.cloudflare.com/waf/managed-rules/#available-managed-rulesets"><u>documentation</u></a>.</p><p>The rule ID is as follows:</p><table><tr><td><p>Ruleset</p></td><td><p>Rule ID</p></td><td><p>Default action</p></td></tr><tr><td><p><code>Managed Ruleset</code></p></td><td><p><code>33aa8a8a948b48b28d40450c5fb92fba</code></p></td><td><p>Block</p></td></tr><tr><td><p><code>Free Ruleset</code></p></td><td><p><code>2b5d06e34a814a889bee9a0699702280</code></p></td><td><p>Block</p></td></tr></table><p><b>Customers on Professional, Business, or Enterprise plans should ensure that Managed Rules are enabled  —  </b><a href="https://developers.cloudflare.com/waf/get-started/#1-deploy-the-cloudflare-managed-ruleset"><b><u>follow these steps to turn it on</u></b></a><b>.</b> Customers on a Free plan have these rules enabled by default.</p><p>We recommend that customers <b>update to the latest version of React 19.2.1 and the latest versions of Next.js (16.0.7, 15.5.7, 15.4.8)</b>.</p><p>The rules were deployed at 5:00 PM GMT on Tuesday, December 2, 2025. Since their release until the publication of this blog and the official CVE announcement, we have not observed any attempted exploit.</p>
    <div>
      <h3>Looking forward</h3>
      <a href="#looking-forward">
        
      </a>
    </div>
    <p>The Cloudflare security team has collaborated with partners to identify various attack patterns and ensure the new rules effectively prevent any bypasses. Over the coming hours and days, the team will maintain continuous monitoring for potential attack variations, updating our protections as necessary to secure all traffic proxied via Cloudflare.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2Nej3zxhHlPNwFL5L5k7Zq/e19062d3811e9704d4ddd0ad16428fa4/BLOG-3089_2.png" />
          </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Cloudforce One]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Web Application Firewall]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[React]]></category>
            <guid isPermaLink="false">6yAZ5qr270gBwMkcYu63DX</guid>
            <dc:creator>Daniele Molteni</dc:creator>
        </item>
        <item>
            <title><![CDATA[Get better visibility for the WAF with payload logging]]></title>
            <link>https://blog.cloudflare.com/waf-payload-logging/</link>
            <pubDate>Mon, 24 Nov 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ The WAF provides ways for our customers to gain insight into why it takes certain actions. The more granular and precise the insight, the more reproducible and understandable it is. Revamped payload logging is one such method.  ]]></description>
            <content:encoded><![CDATA[ <p>As the surface area for attacks on the web increases, Cloudflare’s <a href="https://www.cloudflare.com/application-services/products/waf/"><u>Web Application Firewall (WAF)</u></a>  provides a myriad of solutions to mitigate these attacks. This is great for our customers, but the cardinality in the workloads of the millions of requests we service means that generating false positives is inevitable. This means that the default configuration we have for our customers has to be fine-tuned. </p><p>Fine-tuning isn’t an opaque process: customers have to get some data points and then decide what works for them. This post explains the technologies we offer to enable customers to see why the WAF takes certain actions — and the improvements that have been made to reduce noise and increase signal.</p>
    <div>
      <h2>The Log action is great — can we do more?</h2>
      <a href="#the-log-action-is-great-can-we-do-more">
        
      </a>
    </div>
    <p>Cloudflare’s <a href="https://www.cloudflare.com/application-services/products/waf/"><u>WAF</u></a> protects origin servers from different kinds of layer 7 attacks, which are attacks that <a href="https://www.cloudflare.com/learning/ddos/application-layer-ddos-attack/"><u>target the application layer</u></a>. Protection is provided with various tools like:</p><ul><li><p><a href="https://developers.cloudflare.com/waf/managed-rules/"><u>Managed rules</u></a>, which security analysts at Cloudflare write to address <a href="https://www.cve.org/"><u>common vulnerabilities and exposures (CVE)</u></a>, <a href="https://www.cloudflare.com/learning/security/threats/owasp-top-10/"><u>OWASP security risks</u></a>, and vulnerabilities like Log4Shell.</p></li><li><p><a href="https://developers.cloudflare.com/waf/custom-rules/"><u>Custom rules</u></a>, where customers can write rules with the expressive <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/"><u>Rules language</u></a>.</p></li><li><p><a href="https://developers.cloudflare.com/waf/rate-limiting-rules/"><u>Rate limiting rules</u></a>, <a href="https://developers.cloudflare.com/waf/detections/malicious-uploads/"><u>malicious uploads detection</u></a>, <a href="https://developers.cloudflare.com/waf/detections/leaked-credentials/"><u>leaked credentials detection</u></a>, etc.</p></li></ul><p>These tools are built on the <a href="https://developers.cloudflare.com/ruleset-engine/"><u>Rulesets engine</u></a>. When there is a match on a <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/"><u>Rule expression</u></a>, the engine executes an <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/actions/"><u>action</u></a>.</p><p>The Log action is used to simulate the behaviour of rules. This action proves that a rule expression is matched by the engine and emits a log event which can be accessed via <a href="https://developers.cloudflare.com/waf/analytics/security-analytics/"><u>Security Analytics</u></a>, <a href="https://developers.cloudflare.com/waf/analytics/security-events/"><u>Security Events</u></a>, <a href="https://developers.cloudflare.com/logs/logpush/"><u>Logpush</u></a> or <a href="https://developers.cloudflare.com/logs/logpush/logpush-job/edge-log-delivery/"><u>Edge Log Delivery</u></a>.</p><p>Logs are great at validating a rule works as expected on the traffic it was expected to match, but showing that the rule matches isn’t sufficient, especially when a rule expression can take many code paths.

In pseudocode, an expression can look like:</p><p><code>If any of the http request headers contains an “authorization” key OR the lowercased representation of the http host header starts with “cloudflare” THEN log</code>

The rules language syntax will be:</p>
            <pre><code>any(http.request.headers[*] contains "authorization") or starts_with(lower(http.host), "cloudflare")</code></pre>
            <p>Debugging this expression poses a couple of problems. Is it the left-hand side (LHS) or right-hand side (RHS) of the OR expression above that matches? Functions such as <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#decode_base64"><u>Base64 decoding</u></a>, <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#url_decode"><u>URL decoding</u></a>, and in this case <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#lower"><u>lowercasing</u></a> can apply transformations to the original representation of these fields, which leads to further ambiguity as to which characteristics of the request led to a match.</p><p>To further complicate this, many <a href="https://developers.cloudflare.com/ruleset-engine/about/rules/"><u>rules</u></a> in a <a href="https://developers.cloudflare.com/ruleset-engine/about/rulesets/"><u>ruleset</u></a> can register matches. Rulesets like <a href="https://developers.cloudflare.com/waf/managed-rules/reference/owasp-core-ruleset/"><u>Cloudflare OWASP</u></a> use a cumulative score of different rules to trigger an action when the score crosses a <a href="https://developers.cloudflare.com/waf/managed-rules/reference/owasp-core-ruleset/concepts/#score-threshold"><u>set threshold</u></a>. </p><p>Additionally, the expressions of the Cloudflare Managed and OWASP rules are private. This increases our security posture – but it also means that customers can only guess what these rules do from their titles, tags and descriptions. For instance, one might be labeled “SonicWall SMA - Remote Code Execution - CVE:CVE-2025-32819.”</p><p>Which raises questions: What part of my request led to a match in the Rulesets engine? Are these false positives? </p><p>This is where payload logging shines. It can help us drill down to the specific fields and their respective values, post-transformation, in the rule that led to a match. </p>
    <div>
      <h2>Payload logging</h2>
      <a href="#payload-logging">
        
      </a>
    </div>
    <p>Payload logging is a feature that logs which fields in the request are associated with a rule that led to the WAF taking an action. This reduces ambiguity and provides useful information that can help spot check false positives, guarantee correctness, and aid in fine-tuning of these rules for better performance.</p><p>From the example above, a payload log entry will contain either the LHS or RHS of the expression, but not both. </p>
    <div>
      <h3>How does payload logging work ?</h3>
      <a href="#how-does-payload-logging-work">
        
      </a>
    </div>
    <p>The payload logging and Rulesets engines are built on Wirefilter, which has been <a href="https://blog.cloudflare.com/building-fast-interpreters-in-rust/"><u>explained extensively</u></a>.</p><p>Fundamentally, these engines are objects written in Rust which implement a <a href="https://github.com/cloudflare/wirefilter/blob/72e3954622ff7f30c4171f45461c2274656ee1e3/engine/src/compiler.rs#L7"><u>compiler</u></a> trait. This trait drives the compilation of the abstract syntax trees (ASTs) derived from these expressions.</p>
            <pre><code>struct PayloadLoggingCompiler {
     regex_cache HashMap&lt;String, Arc&lt;Regex&gt;&gt;
}

impl wirefilter::Compiler for PayloadLoggingCompiler {
	type U = PayloadLoggingUserData
	
	fn compile_logical_expr(&amp;mut self, node: LogicalExpr) -&gt; CompiledExpr&lt;Self::U&gt; {
		// ...
		let regex = self.regex_cache.entry(regex_pattern)
		.or_insert_with(|| Arc::new(regex))
		// ...
	}

}</code></pre>
            <p>The Rulesets Engine executes an expression and if it evaluates to true, the expression and its <a href="https://github.com/cloudflare/wirefilter/blob/72e3954622ff7f30c4171f45461c2274656ee1e3/engine/src/execution_context.rs#L38"><u>execution context</u></a> are sent to the payload logging compiler for re-evaluation. The execution context provides all the runtime values needed to evaluate the expression.</p><p>After re-evaluation is done, the fields involved in branches of the expression that evaluate to true are logged.</p><p>The structure of the log is a map of wirefilter fields and their values <code>Map&lt;Field, Value&gt;</code></p>
            <pre><code>{

	“http.host”: “cloudflare.com”,
	“http.method”: “get”,
	“http.user_agent”: “mozilla”

}</code></pre>
            <p>Note: <a href="https://blog.cloudflare.com/encrypt-waf-payloads-hpke/"><u>These logs are encrypted with the public key provided by the customer.</u></a> </p><p>These logs go through our logging pipeline and can be read in different ways. Customers can configure a Logpush job to write to a custom Worker we built that uses the customer’s private key to automatically decrypt these logs. The Payload logging <a href="https://github.com/cloudflare/matched-data-cli"><u>CLI tool</u></a>, <a href="https://github.com/cloudflare/matched-data-worker"><u>Worker</u></a>, or the Cloudflare dashboard can also be used for decryption.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4jTk0nPsfA0yowEwHx5VUr/eed6cece439d238b1ec861a9e0760dd6/image5.png" />
          </figure>
    <div>
      <h3>What improvements have been shipped?</h3>
      <a href="#what-improvements-have-been-shipped">
        
      </a>
    </div>
    <p>In wirefilter, some fields are array types. The field <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.headers.names/"><u>http.request.headers.names</u></a> is an array of all the header names in a request. For example:</p>
            <pre><code>[“content-type”, “content-length”, “authorization”, "host"]</code></pre>
            <p>An expression that reads <code>any(http.request.headers.names[*] contains “c”)</code> will evaluate to true because at least one of the headers contains the letter “c”. With the previous version of the payload logging compiler, all the headers in the “http.request.headers.names” field will be logged since it's a part of the expression that evaluates to true.  </p><p><b>Payload log (previous)</b></p>
            <pre><code>http.request.headers.names[*] = [“content-type”, “content-length”, “authorization”, "host"]</code></pre>
            <p>Now, we partially evaluate the array fields and log the indexes that match the expressions constraint. In this case, it’ll be just the headers that contain a “c”!</p><p><b>Payload log (new)</b></p>
            <pre><code>http.request.headers.names[0,1] = [“content-type”, “content-length”]</code></pre>
            
    <div>
      <h3>Operators</h3>
      <a href="#operators">
        
      </a>
    </div>
    <p>This brings us to operators in wirefilter. Some operators like “eq” result in exact matches, e.g. <code>http.host eq “a.com”</code>. There are other operators that result in “partial” matches – like “in”, “contains”, “matches” – that work alongside regexes. 

The expression in this example: `<code>any(http.request.headers[*] contains “c”)`</code> uses a “contains” operator which produces a partial match. It also uses the “<code>any</code>” function which we can say produces a partial match, because if at least one of the headers contains a “c”, then we should log <i>that</i> header – not <i>all</i> the headers as we did in the previous version.</p><p>With the improvements to the payload logging compiler, when these expressions are evaluated, we log just the partial matches. In this case, the new payload logging compiler handles the “contains” operator similarly to <a href="https://doc.rust-lang.org/std/string/struct.String.html#method.find"><u>the “find” method for bytes in the Rust standard library</u></a>. This improves our payload log to:</p>
            <pre><code>http.request.headers.names[0,1] = [“c”, “c”]</code></pre>
            <p>This makes things a lot clearer. It also saves our logging pipeline from processing millions of bytes. For example, a field that is analyzed a lot is the request body — <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.body.raw/"><u>http.request.body.raw </u></a>— which can be tens of kilobytes in size. Sometimes the expressions are checking for a regex pattern that should match three characters. In this case we’ll be logging 3 bytes instead of kilobytes!</p>
    <div>
      <h3>Context</h3>
      <a href="#context">
        
      </a>
    </div>
    <p>I know, I know, <code>[“c”, “c”]</code> doesn’t really mean much. Even if we’ve provided the exact reason for the match and are significantly saving on the volume of bytes written to our customers storage destinations, the key goal is to provide useful debugging information to the customer. As part of the payload logging improvements, the compiler now also logs a “before” and "after” (if applicable) for partial matches. The size for these buffers are currently 15 bytes each. This means our payload log now looks like:</p>
            <pre><code>http.request.headers[0,1] = [
    {
        before: null, // isnt included in the final log
        content: “c”, 
        after: “ontent-length”
    },
    {
        before: null, // isnt included in the final log
        content: “c”, 
        after:”ontent-type”
    }
]</code></pre>
            <p><b>Example of payload log (previous)</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4yhJWnG9FiDnQRAuV82t6C/0dbef6ded6f48a7f74d6a69aaf7d52a5/image7.png" />
          </figure><p><b>Example of payload log (new)</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6M1bQKaqNvalqtJo7nO6fM/8e87e1927ed404495273c082e258e6ee/image4.png" />
          </figure><p>In the previous log, we have all the header values. In the new log, we have the 8th index which is a malicious script in a HTTP header. The match is on the “&lt;script&gt;” tag and the rest is the context which is the text in gray.      </p>
    <div>
      <h3>Optimizations</h3>
      <a href="#optimizations">
        
      </a>
    </div>
    <p>Managed rules rely heavily on regular expressions to fingerprint malicious requests. Parsing and compiling these expressions are CPU-intensive tasks. As managed rules are written once and deployed across millions of zones, we benefit from compiling these regexes and caching them in memory. This saves us CPU cycles as we don’t have to re-compile these until the process restarts.</p><p>The Payload logging compiler uses a lot of dynamically sized arrays or vectors to store the intermediate state for these logs. Crates like <a href="https://docs.rs/smallvec/latest/smallvec/"><u>smallvec</u></a> are also used to reduce heap allocations.  </p>
    <div>
      <h3>The infamous “TRUNCATED” value</h3>
      <a href="#the-infamous-truncated-value">
        
      </a>
    </div>
    <p>Sometimes, customers see <a href="https://github.com/cloudflare/matched-data-cli/blob/master/src/main.rs#L124-L129"><u>“truncated”</u></a> in their payload logs. This is because every firewall event has a size limit in bytes. When this limit is exceeded, the payload log is truncated. </p><p><b>Payload log (previous)</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7234Ub1YB3xCMd6thJ5Gje/22b87bc0149f82a9315c258227764e58/image6.png" />
          </figure><p><b>Payload log (new)</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3mBw8ElDalEbpjKmGoVTT3/f877a232df29c6e01889cc1941d1b69a/image1.png" />
          </figure><p>We have seen the p50 byte size of the payload logs shrink from 1.5 Kilobytes to 500 bytes – a 67% reduction! That means way fewer truncated payload logs.</p>
    <div>
      <h3>What’s next?</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We’re currently using a <a href="https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8_lossy"><u>lossy representation of utf-8 strings</u></a> to represent values. This means that non-valid utf-8 strings like multimedia are represented as <a href="https://doc.rust-lang.org/std/char/constant.REPLACEMENT_CHARACTER.html"><u>U+FFFD unicode replacement characters</u></a>. For rules that will work on binary data, the integrity of these values should be preserved with byte arrays or with a different serialization format.</p><p>The storage format for payload logging is JSON. We’ll be benchmarking this alongside other binary formats like <a href="https://cbor.io/"><u>CBOR</u></a>, <a href="https://capnproto.org/"><u>Cap'n Proto</u></a>, <a href="https://protobuf.dev/"><u>Protobuf</u></a>, etc., to see how much processing time this saves our pipeline. This will help us deliver logs to our customers faster, with the added advantage that binary formats can also help with maintaining a defined schema that will be backward compatible. </p><p>Finally, payload logging only works with Managed rules. It will be rolled out to other Cloudflare WAF products like custom rules, WAF attack score, content scanning, <a href="https://developers.cloudflare.com/waf/detections/firewall-for-ai/"><u>Firewall for AI</u></a>, and more. 

<i>An example of payload logging showing prompts containing PII, detected by Firewall for AI: </i></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4nq4rYROygGRVW7mTZ3nqz/3c49b85c54eee6f98aa0397dfce32fa5/image2.png" />
          </figure>
    <div>
      <h2>Why should I be excited?</h2>
      <a href="#why-should-i-be-excited">
        
      </a>
    </div>
    <p>Visibility into the actions taken by the WAF will give customers assurance that their rules or configurations are doing exactly what they expect. Improvements to the specificity of payload logging is a step in this direction — and in the pipeline are further improvements to reliability, latency, and expansion to more WAF products.</p><p>As this was a breaking change to the JSON schema, we’ve rolled this out slowly to customers with <a href="https://developers.cloudflare.com/changelog/2025-05-08-improved-payload-logging/"><u>adequate documentation</u></a>.</p><p>To get started and enable payload logging, <a href="https://developers.cloudflare.com/waf/managed-rules/payload-logging/#turn-on-payload-logging"><u>visit our developer documentation</u></a>. </p> ]]></content:encoded>
            <category><![CDATA[Firewall]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Logging]]></category>
            <guid isPermaLink="false">2FEaxrBcxhN1nwrSuT9Jpd</guid>
            <dc:creator>Paschal Obba</dc:creator>
        </item>
        <item>
            <title><![CDATA[One IP address, many users: detecting CGNAT to reduce collateral effects]]></title>
            <link>https://blog.cloudflare.com/detecting-cgn-to-reduce-collateral-damage/</link>
            <pubDate>Wed, 29 Oct 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ IPv4 scarcity drives widespread use of Carrier-Grade Network Address Translation, a practice in ISPs and mobile networks that places many users behind each IP address, along with their collected activity and volumes of traffic. We introduce the method we’ve developed to detect large-scale IP sharing globally and mitigate the issues that result.  ]]></description>
            <content:encoded><![CDATA[ <p>IP addresses have historically been treated as stable identifiers for non-routing purposes such as for geolocation and security operations. Many operational and security mechanisms, such as blocklists, rate-limiting, and anomaly detection, rely on the assumption that a single IP address represents a cohesive<b>, </b>accountable<b> </b>entity or even, possibly, a specific user or device.</p><p>But the structure of the Internet has changed, and those assumptions can no longer be made. Today, a single IPv4 address may represent hundreds or even thousands of users due to widespread use of <a href="https://en.wikipedia.org/wiki/Carrier-grade_NAT"><u>Carrier-Grade Network Address Translation (CGNAT)</u></a>, VPNs, and proxy<b> </b>middleboxes. This concentration of traffic can result in <a href="https://blog.cloudflare.com/consequences-of-ip-blocking/"><u>significant collateral damage</u></a> – especially to users in developing regions of the world – when security mechanisms are applied without taking into account the multi-user nature of IPs.</p><p>This blog post presents our approach to detecting large-scale IP sharing globally. We describe how we <a href="https://www.cloudflare.com/learning/ai/how-to-secure-training-data-against-ai-data-leaks/">build reliable training data</a>, and how detection can help avoid unintentional bias affecting users in regions where IP sharing is most prevalent. Arguably it's those regional variations that motivate our efforts more than any other. </p>
    <div>
      <h2>Why this matters: Potential socioeconomic bias</h2>
      <a href="#why-this-matters-potential-socioeconomic-bias">
        
      </a>
    </div>
    <p>Our work was initially motivated by a simple observation: CGNAT is a likely unseen source of bias on the Internet. Those biases would be more pronounced wherever there are more users and few addresses, such as in developing regions. And these biases can have profound implications for user experience, network operations, and digital equity.</p><p>The reasons are understandable for many reasons, not least because of necessity. Countries in the developing world often have significantly fewer available IPs, and more users. The disparity is a historical artifact of how the Internet grew: the largest blocks of IPv4 addresses were allocated decades ago, primarily to organizations in North America and Europe, leaving a much smaller pool for regions where Internet adoption expanded later. </p><p>To visualize the IPv4 allocation gap, we plot country-level ratios of users to IP addresses in the figure below. We take online user estimates from the <a href="https://data.worldbank.org/indicator/IT.NET.USER.ZS"><u>World Bank Group</u></a> and the number of IP addresses in a country from Regional Internet Registry (RIR) records. The colour-coded map that emerges shows that the usage of each IP address is more concentrated in regions that generally have poor Internet penetration. For example, large portions of Africa and South Asia appear with the highest user-to-IP ratios. Conversely, the lowest user-to-IP ratios appear in Australia, Canada, Europe, and the USA — the very countries that otherwise have the highest Internet user penetration numbers.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2YBdqPx0ALt7pY7rmQZyLQ/049922bae657a715728700c764c4af16/BLOG-3046_2.png" />
          </figure><p>The scarcity of IPv4 address space means that regional differences can only worsen as Internet penetration rates increase. A natural consequence of increased demand in developing regions is that ISPs would rely even more heavily on CGNAT, and is compounded by the fact that CGNAT is common in mobile networks that users in developing regions so heavily depend on. All of this means that <a href="https://datatracker.ietf.org/doc/html/rfc7021"><u>actions known to be based</u></a> on IP reputation or behaviour would disproportionately affect developing economies. </p><p>Cloudflare is a global network in a global Internet. We are sharing our methodology so that others might benefit from our experience and help to mitigate unintended effects. First, let’s better understand CGNAT.</p>
    <div>
      <h3>When one IP address serves multiple users</h3>
      <a href="#when-one-ip-address-serves-multiple-users">
        
      </a>
    </div>
    <p>Large-scale IP address sharing is primarily achieved through two distinct methods. The first, and more familiar, involves services like VPNs and proxies. These tools emerge from a need to secure corporate networks or improve users' privacy, but can be used to circumvent censorship or even improve performance. Their deployment also tends to concentrate traffic from many users onto a small set of exit IPs. Typically, individuals are aware they are using such a service, whether for personal use or as part of a corporate network.</p><p>Separately, another form of large-scale IP sharing often goes unnoticed by users: <a href="https://en.wikipedia.org/wiki/Carrier-grade_NAT"><u>Carrier-Grade NAT (CGNAT)</u></a>. One way to explain CGNAT is to start with a much smaller version of network address translation (NAT) that very likely exists in your home broadband router, formally called a Customer Premises Equipment (or CPE), which translates unseen private addresses in the home to visible and routable addresses in the ISP. Once traffic leaves the home, an ISP may add an additional enterprise-level address translation that causes many households or unrelated devices to appear behind a single IP address.</p><p>The crucial difference between large-scale IP sharing is user choice: carrier-grade address sharing is not a user choice, but is configured directly by Internet Service Providers (ISPs) within their access networks. Users are not aware that CGNATs are in use. </p><p>The primary driver for this technology, understandably, is the exhaustion of the IPv4 address space. IPv4's 32-bit architecture supports only 4.3 billion unique addresses — a capacity that, while once seemingly vast, has been completely outpaced by the Internet's explosive growth. By the early 2010s, Regional Internet Registries (RIRs) had depleted their pools of unallocated IPv4 addresses. This left ISPs unable to easily acquire new address blocks, forcing them to maximize the use of their existing allocations.</p><p>While the long-term solution is the transition to IPv6, CGNAT emerged as the immediate, practical workaround. Instead of assigning a unique public IP address to each customer, ISPs use CGNAT to place multiple subscribers behind a single, shared IP address. This practice solves the problem of IP address scarcity. Since translated addresses are not publicly routable, CGNATs have also had the positive side effect of protecting many home devices that might be vulnerable to compromise. </p><p>CGNATs also create significant operational fallout stemming from the fact that hundreds or even thousands of clients can appear to originate from a single IP address. <b>This means an IP-based security system may inadvertently block or throttle large groups of users as a result of a single user behind the CGNAT engaging in malicious activity.</b></p><p>This isn't a new or niche issue. It has been recognized for years by the Internet Engineering Task Force (IETF), the organization that develops the core technical standards for the Internet. These standards, known as Requests for Comments (RFCs), act as the official blueprints for how the Internet should operate. <a href="https://www.rfc-editor.org/rfc/rfc6269.html"><u>RFC 6269</u></a>, for example, discusses the challenges of IP address sharing, while <a href="https://datatracker.ietf.org/doc/html/rfc7021"><u>RFC 7021</u></a> examines the impact of CGNAT on network applications. Both explain that traditional abuse-mitigation techniques, such as blocklisting or rate-limiting, assume a one-to-one relationship between IP addresses and users: when malicious activity is detected, the offending IP address can be blocked to prevent further abuse.</p><p>In shared IPv4 environments, such as those using CGNAT or other address-sharing techniques, this assumption breaks down because multiple subscribers can appear under the same public IP. Blocking the shared IP therefore penalizes many innocent users along with the abuser. In 2015 Ofcom, the UK's telecommunications regulator, reiterated these concerns in a <a href="https://oxil.uk/research/mc159-report-on-the-implications-of-carrier-grade-network-address-translators-final-report"><u>report</u></a> on the implications of CGNAT where they noted that, “In the event that an IPv4 address is blocked or blacklisted as a source of spam, the impact on a CGNAT would be greater, potentially affecting an entire subscriber base.” </p><p>While the hope was that CGNAT was only a temporary solution until the eventual switch to IPv6, as the old proverb says, nothing is more permanent than a temporary solution. While IPv6 deployment continues to lag, <a href="https://blog.apnic.net/2022/01/19/ip-addressing-in-2021/"><u>CGNAT deployments have become increasingly common</u></a>, and so do the related problems. </p>
    <div>
      <h2>CGNAT detection at Cloudflare</h2>
      <a href="#cgnat-detection-at-cloudflare">
        
      </a>
    </div>
    <p>To enable a fairer treatment of users behind CGNAT IPs by security techniques that rely on IP reputation, our goal is to identify large-scale IP sharing. This allows traffic filtering to be better calibrated and collateral damage minimized. Additionally, we want to distinguish CGNAT IPs from other large-scale sharing (LSS) IP technologies, such as VPNs and proxies, because we may need to take different approaches to different kinds of IP-sharing technologies.</p><p>To do this, we decided to take advantage of Cloudflare’s extensive view of the active IP clients, and build a supervised learning classifier that would distinguish CGNAT and VPN/proxy IPs from IPs that are allocated to a single subscriber (non-LSS IPs), based on behavioural characteristics. The figure below shows an overview of our supervised classifier: </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7tFXZByKRCYxVaAFDG0Xda/d81e7f09b5d12e03e39c266696df9cc3/BLOG-3046_3.png" />
          </figure><p>While our classification approach is straightforward, a significant challenge is the lack of a reliable, comprehensive, and labeled dataset of CGNAT IPs for our training dataset.</p>
    <div>
      <h3>Detecting CGNAT using public data sources </h3>
      <a href="#detecting-cgnat-using-public-data-sources">
        
      </a>
    </div>
    <p>Detection begins by building an initial dataset of IPs believed to be associated with CGNAT. Cloudflare has vast HTTP and traffic logs. Unfortunately there is no signal or label in any request to indicate what is or is not a CGNAT. </p><p>To build an extensive labelled dataset to train our ML classifier, we employ a combination of network measurement techniques, as described below. We rely on public data sources to help disambiguate an initial set of large-scale shared IP addresses from others in Cloudflare’s logs.   </p>
    <div>
      <h4>Distributed Traceroutes</h4>
      <a href="#distributed-traceroutes">
        
      </a>
    </div>
    <p>The presence of a client behind CGNAT can often be inferred through traceroute analysis. CGNAT requires ISPs to insert a NAT step that typically uses the Shared Address Space (<a href="https://datatracker.ietf.org/doc/html/rfc6598"><u>RFC 6598</u></a>) after the customer premises equipment (CPE). By running a traceroute from the client to its own public IP and examining the hop sequence, the appearance of an address within 100.64.0.0/10 between the first private hop (e.g., 192.168.1.1) and the public IP is a strong indicator of CGNAT.</p><p>Traceroute can also reveal multi-level NAT, which CGNAT requires, as shown in the diagram below. If the ISP assigns the CPE a private <a href="https://datatracker.ietf.org/doc/html/rfc1918"><u>RFC 1918</u></a> address that appears right after the local hop, this indicates at least two NAT layers. While ISPs sometimes use private addresses internally without CGNAT, observing private or shared ranges immediately downstream combined with multiple hops before the public IP strongly suggests CGNAT or equivalent multi-layer NAT.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/57k4gwGCHcPggIWtSy36HU/6cf8173c1a4c568caa25a1344a516e9e/BLOG-3046_4.png" />
          </figure><p>Although traceroute accuracy depends on router configurations, detecting private and shared IP ranges is a reliable way to identify large-scale IP sharing. We apply this method to distributed traceroutes from over 9,000 RIPE Atlas probes to classify hosts as behind CGNAT, single-layer NAT, or no NAT.</p>
    <div>
      <h4>Scraping WHOIS and PTR records</h4>
      <a href="#scraping-whois-and-ptr-records">
        
      </a>
    </div>
    <p>Many operators encode metadata about their IPs in the corresponding reverse DNS pointer (PTR) record that can signal administrative attributes and geographic information. We first query the DNS for PTR records for the full IPv4 space and then filter for a set of known keywords from the responses that indicate a CGNAT deployment. For example, each of the following three records matches a keyword (<code>cgnat</code>, <code>cgn</code> or <code>lsn</code>) used to detect CGNAT address space:</p><p><code>node-lsn.pool-1-0.dynamic.totinternet.net
103-246-52-9.gw1-cgnat.mobile.ufone.nz
cgn.gsw2.as64098.net</code></p><p>WHOIS and Internet Routing Registry (IRR) records may also contain organizational names, remarks, or allocation details that reveal whether a block is used for CGNAT pools or residential assignments. </p><p>Given that both PTR and WHOIS records may be manually maintained and therefore may be stale, we try to sanitize the extracted data by validating the fact that the corresponding ISPs indeed use CGNAT based on customer and market reports. </p>
    <div>
      <h4>Collecting VPN and proxy IPs </h4>
      <a href="#collecting-vpn-and-proxy-ips">
        
      </a>
    </div>
    <p>Compiling a list of VPN and proxy IPs is more straightforward, as we can directly find such IPs in public service directories for anonymizers. We also subscribe to multiple VPN providers, and we collect the IPs allocated to our clients by connecting to a unique HTTP endpoint under our control. </p>
    <div>
      <h2>Modeling CGNAT with machine learning</h2>
      <a href="#modeling-cgnat-with-machine-learning">
        
      </a>
    </div>
    <p>By combining the above techniques, we accumulated a dataset of labeled IPs for more than 200K CGNAT IPs, 180K VPNs &amp; proxies and close to 900K IPs allocated that are not LSS IPs. These were the entry points to modeling with machine learning.</p>
    <div>
      <h3>Feature selection</h3>
      <a href="#feature-selection">
        
      </a>
    </div>
    <p>Our hypothesis was that aggregated activity from CGNAT IPs is distinguishable from activity generated from other non-CGNAT IP addresses. Our feature extraction is an evaluation of that hypothesis — since networks do not disclose CGNAT and other uses of IPs, the quality of our inference is strictly dependent on our confidence in the training data. We claim the key discriminator is diversity, not just volume. For example, VM-hosted scanners may generate high numbers of requests, but with low information diversity. Similarly, globally routable CPEs may have individually unique characteristics, but with volumes that are less likely to be caught at lower sampling rates.</p><p>In our feature extraction, we parse a 1% sampled HTTP requests log for distinguishing features of IPs compiled in our reference set, and the same features for the corresponding /24 prefix (namely IPs with the same first 24 bits in common). We analyse the features for each of the VPNs, proxies, CGNAT, or non LSS IP. We find that features from the following broad categories are key discriminators for the different types of IPs in our training dataset:</p><ul><li><p><b>Client-side signals:</b> We analyze the aggregate properties of clients connecting from an IP. A large, diverse user base (like on a CGNAT) naturally presents a much wider statistical variety of client behaviors and connection parameters than a single-tenant server or a small business proxy.</p></li><li><p><b>Network and transport-level behaviors:</b> We examine traffic at the network and transport layers. The way a large-scale network appliance (like a CGNAT) manages and routes connections often leaves subtle, measurable artifacts in its traffic patterns, such as in port allocation and observed network timing.</p></li><li><p><b>Traffic volume and destination diversity:</b> We also model the volume and "shape" of the traffic. An IP representing thousands of independent users will, on average, generate a higher volume of requests and target a much wider, less correlated set of destinations than an IP representing a single user.</p></li></ul><p>Crucially, to distinguish CGNAT from VPNs and proxies (which is absolutely necessary for calibrated security filtering), we had to aggregate these features at two different scopes: per-IP and per /24 prefixes. CGNAT IPs are typically allocated large blocks of IPs, whereas VPNs IPs are more scattered across different IP prefixes. </p>
    <div>
      <h3>Classification results</h3>
      <a href="#classification-results">
        
      </a>
    </div>
    <p>We compute the above features from HTTP logs over 24-hour intervals to increase data volume and reduce noise due to DHCP IP reallocation. The dataset is split into 70% training and 30% testing sets with disjoint /24 prefixes, and VPN and proxy labels are merged due to their similarity and lower operational importance compared to CGNAT detection.</p><p>Then we train a multi-class <a href="https://xgboost.readthedocs.io/en/stable/"><u>XGBoost</u></a> model with class weighting to address imbalance, assigning each IP to the class with the highest predicted probability. XGBoost is well-suited for this task because it efficiently handles large feature sets, offers strong regularization to prevent overfitting, and delivers high accuracy with limited parameter tuning. The classifier achieves 0.98 accuracy, 0.97 weighted F1, and 0.04 log loss. The figure below shows the confusion matrix of the classification.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/26i81Pe0yjlftHfIDrjB5X/45d001447fc52001a25176c8036a92cb/BLOG-3046_5.png" />
          </figure><p>Our model is accurate for all three labels. The errors observed are mainly misclassifications of VPN/proxy IPs as CGNATs, mostly for VPN/proxy IPs that are within a /24 prefix that is also shared by broadband users outside of the proxy service. We also evaluate the prediction accuracy using <a href="https://scikit-learn.org/stable/modules/cross_validation.html"><u>k-fold cross validation</u></a>, which provides a more reliable estimate of performance by training and validating on multiple data splits, reducing variance and overfitting compared to a single train–test split. We select 10 folds and we evaluate the <a href="https://developers.google.com/machine-learning/crash-course/classification/roc-and-auc"><u>Area Under the ROC Curve</u></a> (AUC) and the multi-class logloss. We achieve a macro-average AUC of 0.9946 (σ=0.0069) and log loss of 0.0429 (σ=0.0115). Prefix-level features are the most important contributors to classification performance.</p>
    <div>
      <h3>Users behind CGNAT are more likely to be rate limited</h3>
      <a href="#users-behind-cgnat-are-more-likely-to-be-rate-limited">
        
      </a>
    </div>
    <p>The figure below shows the daily number of CGNAT IP inferences generated by our CDN-deployed detection service between December 17, 2024 and January 9, 2025. The number of inferences remains largely stable, with noticeable dips during weekends and holidays such as Christmas and New Year’s Day. This pattern reflects expected seasonal variations, as lower traffic volumes during these periods lead to fewer active IP ranges and reduced request activity.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7hiYstptHAK6tFQrM2kEsf/7f8192051156fc6eaecdf26a829ef11c/BLOG-3046_6.png" />
          </figure><p>Next, recall that actions that rely on IP reputation or behaviour may be unduly influenced by CGNATs. One such example is bot detection. In an evaluation of our systems, we find that bot detection is resilient to those biases. However, we also learned that customers are more likely to rate limit IPs that we find are CGNATs.</p><p>We analyze bot labels by analyzing how often requests from CGNAT and non-CGNAT IPs are labeled as bots. <a href="https://www.cloudflare.com/resources/assets/slt3lc6tev37/JYknFdAeCVBBWWgQUtNZr/61844a850c5bba6b647d65e962c31c9c/BDES-863_Bot_Management_re_edit-_How_it_Works_r3.pdf"><u>Cloudflare assigns a bot score</u></a> to each HTTP request using CatBoost models trained on various request features, and these scores are then exposed through the Web Application Firewall (WAF), allowing customers to apply filtering rules. The median bot rate is nearly identical for CGNAT (4.8%) and non-CGNAT (4.7%) IPs. However, the mean bot rate is notably lower for CGNATs (7%) than for non-CGNATs (13.1%), indicating different underlying distributions. Non-CGNAT IPs show a much wider spread, with some reaching 100% bot rates, while CGNAT IPs cluster mostly below 15%. This suggests that non-CGNAT IPs tend to be dominated by either human or bot activity, whereas CGNAT IPs reflect mixed behavior from many end users, with human traffic prevailing.</p><p>Interestingly, despite bot scores that indicate traffic is more likely to be from human users, CGNAT IPs are subject to rate limiting three times more often than non-CGNAT IPs. This is likely because multiple users share the same public IP, increasing the chances that legitimate traffic gets caught by customers’ bot mitigation and firewall rules.</p><p>This tells us that users behind CGNAT IPs are indeed susceptible to collateral effects, and identifying those IPs allows us to tune mitigation strategies to disrupt malicious traffic quickly while reducing collateral impact on benign users behind the same address.</p>
    <div>
      <h2>A global view of the CGNAT ecosystem</h2>
      <a href="#a-global-view-of-the-cgnat-ecosystem">
        
      </a>
    </div>
    <p>One of the early motivations of this work was to understand if our knowledge about IP addresses might hide a bias along socio-economic boundaries—and in particular if an action on an IP address may disproportionately affect populations in developing nations, often referred to as the Global South. Identifying where different IPs exist is a necessary first step.</p><p>The map below shows the fraction of a country’s inferred CGNAT IPs over all IPs observed in the country. Regions with a greater reliance on CGNAT appear darker on the map. This view highlights the geodiversity of CGNATs in terms of importance; for example, much of Africa and Central and Southeast Asia rely on CGNATs. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4P2XcuEebKfcYdCgykMWuP/4a0aa86bd619ba24533de6862175e919/BLOG-3046_7.png" />
          </figure><p>As further evidence of continental differences, the boxplot below shows the distribution of distinct user agents per IP across /24 prefixes inferred to be part of a CGNAT deployment in each continent. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7bqJSHexFuXFs4A8am1ibQ/591be6880e8f58c9d61b147aaf0487f5/BLOG-3046_8.png" />
          </figure><p>Notably, Africa has a much higher ratio of user agents to IP addresses than other regions, suggesting more clients share the same IP in African <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>ASNs</u></a>. So, not only do African ISPs rely more extensively on CGNAT, but the number of clients behind each CGNAT IP is higher. </p><p>While the deployment rate of CGNAT per country is consistent with the users-per-IP ratio per country, it is not sufficient by itself to confirm deployment. The scatterplot below shows the number of users (according to <a href="https://stats.labs.apnic.net/aspop/"><u>APNIC user estimates</u></a>) and the number of IPs per ASN for ASNs where we detect CGNAT. ASNs that have fewer available IP addresses than their user base appear below the diagonal. Interestingly the scatterplot indicates that many ASNs with more addresses than users still choose to deploy CGNAT. Presumably, these ASNs provide additional services beyond broadband, preventing them from dedicating their entire address pool to subscribers. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/34GKPlJWvkwudU5MbOtots/c883760a7c448b12995997e3e6e51979/BLOG-3046_9.png" />
          </figure>
    <div>
      <h3>What this means for everyday Internet users</h3>
      <a href="#what-this-means-for-everyday-internet-users">
        
      </a>
    </div>
    <p>Accurate detection of CGNAT IPs is crucial for minimizing collateral effects in network operations and for ensuring fair and effective application of security measures. Our findings underscore the potential socio-economic and geographical variations in the use of CGNATs, revealing significant disparities in how IP addresses are shared across different regions. </p><p>At Cloudflare we are going beyond just using these insights to evaluate policies and practices. We are using the detection systems to improve our systems across our application security suite of features, and working with customers to understand how they might use these insights to improve the protections they configure.</p><p>Our work is ongoing and we’ll share details as we go. In the meantime, if you’re an ISP or network operator that operates CGNAT and want to help, get in touch at <a href="#"><u>ask-research@cloudflare.com</u></a>. Sharing knowledge and working together helps make better and equitable user experience for subscribers, while preserving web service safety and security.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Web Application Firewall]]></category>
            <category><![CDATA[Better Internet]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[IPv4]]></category>
            <category><![CDATA[Network Services]]></category>
            <guid isPermaLink="false">9cTCNUkDdgVjdBN6M6JLv</guid>
            <dc:creator>Vasilis Giotsas</dc:creator>
            <dc:creator>Marwan Fayed</dc:creator>
        </item>
        <item>
            <title><![CDATA[Block unsafe prompts targeting your LLM endpoints with Firewall for AI]]></title>
            <link>https://blog.cloudflare.com/block-unsafe-llm-prompts-with-firewall-for-ai/</link>
            <pubDate>Tue, 26 Aug 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare's AI security suite now includes unsafe content moderation, integrated into the Application Security Suite via Firewall for AI.  ]]></description>
            <content:encoded><![CDATA[ <p>Security teams are racing to <a href="https://www.cloudflare.com/the-net/vulnerable-llm-ai/"><u>secure a new attack surface</u></a>: AI-powered applications. From chatbots to search assistants, LLMs are already shaping customer experience, but they also open the door to new risks. A single malicious prompt can exfiltrate sensitive data, <a href="https://www.cloudflare.com/learning/ai/data-poisoning/"><u>poison a model</u></a>, or inject toxic content into customer-facing interactions, undermining user trust. Without guardrails, even the best-trained model can be turned against the business.</p><p>Today, as part of AI Week, we’re expanding our <a href="https://www.cloudflare.com/ai-security/">AI security offerings</a> by introducing unsafe content moderation, now integrated directly into Cloudflare <a href="https://developers.cloudflare.com/waf/detections/firewall-for-ai/"><u>Firewall for AI</u></a>. Built with Llama, this new feature allows customers to leverage their existing Firewall for AI engine for unified detection, analytics, and topic enforcement, providing real-time protection for <a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/"><u>Large Language Models (LLMs)</u></a> at the network level. Now with just a few clicks, security and application teams can detect and block harmful prompts or topics at the edge — eliminating the need to modify application code or infrastructure.

This feature is immediately available to current Firewall for AI users. Those not yet onboarded can contact their account team to participate in the beta program.</p>
    <div>
      <h2>AI protection in application security</h2>
      <a href="#ai-protection-in-application-security">
        
      </a>
    </div>
    <p>Cloudflare's Firewall for AI <a href="https://blog.cloudflare.com/best-practices-sase-for-ai/">protects user-facing LLM applications</a> from abuse and data leaks, addressing several of the <a href="https://www.cloudflare.com/learning/ai/owasp-top-10-risks-for-llms/"><u>OWASP Top 10 LLM risks</u></a> such as prompt injection, PII disclosure, and unbound consumption. It also extends protection to other risks such as unsafe or harmful content.</p><p>Unlike built-in controls that vary between model providers, Firewall for AI is model-agnostic. It sits in front of any model you choose, whether it’s from a third party like OpenAI or Gemini, one you run in-house, or a custom model you have built, and applies the same consistent protections.</p><p>Just like our origin-agnostic <a href="https://www.cloudflare.com/application-services/#application-services-case-products"><u>Application Security suite</u></a>, Firewall for AI enforces policies at scale across all your models, creating a unified security layer. That means you can define guardrails once and apply them everywhere. For example, a financial services company might require its LLM to only respond to finance-related questions, while blocking prompts about unrelated or sensitive topics, enforced consistently across every model in use.</p>
    <div>
      <h2>Unsafe content moderation protects businesses and users</h2>
      <a href="#unsafe-content-moderation-protects-businesses-and-users">
        
      </a>
    </div>
    <p>Effective AI moderation is more than blocking “bad words”, it’s about setting boundaries that protect users, meeting legal obligations, and preserving brand integrity, without over-moderating in ways that silence important voices.</p><p>Because LLMs cannot be fully scripted, their interactions are inherently unpredictable. This flexibility enables rich user experiences but also opens the door to abuse.</p><p>Key risks from unsafe prompts include misinformation, biased or offensive content, and model poisoning, where repeated harmful prompts degrade the quality and safety of future outputs. Blocking these prompts aligns with the OWASP Top 10 for LLMs, preventing both immediate misuse and long-term degradation.</p><p>One example of this is<a href="https://www.theverge.com/2016/3/24/11297050/tay-microsoft-chatbot-racist"> <b><u>Microsoft’s Tay chatbot</u></b></a>. Trolls deliberately submitted toxic, racist, and offensive prompts, which Tay quickly began repeating. The failure was not only in Tay’s responses; it was in the lack of moderation on the inputs it accepted.</p>
    <div>
      <h2>Detecting unsafe prompts before reaching the model</h2>
      <a href="#detecting-unsafe-prompts-before-reaching-the-model">
        
      </a>
    </div>
    <p>Cloudflare has integrated <a href="https://huggingface.co/meta-llama/Llama-Guard-3-8B"><u>Llama Guard</u></a> directly into Firewall for AI. This brings AI input moderation into the same rules engine our customers already use to protect their applications. It uses the same approach that we created for developers building with AI in our <a href="https://blog.cloudflare.com/guardrails-in-ai-gateway/"><u>AI Gateway</u></a> product.</p><p>Llama Guard analyzes prompts in real time and flags them across multiple safety categories, including hate, violence, sexual content, criminal planning, self-harm, and more.</p><p>With this integration, Firewall for AI not only <a href="https://blog.cloudflare.com/take-control-of-public-ai-application-security-with-cloudflare-firewall-for-ai/#discovering-llm-powered-applications"><u>discovers LLM traffic</u></a> endpoints automatically, but also enables security and AI teams to take immediate action. Unsafe prompts can be blocked before they reach the model, while flagged content can be logged or reviewed for oversight and tuning. Content safety checks can also be combined with other Application Security protections, such as <a href="https://www.cloudflare.com/application-services/products/bot-management/"><u>Bot Management</u> </a>and <a href="https://www.cloudflare.com/application-services/products/rate-limiting/"><u>Rate Limiting</u></a>, to create layered defenses when protecting your model.</p><p>The result is a single, edge-native policy layer that enforces guardrails before unsafe prompts ever reach your infrastructure — without needing complex integrations.</p>
    <div>
      <h2>How it works under the hood</h2>
      <a href="#how-it-works-under-the-hood">
        
      </a>
    </div>
    <p>Before diving into the architecture of Firewall for AI engine and how it fits within our previously mentioned module to detect <a href="https://blog.cloudflare.com/take-control-of-public-ai-application-security-with-cloudflare-firewall-for-ai/#using-workers-ai-to-deploy-presidio"><u>PII in the prompts</u></a>, let’s start with how we detect unsafe topics.</p>
    <div>
      <h3>Detection of unsafe topics</h3>
      <a href="#detection-of-unsafe-topics">
        
      </a>
    </div>
    <p>A key challenge in building safety guardrails is balancing a good detection with model helpfulness. If detection is too broad, it can prevent a model from answering legitimate user questions, hurting its utility. This is especially difficult for topic detection because of the ambiguity and dynamic nature of human language, where context is fundamental to meaning. </p><p>Simple approaches like keyword blocklists are interesting for precise subjects — but insufficient. They are easily bypassed and fail to understand the context in which words are used, leading to poor recall. Older probabilistic models such as <a href="https://en.wikipedia.org/wiki/Latent_Dirichlet_allocation"><u>Latent Dirichlet Allocation (LDA)</u></a> were an improvement, but did not properly account for word ordering and other contextual nuances. 

Recent advancements in LLMs introduced a new paradigm. Their ability to perform zero-shot or few-shot classification is uniquely suited for the task of topic detection. For this reason, we chose <a href="https://huggingface.co/meta-llama/Llama-Guard-3-8B"><u>Llama Guard 3</u></a>, an open-source model based on the Llama architecture that is specifically fine-tuned for content safety classification. When it analyzes a prompt, it answers whether the text is safe or unsafe, and provides a specific category. We are showing the default categories, as listed <a href="http://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.llm.prompt.unsafe_topic_categories/"><u>here</u></a>. Because Llama 3 has a fixed knowledge cutoff, certain categories — like defamation or elections — are time-sensitive. As a result, the model may not fully capture events or context that emerged after it was trained, and that’s important to keep in mind when relying on it.</p><p>For now, we cover the 13 default categories. We plan to expand coverage in the future, leveraging the model’s zero-shot capabilities.</p>
    <div>
      <h3>A scalable architecture for future detections</h3>
      <a href="#a-scalable-architecture-for-future-detections">
        
      </a>
    </div>
    <p>We designed Firewall for AI to scale without adding noticeable latency, including Llama Guard, and this remains true even as we add new detection models.</p><p>To achieve this, we built a new asynchronous architecture. When a request is sent to an application protected by Firewall for AI, a Cloudflare Worker makes parallel, non-blocking requests to our different detection modules — one for PII, one for unsafe topics, and others as we add them. </p><p>Thanks to the Cloudflare network, this design scales to handle high request volumes out of the box, and latency does not increase as we add new detections. It will only be bounded by the slowest model used. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4Y2gTP6teVR2263UIEWHc9/9a31fb394cee6c437c1d4af6f71d867c/image3.png" />
          </figure><p>We optimize to keep the model utility at its maximum while keeping the guardrail detection broad enough.</p><p>Llama Guard is a rather large model, so running it at scale with minimal latency is a challenge. We deploy it on <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Workers AI</u></a>, leveraging our large fleet of high performance GPUs. This infrastructure ensures we can offer fast, reliable inference throughout our network.</p><p>To ensure the system remains fast and reliable as adoption grows, we ran extensive load tests simulating the requests per second (RPS) we anticipate, using a wide range of prompt sizes to prepare for real-world traffic. To handle this, the number of model instances deployed on our network scales automatically with the load. We employ concurrency to minimize latency and optimize for hardware utilization. We also enforce a hard 2-second threshold for each analysis; if this time limit is reached, we fall back to any detections already completed, ensuring your application's requests latency is never further impacted.</p>
    <div>
      <h3>From detection to security rules enforcement</h3>
      <a href="#from-detection-to-security-rules-enforcement">
        
      </a>
    </div>
    <p>Firewall for AI follows the same familiar pattern as other Application Security features like Bot Management and WAF Attack Score, making it easy to adopt.</p><p>Once enabled, the <a href="https://developers.cloudflare.com/waf/detections/firewall-for-ai/#fields"><u>new fields</u></a> appear in <a href="https://developers.cloudflare.com/waf/analytics/security-analytics/"><u>Security Analytics</u></a> and expanded logs. From there, you can filter by unsafe topics, track trends over time, and drill into the results of individual requests to see all detection outcomes, for example: did we detect unsafe topics, and what are the categories. The request body itself (the prompt text) is not stored or exposed; only the results of the analysis are logged.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/722JxyLvT6DFQxFpQhHMYP/3f1a6aa8ef1dafe4ad1a8277578fd7ae/image2.png" />
          </figure><p>After reviewing the analytics, you can enforce unsafe topic moderation by creating rules to log or block based on prompt categories in <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>Custom rules</u></a>.</p><p>For example, you might log prompts flagged as sexual content or hate speech for review. </p><p>You can use this expression: 
<code>If (any(cf.llm.prompt.unsafe_topic_categories[*] in {"S10" "S12"})) then Log</code>

Or deploy the rule with the categories field in the dashboard as in the below screenshot.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2CUsVjjpCEqv2UQMU6cMmt/5307235338c1b58856c0685585347537/image4.png" />
          </figure><p>You can also take a broader approach by blocking all unsafe prompts outright:
<code>If (cf.llm.prompt.unsafe_topic_detected)then Block</code></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3uRT9YlRlRPsL5bNyBFA3i/54eb171ecb48aaecc7876b972789bf15/image5.png" />
          </figure><p>These rules are applied automatically to all discovered HTTP requests containing prompts, ensuring guardrails are enforced consistently across your AI traffic.</p>
    <div>
      <h2>What’s Next</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>In the coming weeks, Firewall for AI will expand to detect prompt injection and jailbreak attempts. We are also exploring how to add more visibility in the analytics and logs, so teams can better validate detection results. A major part of our roadmap is adding model response handling, giving you control over not only what goes into the LLM but also what comes out. Additional abuse controls, such as rate limiting on tokens and support for more safety categories, are also on the way.</p><p>Firewall for AI is available in beta today. If you’re new to Cloudflare and want to explore how to implement these AI protections, <a href="https://www.cloudflare.com/plans/enterprise/contact/?utm_medium=referral&amp;utm_source=blog&amp;utm_campaign=2025-q3-acq-gbl-connectivity-ge-ge-general-ai_week_blog"><u>reach out for a consultation</u></a>. If you’re already with Cloudflare, contact your account team to get access and start testing with real traffic.</p><p>Cloudflare is also opening up a user research program focused on <a href="https://www.cloudflare.com/learning/ai/what-is-ai-security/">AI security</a>. If you are curious about previews of new functionality or want to help shape our roadmap, <a href="https://www.cloudflare.com/lp/ai-security-user-research-program-2025"><u>express your interest here</u></a>.</p><div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[AI Week]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[LLM]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[AI]]></category>
            <guid isPermaLink="false">59hk6A3nH3YcLMjXhYnNof</guid>
            <dc:creator>Radwa Radwan</dc:creator>
            <dc:creator>Mathias Deschamps</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare protects against critical SharePoint vulnerability, CVE-2025-53770]]></title>
            <link>https://blog.cloudflare.com/cloudflare-protects-against-critical-sharepoint-vulnerability-cve-2025-53770/</link>
            <pubDate>Tue, 22 Jul 2025 16:30:00 GMT</pubDate>
            <description><![CDATA[ Microsoft disclosed two critical vulnerabilities, CVE-2025-53771 and CVE-2025-53770, that are exploited to attack SharePoint servers. ]]></description>
            <content:encoded><![CDATA[ <p>On July 19, 2025,<a href="https://msrc.microsoft.com/blog/2025/07/customer-guidance-for-sharepoint-vulnerability-cve-2025-53770/"> <u>Microsoft disclosed CVE-2025-53770</u></a>, a critical zero-day Remote Code Execution (RCE) vulnerability. Assigned a CVSS 3.1 base score of 9.8 (Critical), the vulnerability affects SharePoint Server 2016, 2019, and the Subscription Edition, along with unsupported 2010 and 2013 versions. Cloudflare’s WAF Managed Rules now includes 2 emergency releases that mitigate these vulnerabilities for WAF customers.</p>
    <div>
      <h3>Unpacking CVE-2025-53770</h3>
      <a href="#unpacking-cve-2025-53770">
        
      </a>
    </div>
    <p>The vulnerability's root cause is <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-53770"><u>improper deserialization of untrusted data</u></a>, which allows a remote, unauthenticated attacker to execute arbitrary code over the network without any user interaction. Moreover, what makes CVE-2025-53770 uniquely threatening is its methodology – the exploit chain, labeled "ToolShell." ToolShell is engineered <i>to play the long-game</i>: attackers are not only gaining temporary access, but also taking the server's cryptographic machine keys, specifically the <code>ValidationKey</code> and <code>DecryptionKey</code>. Possessing these keys allows threat actors to independently forge authentication tokens and <code>__VIEWSTATE</code> payloads, granting them persistent access that can survive standard mitigation strategies such as a server reboot or removing web shells.</p><p>In response to the active nature of these attacks, the U.S. Cybersecurity and Infrastructure Security Agency (CISA) added CVE-2025-53770 to its<a href="https://www.cisa.gov/news-events/alerts/2025/07/20/cisa-adds-one-known-exploited-vulnerability-cve-2025-53770-toolshell-catalog"> <u>Known Exploited Vulnerabilities (KEV) catalog</u></a> with an emergency remediation deadline. The security community's consensus is clear: any organization with an on-premise SharePoint server on the Internet should assume it has been compromised and take immediate action to fully address this vulnerability.</p><p>Since releasing our vulnerability patch in Cloudflare’s WAF Managed Ruleset, we’ve tracked the number of HTTP request matches for the vulnerability, which you can see in the graph below. Notably, we observed a significant peak around 11AM UTC, the morning of July 22, at around 300,000 hits at one point in time. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1lIEI0Bq0Y9KKfejkUo2sB/3e0ae3f0ccfe0d4eec09ef837157323b/image2.png" />
          </figure>
    <div>
      <h3>How does the ToolShell exploit chain work?</h3>
      <a href="#how-does-the-toolshell-exploit-chain-work">
        
      </a>
    </div>
    <p>The ToolShell exploit chain was first demonstrated at the <a href="https://www.zerodayinitiative.com/blog/2025/5/16/pwn2own-berlin-2025-day-two-results"><u>Pwn2Own hacking competition</u></a> in May 2025, where researchers chained an authentication bypass (CVE-2025-49706) with a deserialization RCE (CVE-2025-49704). Unfortunately, this was not the end of ToolShell’s lifespan. Threat actors evidently analyzed the patches to find weaknesses and exploit them in the wild, forcing Microsoft to assign new identifiers and call out CVE-2025-53771 for the authentication bypass. This rapid exploit → patch → bypass cycle shows that threat actors are not merely discovering vulnerabilities, but also systematically reverse-engineering <i>patches</i> to weaponize bypasses. For responders, this closes the window – or hides it altogether – to respond and put up defenses, highlighting the need for evolving, proactive security postures.</p><p>The ToolShell exploit works in 3 stages:</p><ol><li><p><b>Authentication Bypass, leveraging CVE-2025-53771</b>: The attack begins with a <code>POST</code> request sent to the <code>/_layouts/15/ToolPane.aspx</code> endpoint, a legacy component of SharePoint. The crutch of this authentication bypass happens by setting the <code>Referer</code> header to <code>/_layouts/SignOut.aspx</code>, which tricks the SharePoint server into trusting the attacker. With trust in hand, the attacker is able to skip authentication checks and move forward with authenticated access.</p></li><li><p><b>Remote Code Execution via Deserialization, CVE-2025-53770: </b>With privileged access, the attacker can interact with the <code>ToolPane.aspx</code> endpoint. The attacker submits a malicious payload in the body of the <code>POST</code> request, triggering the core vulnerability: a deserialization flaw in which the SharePoint application deserializes the object into executable code on the server. At this point, the attacker can execute commands as they wish.</p></li><li><p><b>The Long-Game: Possessing Cryptographic Keys:</b> Finally, to play the long-game and maintain continued access, the attacker will use a specific web shell to steal the server's cryptographic machine keys. By taking the <code>ValidationKey</code> and the <code>DecryptionKey</code>, the attacker obtains the state information used by SharePoint. Possessing these keys allows the attacker to operate independently, long after the original exploit; this means they can continue to execute new malicious payloads on the exploited server. This permanent backdoor makes this attack method uniquely dangerous.</p></li></ol>
    <div>
      <h3>Cloudflare’s new WAF Managed Rules for CVE-2025-53770, CVE-2025-53771 </h3>
      <a href="#cloudflares-new-waf-managed-rules-for-cve-2025-53770-cve-2025-53771">
        
      </a>
    </div>
    <p>CVE-2025-53770 is a clear example of how modern cyber threats are two-sided, combining an initial breach vector with a mechanism for long-term persistence. This means that a successful defense will address both the immediate RCE vulnerability and the subsequent threat of unwelcome access. </p><p>Once a public proof-of-concept became available for this exploit, Cloudflare’s security analysts crafted and tested new patches, ensuring that they would address not only the initial attack, but also the longer-term threat. </p><p>The team began researching the exploit the evening of July 20, and on July 21, 2025, Cloudflare deployed our emergency WAF Managed Rules to patch the vulnerability, meaning every customer using the Cloudflare Managed Ruleset will automatically be protected from this critical SharePoint vulnerability. These rules have been announced on the <a href="https://developers.cloudflare.com/waf/change-log/2025-07-21-emergency/">WAF changelog</a> and will take effect immediately.</p> ]]></content:encoded>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[CVE]]></category>
            <guid isPermaLink="false">2RtKFdquX8O4ijNDZvLjyd</guid>
            <dc:creator>Jin-Hee Lee</dc:creator>
            <dc:creator>Vaibhav Singhal</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare named a leader in Web Application Firewall Solutions in 2025 Forrester report]]></title>
            <link>https://blog.cloudflare.com/cloudflare-named-leader-waf-forrester-2025/</link>
            <pubDate>Thu, 20 Mar 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Forrester Research has recognized Cloudflare as a Leader in its The Forrester Wave™: Web Application Firewall Solutions, Q1 2025 report. ]]></description>
            <content:encoded><![CDATA[ <p>Forrester Research has recognized Cloudflare as a Leader in its <i>The Forrester Wave™: Web Application Firewall Solutions, Q1 2025</i> report. This market analysis helps security and risk professionals select the right solution for their needs. According to Forrester: </p><blockquote><p><i>“Cloudflare is a strong option for customers that want to manage an easy-to-use, unified web application protection platform that will continue to innovate.”</i></p></blockquote><p>In this evaluation, Forrester assessed 10 Web Application Firewall (WAF) vendors across 22 criteria, including product security and vision. We believe this recognition is due to our continued investment in our product offering. Get a complimentary copy of the report <a href="https://www.cloudflare.com/lp/forrester-wave-waf-2025/"><u>here</u></a>.</p><p>Since introducing our <a href="https://blog.cloudflare.com/heuristics-and-rules-why-we-built-a-new-old-waf/"><u>first WAF</u></a> in 2013, Cloudflare has transformed it into a robust, enterprise-grade Application Security platform. Our fully integrated suite includes WAF, bot mitigation, API security, client-side protection, and DDoS mitigation, all built on our expansive global network. By leveraging AI and machine learning, we deliver industry-leading security while enhancing application performance through our content delivery and optimization solutions.</p><p>According to the Forrester report, <i>“Cloudflare stands out with features that help customers work more efficiently.”</i> Unlike other solutions in the market, Cloudflare’s WAF, API Security, bot detection, client-side security, and DDoS protection are natively <a href="https://blog.cloudflare.com/new-application-security-experience/"><u>integrated within a single platform</u></a>, running on a unified engine. Our integrated solution empowers a seamless user experience and enables advanced threat detection across multiple vectors to meet the most demanding security requirements.</p>
    <div>
      <h3>Cloudflare: a standout in Application Security</h3>
      <a href="#cloudflare-a-standout-in-application-security">
        
      </a>
    </div>
    <p>Forrester’s evaluation of Web Application Firewall solutions is one of the most comprehensive assessments in the industry. We believe this report highlights Cloudflare’s integrated global cloud platform and our ability to deliver enterprise-grade security without added complexity. We don’t just offer a WAF — we provide a flexible, customizable security toolkit designed to address your unique application security challenges.</p><p>Cloudflare continuously leads the WAF market through our strategic vision and the breadth of our capabilities. We center our approach on relentless innovation, delivering industry-leading security features, and ensuring a seamless management experience with enterprise processes and tools such as Infrastructure as Code (IaC) and DevOps. Our predictable cadence of major feature releases, powered by annual initiatives like Security Week and Birthday Week, ensures that customers always have access to the latest security advancements.</p><p>We believe Forrester also highlighted Cloudflare’s extensive security capabilities, with particular recognition of the significant improvements in our API security offerings.</p>
    <div>
      <h3>Cloudflare’s top-ranked criteria</h3>
      <a href="#cloudflares-top-ranked-criteria">
        
      </a>
    </div>
    <p>In the report, Cloudflare received the highest possible scores in 15 out of 22 criteria, reinforcing, in our opinion, our commitment to delivering the most advanced, flexible and easy-to-use web application protection in the industry. Some of the key criteria include:</p><ul><li><p><b>Detection models</b>: Advanced AI and machine learning models that continuously evolve to detect new threats.</p></li><li><p><b>Layer 7 DDoS protection</b>: Industry-leading mitigation of sophisticated application-layer attacks.</p></li><li><p><b>Rule creation and modification:</b> Simple, easy to use rule creation experience, propagating within seconds globally.</p></li><li><p><b>Management UI:</b> An intuitive and efficient user interface that simplifies security management.</p></li><li><p><b>Product security</b>: A robust architecture that ensures enterprise-grade security.</p></li><li><p><b>Infrastructure-as-code support</b>: Seamless integration with DevOps workflows for automated security policy enforcement.</p></li><li><p><b>Innovation</b>: A forward-thinking approach to security, consistently pushing the boundaries of what’s possible.</p></li></ul>
    <div>
      <h3>What sets Cloudflare apart?</h3>
      <a href="#what-sets-cloudflare-apart">
        
      </a>
    </div>
    <p>First, Cloudflare’s WAF goes beyond traditional rule-based protections, offering a comprehensive suite of detection mechanisms to identify attacks and vulnerabilities across web and API traffic while also safeguarding client environments. We leverage AI and machine learning to detect threats such as attacks, automated traffic, anomalies, and compromised JavaScript, among others. Our industry-leading application-layer DDoS protection makes volumetric attacks a thing of the past.</p><p>Second, Cloudflare has also made significant strides in <a href="https://developers.cloudflare.com/api-shield/"><u>API security</u></a>. Our WAF can be supercharged with features such as: API discovery, schema validation &amp; sequence mitigation, volumetric detection, and JWT authentication. </p><p>Third, Cloudflare simplifies security management with an intuitive dashboard that is easy to use while still offering powerful configurations for advanced practitioners. All features are Terraform-supported, allowing teams to manage the entire Cloudflare platform as code. With Security Analytics, customers gain a comprehensive view of all traffic, whether mitigated or not, and can run what-if scenarios to test new rules before deployment. This analytic capability ensures that businesses can dynamically adapt their security posture while maintaining high performance. To make security management even more seamless, our<a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/"> AI agent,</a> powered by Natural Language Processing (NLP), helps users craft and refine custom rules and create powerful visualizations within our analytics engine.</p>
    <div>
      <h3>Cloudflare: the clear choice for modern security</h3>
      <a href="#cloudflare-the-clear-choice-for-modern-security">
        
      </a>
    </div>
    <p>We are confident that Forrester’s report validates what our customers already know: Cloudflare is a leading WAF vendor, offering unmatched security, innovation, and ease of use. As threats continue to evolve, we remain committed to pushing the boundaries of web security to protect organizations worldwide.</p><p>If you’re looking for a powerful, scalable, and easy-to-manage web application firewall, Cloudflare is the best choice for securing your applications, <a href="https://www.cloudflare.com/the-net/api-security/">APIs</a>, and infrastructure.</p>
    <div>
      <h3>Ready to enhance your security?</h3>
      <a href="#ready-to-enhance-your-security">
        
      </a>
    </div>
    <p>Learn more about Cloudflare WAF by <a href="https://dash.cloudflare.com/sign-up"><u>creating an account</u></a> today and see why Forrester has recognized us as a leader in the market. </p><p><i>Forrester does not endorse any company, product, brand, or service included in its research publications and does not advise any person to select the products or services of any company or brand based on the ratings included in such publications. Information is based on the best available resources. Opinions reflect judgment at the time and are subject to change. For more information, read about Forrester’s objectivity </i><a href="https://www.forrester.com/about-us/objectivity/"><i><u>here </u></i></a>.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Web Application Firewall]]></category>
            <category><![CDATA[API Security]]></category>
            <category><![CDATA[Forrester]]></category>
            <guid isPermaLink="false">6oqVUC4QLYuEBImzaJo8eu</guid>
            <dc:creator>Daniele Molteni</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing Cloudy, Cloudflare’s AI agent for simplifying complex configurations]]></title>
            <link>https://blog.cloudflare.com/introducing-ai-agent/</link>
            <pubDate>Thu, 20 Mar 2025 13:10:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare’s first AI agent, Cloudy, helps make complicated configurations easy to understand for Cloudflare administrators. ]]></description>
            <content:encoded><![CDATA[ <p>It’s a big day here at Cloudflare! Not only is it Security Week, but today marks Cloudflare’s first step into a completely new area of functionality, intended to improve how our users both interact with, and get value from, all of our products.</p><p>We’re excited to share a first glance of how we’re embedding <a href="https://www.cloudflare.com/learning/ai/what-is-artificial-intelligence/">AI</a> features into the management of Cloudflare products you know and love. Our first mission? Focus on security and streamline the rule and policy management experience. The goal is to automate away the time-consuming task of manually reviewing and contextualizing Custom Rules in <a href="https://www.cloudflare.com/application-services/products/waf/">Cloudflare WAF</a>, and Gateway policies in Cloudflare One, so you can instantly understand what each policy does, what gaps they have, and what you need to do to fix them.</p>
    <div>
      <h3>Meet Cloudy, Cloudflare’s first AI agent</h3>
      <a href="#meet-cloudy-cloudflares-first-ai-agent">
        
      </a>
    </div>
    <p>Our initial step toward a fully AI-enabled product experience is the introduction of <i>Cloudy</i>, the first version of Cloudflare AI agents, assistant-like functionality designed to help users quickly understand and improve their Cloudflare configurations in multiple areas of the product suite. You’ll start to see Cloudy functionality seamlessly embedded into two Cloudflare products across the dashboard, which we’ll talk about below.</p><p>And while the name <i>Cloudy</i> may be fun and light-hearted, our goals are more serious: Bring Cloudy and AI-powered functionality to every corner of Cloudflare, and optimize how our users operate and manage their favorite Cloudflare products. Let’s start with two places where Cloudy is now live and available to all customers using the WAF and Gateway products.</p>
    <div>
      <h3>WAF Custom Rules</h3>
      <a href="#waf-custom-rules">
        
      </a>
    </div>
    <p>Let’s begin with AI-powered overviews of <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF Custom Rules</u></a>. For those unfamiliar, Cloudflare’s Web Application Firewall (WAF) helps protect web applications from attacks like <a href="https://www.cloudflare.com/learning/security/threats/sql-injection/">SQL injection</a>, <a href="https://www.cloudflare.com/learning/security/threats/cross-site-scripting/">cross-site scripting (XSS)</a>, and other vulnerabilities. </p><p>One specific feature of the WAF is the ability to create WAF Custom Rules. These allow users to tailor security policies to block, challenge, or allow traffic based on specific attributes or security criteria.</p><p>However, for customers with dozens or even hundreds of rules deployed across their organization, it can be challenging to maintain a clear understanding of their security posture. Rule configurations evolve over time, often managed by different team members, leading to potential inefficiencies and security gaps. What better problem for Cloudy to solve?</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4zcFRfhRWGQWhoza9TolDu/25e1357540db32e59150609e6eddd1e0/BLOG-2692_2.png" />
          </figure><p>Powered by <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a>, today we’ll share how Cloudy will help review your WAF Custom Rules and provide a summary of what's configured across them. Cloudy will also help you identify and solve issues such as:</p><ul><li><p><b>Identifying redundant rules</b>: Identify when multiple rules are performing the same function, or using similar fields, helping you streamline your configuration.</p></li><li><p><b>Optimising execution order</b>: Spot cases where rules ordering affects functionality, such as when a terminating rule (block/challenge action) prevents subsequent rules from executing.</p></li><li><p><b>Analysing conflicting rules</b>: Detect when rules counteract each other, such as one rule blocking traffic that another rule is designed to allow or log.</p></li><li><p><b>Identifying disabled rules</b>: Highlight potentially important security rules that are in a disabled state, helping ensure that critical protections are not accidentally left inactive.</p></li></ul><p>Cloudy won't just summarize your rules, either. It will analyze the relationships and interactions between rules to provide actionable recommendations. For security teams managing complex sets of Custom Rules, this means less time spent auditing configurations and more confidence in your security coverage.</p><p>Available to all users, we’re excited to show how Cloudflare AI Agents can enhance the usability of our products, starting with WAF Custom Rules. But this is just the beginning.</p>
    <div>
      <h3>Cloudflare One Firewall policies</h3>
      <a href="#cloudflare-one-firewall-policies">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4CXHQVlO3GGqwp6DGyOklJ/3068c434c4a303cf22c328c302947fcb/BLOG-2692_3.png" />
          </figure><p>We've also added Cloudy to <a href="https://www.cloudflare.com/static/e9ea5dfaa69c554cc1cbaa7f3e441acf/Cloudflare_One_at_a_glance.pdf"><u>Cloudflare One</u></a>, our SASE platform, where enterprises manage the security of their employees and tools from a single dashboard.</p><p>In <a href="https://www.cloudflare.com/zero-trust/products/gateway/"><u>Cloudflare Gateway</u></a>, our Secure Web Gateway offering, customers can configure policies to manage how employees do their jobs on the Internet. These Gateway policies can block access to malicious sites, prevent data loss violations, and control user access, among other things.</p><p>But similar to WAF Custom Rules, Gateway policy configurations can become overcomplicated and bogged down over time, with old, forgotten policies that do who-knows-what. Multiple selectors and operators working in counterintuitive ways. Some blocking traffic, others allowing it. Policies that include several user groups, but carve out specific employees. We’ve even seen policies that block hundreds of URLs in a single step. All to say, managing years of Gateway policies can become overwhelming.</p><p>So, why not have Cloudy summarize Gateway policies in a way that makes their purpose clear and concise?</p><p>Available to all Cloudflare Gateway users (create a free Cloudflare One account <a href="https://www.cloudflare.com/zero-trust/products/"><u>here</u></a>), Cloudy will now provide a quick summary of any Gateway policy you view. It’s now easier than ever to get a clear understanding of each policy at a glance, allowing admins to spot misconfigurations, redundant controls, or other areas for improvement, and move on with confidence.</p>
    <div>
      <h3>Built on Workers AI</h3>
      <a href="#built-on-workers-ai">
        
      </a>
    </div>
    <p>At the heart of our new functionality is <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Cloudflare Workers AI</u></a> (yes, the same version that everyone uses!) that leverages advanced <a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/">large language models (LLMs) </a>to process vast amounts of information; in this case, policy and rules data. Traditionally, manually reviewing and contextualizing complex configurations is a daunting task for any security team. With Workers AI, we automate that process, turning raw configuration data into consistent, clear summaries and actionable recommendations.</p>
    <div>
      <h4><b>How it works</b></h4>
      <a href="#how-it-works">
        
      </a>
    </div>
    <p>Cloudflare Workers AI ingests policy and rule configurations from your Cloudflare setup and combines them with a purpose-built LLM prompt. We leverage the same <a href="https://developers.cloudflare.com/workers-ai/models/"><u>publicly-available LLM models</u></a> that we offer our customers, and then further enrich the prompt with some additional data to provide it with context. For this specific task of analyzing and summarizing policy and rule data, we provided the LLM:</p><ul><li><p><b>Policy &amp; rule data</b>: This is the primary data itself, including the current configuration of policies/rules for Cloudy to summarize and provide suggestions against.</p></li><li><p><b>Documentation on product abilities:</b> We provide the model with additional technical details on the policy/rule configurations that are possible with each product, so that the model knows what kind of recommendations are within its bounds.</p></li><li><p><b>Enriched datasets</b>: Where WAF Custom Rules or CF1 Gateway policies leverage other ‘lists’ (e.g., a WAF rule referencing multiple countries, a Gateway policy leveraging a specific content category), the list item(s) selected must be first translated from an ID to plain-text wording so that the LLM can interpret which policy/rule values are actually being used.</p></li><li><p><b>Output instructions</b>: We specify to the model which format we’d like to receive the output in. In this case, we use JSON for easiest handling.</p></li><li><p><b>Additional clarifications</b>: Lastly, we explicitly instruct the LLM to be sure about its output, valuing that aspect above all else. Doing this helps us ensure that no hallucinations make it to the final output.</p></li></ul><p>By automating the analysis of your WAF Custom Rules and Gateway policies, Cloudflare Workers AI not only saves you time but also enhances security by reducing the risk of human error. You get clear, actionable insights that allow you to streamline your configurations, quickly spot anomalies, and maintain a strong security posture—all without the need for labor-intensive manual reviews.</p>
    <div>
      <h4>What’s next for Cloudy</h4>
      <a href="#whats-next-for-cloudy">
        
      </a>
    </div>
    <p>Beta previews of Cloudy are live for all Cloudflare customers today. But this is just the beginning of what we envision for AI-powered functionality across our entire product suite.</p><p>Throughout the rest of 2025, we plan to roll out additional <a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/">AI agent capabilities</a> across other areas of Cloudflare. These new features won’t just help customers manage security more efficiently, but they’ll also provide intelligent recommendations for optimizing performance, streamlining operations, and enhancing overall user experience.</p><p>We’re excited to hear your thoughts as you get to meet Cloudy and try out these new AI features – send feedback to us at <a href="#"><u>cloudyfeedback@cloudflare.com</u></a>, or post your thoughts on X, LinkedIn, or Mastodon tagged with #SecurityWeek! Your feedback will help shape our roadmap for AI enhancement, and bring our users smarter, more efficient tooling that helps everyone get more secure.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5gGseiyO6pbddpdSVQ5wfJ/ae1d0d5a2f8ec01f571de7a85b655370/BLOG-2692_4.png" />
          </figure>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Workers AI]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[LLM]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Cloudflare Zero Trust]]></category>
            <category><![CDATA[SASE]]></category>
            <category><![CDATA[Secure Web Gateway]]></category>
            <category><![CDATA[Beta]]></category>
            <category><![CDATA[Network Services]]></category>
            <guid isPermaLink="false">7ywSxti5U7fxjKbqmVXpGW</guid>
            <dc:creator>Alex Dunbrack</dc:creator>
            <dc:creator>Harsh Saxena</dc:creator>
        </item>
        <item>
            <title><![CDATA[Making Application Security simple with a new unified dashboard experience]]></title>
            <link>https://blog.cloudflare.com/new-application-security-experience/</link>
            <pubDate>Thu, 20 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ We’re introducing a new Application Security experience in the Cloudflare dashboard, with a reworked UI organized by use cases, making it easier for customers to navigate and secure their accounts. ]]></description>
            <content:encoded><![CDATA[ <p>Over the years, we have framed our Application Security features against market-defined product groupings such as Web Application Firewall (WAF), DDoS Mitigation, Bot Management, API Security (API Shield), Client Side Security (Page Shield), and so forth. This has led to unnecessary artificial separation of what is, under the hood, a well-integrated single platform.</p><p>This separation, which has sometimes guided implementation decisions that have led to different systems being built for the same purpose, makes it harder for our users to adopt our features and implement a simple effective security posture for their environment.</p><p>Today, following user feedback and our drive to constantly innovate and simplify, we are going back to our roots by breaking these artificial product boundaries and revising our dashboard, so it highlights our strengths. The ultimate goal remains: to make it shockingly easy to secure your web assets.</p><p><b>Introducing a new unified Application Security experience.</b></p><p>If you are a Cloudflare Application Security user, log in <a href="http://dash.cloudflare.com/:account/:zone/security"><u>to the dashboard</u></a> today and try out the updated dashboard interface. To make the transition easier, you can toggle between old and new interfaces.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/iyOx4HWAdpFyp0W6nECvi/5f67090ee17c9db87ce2c130f80d493a/image5.png" />
          </figure>
    <div>
      <h2>Security, simplified</h2>
      <a href="#security-simplified">
        
      </a>
    </div>
    <p>Modern applications are built using a variety of technologies. Your app might include a web interface and a mobile version, both powered by an API, each with its own unique security requirements. As these technologies increasingly overlap, traditional security categories like Web, API, client-side, and bot protection start to feel artificial and disconnected when applied to real-world application security.</p><p>Consider scenarios where you want to secure your API endpoints with proper authentication, or prevent vulnerability scanners from probing for weaknesses. These tasks often require switching between multiple dashboards, creating different policies, and managing disjointed configurations. This fragmented approach not only complicates workflows but also increases the risk of overlooking a critical vulnerability. The result? A security posture that is harder to manage and potentially less effective.</p><p>When you zoom out, a pattern emerges. Whether it’s managing bots, securing APIs, or filtering web traffic, these solutions ultimately analyze incoming traffic looking for specific patterns, and the resulting signal is used to perform actions. The primary difference between these tools is the type of signal they generate, such as identifying bots, enforcing authorization, or flagging suspicious requests. </p><p>At Cloudflare, we saw an opportunity to address this complexity by unifying our application security tools into a single platform with one cohesive UI. A unified approach means security practitioners no longer have to navigate multiple interfaces or piece together different security controls. With a single UI, you can configure policies more efficiently, detect threats faster, and maintain consistent protection across all aspects of your application. This simplicity doesn’t just save time, it ensures that your applications remain secure, even as threats evolve.</p><p>At the end of the day, attackers won’t care which product you’re using. But by unifying application security, we ensure they’ll have a much harder time finding a way in.</p>
    <div>
      <h2>Many products, one common approach</h2>
      <a href="#many-products-one-common-approach">
        
      </a>
    </div>
    <p>To redefine the experience across Application Security products, we can start by defining three concepts that commonly apply:</p><ul><li><p>Web traffic (HTTP/S), which can be generalised even further as “data”</p></li><li><p>Signals and detections, which provide intelligence about the traffic. Can be generalised as “metadata”</p></li><li><p>Security rules that let you combine any signal or detection (metadata), to block, challenge or otherwise perform an action on the web traffic (data)</p></li></ul><p>We can diagram the above as follows:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/46XB4bR8DSCZWe7PDQNDLp/4043ff4d123c4b8c5eafe0948c2fdefe/image1.png" />
          </figure><p>Using these concepts, all the product groupings that we offer can be converted to different types of signals or detections. All else remains the same. And if we are able to run and generate our signals on all traffic separately from the rule system, therefore generating all the metadata, we get what we call <a href="https://developers.cloudflare.com/waf/detections/"><b><u>always-on detections</u></b></a>, another vital benefit of a single platform approach. Also note that <a href="https://blog.cloudflare.com/traffic-sequence-which-product-runs-first/"><u>the order</u></a> in which we generate the signals becomes irrelevant.</p><p>In diagram form:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5TgbZHUYCkztCPfpbk8rYQ/d2ec02dddb61b8b708019aade73b9623/image12.png" />
          </figure><p>The benefits are twofold. First, problem spaces (such as account takeover or web attacks) become signal groupings, and therefore metadata that can be queried to answer questions about your environment.</p><p>For example, let’s take our Bot Management signal, the <a href="https://developers.cloudflare.com/bots/concepts/bot-score/"><u>bot score</u></a>, and our <a href="https://developers.cloudflare.com/waf/detections/attack-score/"><u>WAF Attack Score</u></a> signal, the attack score. These already run as always-on detections at Cloudflare. By combining these two signals and filtering your traffic against them, you can gain powerful insights on who is accessing your application<b>*</b>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7xcSJtpZdY8L5svEob6dRW/f779872d453551b8d5ca11845a246fc5/image11.png" />
          </figure><p>Second, as everything is just a signal, the mitigation layer, driven by the optional rules, becomes detection agnostic. By providing the same signals as fields in a unified rule system, writing high level policies becomes a breeze. And as we said earlier, given the detection is <b>always-on </b>and fully separated from the mitigation rule system, exploring the data can be thought of as a powerful rule match preview engine. No need to deploy a rule in LOG mode to see what it matches!</p><p>We can now design a unified user experience that reflects Application Security as a single product.</p><p><sup><b><i>* note:</i></b></sup><sup><i> the example here is simplistic, and the use cases become a lot more powerful once you expand to the full set of potential signals that the platform can generate. Take, for example, our ability to detect file uploads. If you run a job application site, you may want to let crawlers access your site, but you may *</i></sup><sup><b><i>not</i></b></sup><sup><i>* want crawlers to submit applications on behalf of applicants. By combining the bot score signal with the file upload signal, you can ensure that rule is enforced.</i></sup></p>
    <div>
      <h2>Introducing a unified Application Security experience</h2>
      <a href="#introducing-a-unified-application-security-experience">
        
      </a>
    </div>
    <p>As signals are always-on, the user journey can now start from our <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#:~:text=protect%20what%20matters.-,Posture%20overview,-from%20attacks%20to"><u>new overview page</u></a> where we highlight security suggestions based on your traffic profile and configurations. Alternatively, you can jump straight into analytics where you can investigate your traffic using a combination of all available signals.</p><p>When a specific traffic pattern seems malicious, you can jump into the rule system to implement a security policy. As part of our new design, given the simplicity of the navigation, we also took advantage of the opportunity to introduce a <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#:~:text=Discovery%20of%20web%20assets"><u>new web assets page</u></a>, where we highlight discovery and attack surface management details.</p><p>Of course, reaching the final design required multiple iterations and feedback sessions. To best understand the balance of maintaining flexibility in the UI whilst reducing complexity, we focused on customer tasks to be done and documenting their processes while trying to achieve their intended actions in the dashboard. Reducing navigation items and using clear naming was one element, but we quickly learned that the changes needed to support ease of use for tasks across the platform.</p><p>Here is the end result:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2IFfm5Q1D6sfGzqhasl2Pb/e2f078c281a4067f5bb624b0ca37509e/image8.png" />
          </figure><p>To recap, our new dashboard now includes:</p><ul><li><p>One overview page where misconfigurations, risks, and suggestions are aggregated</p></li><li><p>Simplified and redesigned security analytics that surfaces security signals from all Application Security capabilities, so you can easily identify and act on any suspicious activity</p></li><li><p>A new web assets page, where you can manage your attack surfaces, helping improve detection relevance</p></li><li><p>A single Security Rules page that provides a unified interface to manage, prioritise, and customise all mitigation rules in your zone, significantly streamlining your security configuration</p></li><li><p>A new settings page where advanced control is based on security needs, not individual products</p></li></ul><p>Let’s dive into each one.</p>
    <div>
      <h3>Overview</h3>
      <a href="#overview">
        
      </a>
    </div>
    <p>With the unified security approach, the new overview page aggregates and prioritizes security suggestions across all your web assets, helping you <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/"><u>maintain a healthy security posture</u></a>. The suggestions span from detected (ongoing) attacks if there are any, to risks and misconfigurations to further solidify your protection. This becomes the daily starting point to manage your security posture.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/19dZ0olpyIjEjywnd5zRrh/32bd0b872ab3c00f411e5287a8e2b6ae/image6.png" />
          </figure>
    <div>
      <h3>Analytics</h3>
      <a href="#analytics">
        
      </a>
    </div>
    <p>Security Analytics and Events have been redesigned to make it easier to analyze your traffic. Suspicious activity detected by Cloudflare is surfaced at the top of the page, allowing you to easily filter and review related traffic. From the Traffic Analytics Sampled Log view, further below in the page, new workflows enable you to take quick action to craft a custom rule or review related security events in context.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/16cUGVu3gqAD8sm9OaAs6x/2ef0474f3d193d95f062ed33abae2d80/image3.png" />
          </figure>
    <div>
      <h3>Web assets</h3>
      <a href="#web-assets">
        
      </a>
    </div>
    <p>Web assets is a new concept introduced to bridge your business goals with threat detection capabilities. A web asset is any endpoint, file, document, or other related entity that we normally would act on from a security perspective. Within our new web asset page, you will be able to explore all relevant discovered assets by our system.</p><p>With our unified security platform, we are able to rapidly build new <a href="https://blog.cloudflare.com/cloudflare-security-posture-management/#securing-your-web-applications:~:text=Use%2Dcase%20driven%20threat%20detection"><u>use-case driven threat detections</u></a>. For example, to block automated actions across your e-commerce website, you can instruct Cloudflare’s system to block any fraudulent signup attempts, while allowing verified crawlers to index your product pages. This is made possible by labelling your web assets, which, where possible, is automated by Cloudflare, and then using those labels to power threat detections to protect your assets.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/nKFhkuUboScRORcWHgYJR/17d23bb52e532910da6b1cc868bf702e/image9.png" />
          </figure>
    <div>
      <h3>Security rules</h3>
      <a href="#security-rules">
        
      </a>
    </div>
    <p>The unified Security rules interface brings all mitigation rule types — including WAF custom rules, rate limiting rules, API sequence rules, and client side rules — together in one centralized location, eliminating the need to navigate multiple dashboards.</p><p>The new page gives you visibility into how Cloudflare mitigates both incoming traffic and blocks potentially malicious client side resources from loading, making it easier to understand your security posture at a glance. The page allows you to create customised mitigation rules by combining any detection signals, such as Bot Score, Attack Score, or signals from Leaked Credential Checks, enabling precise control over how Cloudflare responds to potential threats.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/63A8aBq9400mKEyHAJGAuk/447447977592218fbaa418b3735754c7/image10.png" />
          </figure>
    <div>
      <h3>Settings</h3>
      <a href="#settings">
        
      </a>
    </div>
    <p>Balancing guidance and flexibility was the key driver for designing the new Settings page. As much as Cloudflare <i>guides</i> you towards the optimal security posture through recommendations and alerts, customers that want the <i>flexibility</i> to proactively adjust these settings can find all of them here.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/pz3N1v2EOCj3V9sKF009F/a106b34e0039bebf6eecdfc5c1244f41/image7.png" />
          </figure>
    <div>
      <h2>Experience it today</h2>
      <a href="#experience-it-today">
        
      </a>
    </div>
    <p>This is the first of many enhancements we plan to make to the Application Security experience in the coming months. To check out the new navigation, log in to the <a href="https://dash.cloudflare.com/"><u>Cloudflare dashboard</u></a>, click on “Security” and choose “Check it out” when you see the message below. You will still have the option of opting out, if you so prefer.</p><div>
  
</div>
<p></p><p>Let us know what you think either by sharing feedback in our <a href="https://community.cloudflare.com/"><u>community forum</u></a> or by providing feedback directly in the dashboard (you will be prompted if you revert to the old design).</p>
    <div>
      <h2>Watch on Cloudflare TV</h2>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[Dashboard]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Bot Management]]></category>
            <guid isPermaLink="false">ktsrG1vJGggZ2JlL4cHxS</guid>
            <dc:creator>Michael Tremante</dc:creator>
            <dc:creator>Pete Thomas</dc:creator>
            <dc:creator>Jessica Tarasoff</dc:creator>
        </item>
        <item>
            <title><![CDATA[Resolving a Mutual TLS session resumption vulnerability]]></title>
            <link>https://blog.cloudflare.com/resolving-a-mutual-tls-session-resumption-vulnerability/</link>
            <pubDate>Fri, 07 Feb 2025 20:13:14 GMT</pubDate>
            <description><![CDATA[ Cloudflare patched a Mutual TLS (mTLS) vulnerability (CVE-2025-23419) reported via its Bug Bounty Program. The flaw in session resumption allowed client certificates to authenticate across different ]]></description>
            <content:encoded><![CDATA[ <p>On January 23, 2025, Cloudflare was notified via its <a href="https://www.cloudflare.com/en-gb/disclosure/"><u>Bug Bounty Program</u></a> of a vulnerability in Cloudflare’s <a href="https://www.cloudflare.com/en-gb/learning/access-management/what-is-mutual-tls/"><u>Mutual TLS</u></a> (mTLS) implementation. </p><p>The vulnerability affected customers who were using mTLS and involved a flaw in our session resumption handling. Cloudflare’s investigation revealed <b>no</b> evidence that the vulnerability was being actively exploited. And tracked as<a href="https://nvd.nist.gov/vuln/detail/CVE-2025-23419"> <u>CVE-2025-23419</u></a>, Cloudflare mitigated the vulnerability within 32 hours after being notified. Customers who were using Cloudflare’s API shield in conjunction with <a href="https://developers.cloudflare.com/waf/custom-rules/"><u>WAF custom rules</u></a> that validated the issuer's Subject Key Identifier (<a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_ski/"><u>SKI</u></a>) were not vulnerable. Access policies such as identity verification, IP address restrictions, and device posture assessments were also not vulnerable.</p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>The bug bounty report detailed that a client with a valid mTLS certificate for one Cloudflare zone could use the same certificate to resume a TLS session with another Cloudflare zone using mTLS, without having to authenticate the certificate with the second zone.</p><p>Cloudflare customers can implement mTLS through Cloudflare <a href="https://developers.cloudflare.com/api-shield/security/mtls/"><u>API Shield</u></a> with Custom Firewall Rules and the <a href="https://developers.cloudflare.com/cloudflare-one/identity/devices/access-integrations/mutual-tls-authentication/"><u>Cloudflare Zero Trust</u></a> product suite. Cloudflare establishes the TLS session with the client and forwards the client certificate to Cloudflare’s Firewall or Zero Trust products, where customer policies are enforced.</p><p>mTLS operates by extending the standard TLS handshake to require authentication from both sides of a connection - the client and the server. In a typical TLS session, a client connects to a server, which presents its <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a>. The client verifies the certificate, and upon successful validation, an encrypted session is established. However, with mTLS, the client also presents its own TLS certificate, which the server verifies before the connection is fully established. Only if both certificates are validated does the session proceed, ensuring bidirectional trust.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2FXDaK0R6cpH4IZwSlCyXk/e8f6764656d2672f9eadf4e60851614f/BLOG-2667_2.png" />
          </figure><p>mTLS is useful for <a href="https://developers.cloudflare.com/api-shield/security/mtls/"><u>securing API communications</u></a>, as it ensures that only legitimate and authenticated clients can interact with backend services. Unlike traditional authentication mechanisms that rely on credentials or <a href="https://www.cloudflare.com/en-gb/learning/access-management/token-based-authentication/"><u>tokens</u></a>, mTLS requires possession of a valid certificate and its corresponding private key.</p><p>To improve TLS connection performance, Cloudflare employs <a href="https://blog.cloudflare.com/tls-session-resumption-full-speed-and-secure/"><u>session resumption</u></a>. Session resumption speeds up the handshake process, reducing both latency and resource consumption. The core idea is that once a client and server have successfully completed a TLS handshake, future handshakes should be streamlined — assuming that fundamental parameters such as the cipher suite or TLS version remain unchanged.</p><p>There are two primary mechanisms for session resumption: session IDs and session tickets. With session IDs, the server stores the session context and associates it with a unique session ID. When a client reconnects and presents this session ID in its ClientHello message, the server checks its cache. If the session is still valid, the handshake is resumed using the cached state.</p><p>Session tickets function in a stateless manner. Instead of storing session data, the server encrypts the session context and sends it to the client as a session ticket. In future connections, the client includes this ticket in its ClientHello, which the server can then decrypt to restore the session, eliminating the need for the server to maintain session state.</p><p>A resumed mTLS session leverages previously established trust, allowing clients to reconnect to a protected application without needing to re-initiate an mTLS handshake.</p>
    <div>
      <h3>The mTLS resumption vulnerability</h3>
      <a href="#the-mtls-resumption-vulnerability">
        
      </a>
    </div>
    <p>In Cloudflare’s mTLS implementation, however, session resumption introduced an unintended behavior.  <a href="https://boringssl.googlesource.com/boringssl"><u>BoringSSL</u></a>, the TLS library that Cloudflare uses, will store the client certificate from the originating, full TLS handshake in the session. Upon resuming that session, the client certificate is not revalidated against the full chain of trust, and the original handshake's verification status is respected. To avoid this situation, BoringSSL provides an API to partition session caches/tickets between different “contexts” defined by the application. Unfortunately, Cloudflare’s use of this API was not correct, which allowed TLS sessions to be resumed when they shouldn’t have been. </p><p>To exploit this vulnerability, the security researcher first set up two zones on Cloudflare and configured them behind Cloudflare’s proxy with mTLS enabled. Once their domains were configured, the researcher authenticated to the first zone using a valid client certificate, allowing Cloudflare to issue a TLS session ticket against that zone. </p><p>The researcher then changed the TLS Server Name Indication (SNI) and HTTP Host header from the first zone (which they had authenticated with) to target the second zone (which they had <i>not</i> authenticated with). The researcher then presented the session ticket when handshaking with the second Cloudflare-protected mTLS zone. This resulted in Cloudflare resuming the session with the second zone and reporting verification status for the cached client certificate as successful,bypassing the mTLS authentication that would normally be required to initiate a session.</p><p>If you were using additional validation methods in your API Shield or Access policies – for example, checking the issuers SKI, identity verification, IP address restrictions, or device posture assessments – these controls continued to function as intended. However, due to the issue with TLS session resumption, the mTLS checks mistakenly returned a passing result without re-evaluating the full certificate chain.</p>
    <div>
      <h2>Remediation and next steps</h2>
      <a href="#remediation-and-next-steps">
        
      </a>
    </div>
    <p>We have disabled TLS session resumption for all customers that have mTLS enabled. As a result, Cloudflare will no longer allow resuming sessions that cache client certificates and their verification status.</p><p>We are exploring ways to bring back the performance improvements from TLS session resumption for mTLS customers.</p>
    <div>
      <h2>Further hardening</h2>
      <a href="#further-hardening">
        
      </a>
    </div>
    <p>Customers can further harden their mTLS configuration and add enhanced logging to detect future issues by using Cloudflare's <a href="https://developers.cloudflare.com/rules/transform/"><u>Transform Rules</u></a>, logging, and firewall features.</p><p>While Cloudflare has mitigated the issue by disabling session resumption for mTLS connections, customers may want to implement additional monitoring at their origin to enforce stricter authentication policies. All customers using mTLS can also enable additional request headers using our <a href="https://developers.cloudflare.com/rules/transform/managed-transforms/reference/#add-tls-client-auth-headers"><u>Managed Transforms</u></a> product. Enabling this feature allows us to pass additional metadata to your origin with the details of the client certificate that was used for the connection.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7eYFaZUrBYTESAZEQHsnHS/8bdb9135ab58648529cb8339c48ebb2b/BLOG-2667_3.png" />
          </figure><p>Enabling this feature allows you to see the following headers where mTLS is being utilized on a request.</p>
            <pre><code>{
  "headers": {
    "Cf-Cert-Issuer-Dn": "CN=Taskstar Root CA,OU=Taskstar\\, Inc.,L=London,ST=London,C=UK",
    "Cf-Cert-Issuer-Dn-Legacy": "/C=UK/ST=London/L=London/OU=Taskstar, Inc./CN=Taskstar Root CA",
    "Cf-Cert-Issuer-Dn-Rfc2253": "CN=Taskstar Root CA,OU=Taskstar\\, Inc.,L=London,ST=London,C=UK",
    "Cf-Cert-Issuer-Serial": "7AB07CC0D10C38A1B554C728F230C7AF0FF12345",
    "Cf-Cert-Issuer-Ski": "A5AC554235DBA6D963B9CDE0185CFAD6E3F55E8F",
    "Cf-Cert-Not-After": "Jul 29 10:26:00 2025 GMT",
    "Cf-Cert-Not-Before": "Jul 29 10:26:00 2024 GMT",
    "Cf-Cert-Presented": "true",
    "Cf-Cert-Revoked": "false",
    "Cf-Cert-Serial": "0A62670673BFBB5C9CA8EB686FA578FA111111B1B",
    "Cf-Cert-Sha1": "64baa4691c061cd7a43b24bccb25545bf28f1111",
    "Cf-Cert-Sha256": "528a65ce428287e91077e4a79ed788015b598deedd53f17099c313e6dfbc87ea",
    "Cf-Cert-Ski": "8249CDB4EE69BEF35B80DA3448CB074B993A12A3",
    "Cf-Cert-Subject-Dn": "CN=MB,OU=Taskstar Admins,O=Taskstar,L=London,ST=Essex,C=UK",
    "Cf-Cert-Subject-Dn-Legacy": "/C=UK/ST=Essex/L=London/O=Taskstar/OU=Taskstar Admins/CN=MB ",
    "Cf-Cert-Subject-Dn-Rfc2253": "CN=MB,OU=Taskstar Admins,O=Taskstar,L=London,ST=London,C=UK",
    "Cf-Cert-Verified": "true",
    "Cf-Client-Cert-Sha256": "083129c545d7311cd5c7a26aabe3b0fc76818495595cea92efe111150fd2da2",
    }
}
</code></pre>
            <p>Enterprise customers can also use our <a href="https://developers.cloudflare.com/logs/"><u>Cloudflare Log</u></a> products to add these headers via the Logs <a href="https://developers.cloudflare.com/logs/reference/custom-fields/"><u>Custom Fields</u></a> feature. For example:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3D864CsepB5U2wM1AWhYVu/ca7d3d1ca144bc4fb7ac7edddfdf5987/BLOG-2667_4.png" />
          </figure><p>This will add the following information to Cloudflare Logs.</p>
            <pre><code>"RequestHeaders": {
    "cf-cert-issuer-ski": "A5AC554235DBA6D963B9CDE0185CFAD6E3F55E8F",
    "cf-cert-sha256": "528a65ce428287e91077e4a79ed788015b598deedd53f17099c313e6dfbc87ea"
  },
</code></pre>
            <p>Customers already logging this information — either at their origin or via Cloudflare Logs — can retroactively check for unexpected certificate hashes or issuers that did not trigger any security policy.</p><p>Users are also able to use this information within their <a href="https://developers.cloudflare.com/learning-paths/application-security/firewall/custom-rules/"><u>WAF custom rules</u></a> to conduct additional checks. For example, checking the <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_ski/"><u>Issuer's SKI</u></a> can provide an extra layer of security.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1YWZe9P1hhYEPJrWH4gpqi/b0a6f3c70a203032404c1ca0e2fc517c/BLOG-2667_5.png" />
          </figure><p>Customers who enabled this <a href="https://developers.cloudflare.com/api-shield/security/mtls/configure/#expression-builder"><u>additional check</u></a> were not vulnerable.</p>
    <div>
      <h2><b>Conclusion</b></h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We would like to thank Sven Hebrok, Felix Cramer, Tim Storm, Maximilian Radoy, and Juraj Somorovsky of Paderborn University who responsibly disclosed this issue via our <a href="https://hackerone.com/cloudflare?type=team"><u>HackerOne Bug Bounty Program</u></a>, allowing us to identify and mitigate the vulnerability. We welcome further submissions from our community of researchers to continually improve our products' security.</p><p>Finally, we want to apologize to our mTLS customers. Security is at the core of everything we do at Cloudflare, and we deeply regret any concerns this issue may have caused. We have taken immediate steps to resolve the vulnerability and have implemented additional safeguards to prevent similar issues in the future. </p>
    <div>
      <h2><b>Timeline </b></h2>
      <a href="#timeline">
        
      </a>
    </div>
    <p><i>All timestamps are in UTC</i></p><ul><li><p><b>2025-01-23 15:40</b> – Cloudflare is notified of a vulnerability in Mutual TLS and the use of session resumption.</p></li><li><p><b>2025-01-23 16:02 to 21:06</b> – Cloudflare validates Mutual TLS vulnerability and prepares a release to disable session resumption for Mutual TLS.</p></li><li><p><b>2025-01-23 21:26</b> – Cloudflare begins rollout of remediation.</p></li><li><p><b>2025-01-24 20:15</b> – Rollout completed. Vulnerability is remediated.</p></li></ul><p></p> ]]></content:encoded>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[SASE]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Network Services]]></category>
            <guid isPermaLink="false">4gJhafUsmUjkevKu55304a</guid>
            <dc:creator>Matt Bullock</dc:creator>
            <dc:creator>Rushil Mehra</dc:creator>
            <dc:creator>Alessandro Ghedini</dc:creator>
        </item>
        <item>
            <title><![CDATA[Advancing Threat Intelligence: JA4 fingerprints and inter-request signals]]></title>
            <link>https://blog.cloudflare.com/ja4-signals/</link>
            <pubDate>Mon, 12 Aug 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[ Explore how Cloudflare's JA4 fingerprinting and inter-request signals provide robust and scalable insights for advanced web security and threat detection.
 ]]></description>
            <content:encoded><![CDATA[ <p>For many years, Cloudflare has used advanced fingerprinting techniques to help block online threats, in products like our <a href="https://blog.cloudflare.com/meet-gatebot-a-bot-that-allows-us-to-sleep"><u>DDoS engine</u></a>, <a href="https://blog.cloudflare.com/patching-the-internet-fixing-the-wordpress-br/"><u>our WAF</u></a>, and <a href="https://www.cloudflare.com/application-services/products/bot-management/"><u>Bot Management</u></a>. For the purposes of Bot Management, fingerprinting characteristic elements of client software help us quickly identify what kind of software is making an HTTP request. It’s an efficient and accurate way to differentiate a browser from a Python script, while preserving user privacy. These fingerprints are used on their own for simple rules, and they underpin complex machine learning models as well. </p><p>Making sure our fingerprints keep pace with the pace of change on the Internet is a constant and critical task. Bots will always adapt to try and look more browser-like. Less frequently, browsers will introduce major changes to their behavior and affect the entire Internet landscape. Last year, Google <a href="https://chromestatus.com/feature/5124606246518784"><u>did exactly that</u></a>, making older TLS fingerprints almost useless for identifying the latest version of Chrome.</p>
    <div>
      <h2>JA3 Fingerprint </h2>
      <a href="#ja3-fingerprint">
        
      </a>
    </div>
    <p>JA3 fingerprint introduced by <a href="https://github.com/salesforce/ja3"><u>Salesforce researchers</u></a> in 2017 and later adopted by Cloudflare, involves creating a hash of the TLS ClientHello message. This hash includes the ordered list of TLS cipher suites, extensions, and other parameters, providing a unique identifier for each client. Cloudflare customers can use JA3 to build detection rules and gain insight into their network traffic.</p><p>In early 2023, Google <a href="https://chromestatus.com/feature/5124606246518784"><u>implemented a change in Chromium-based browsers</u></a> to shuffle the order of TLS extensions – a strategy aimed at disrupting the detection capabilities of JA3 and enhancing the robustness of the TLS ecosystem. This modification was prompted by concerns that fixed fingerprint patterns could lead to rigid server implementations, potentially causing complications each time Chrome updates were rolled out. Over time, JA3 became less useful due to the following reasons:</p><ul><li><p><b>Randomization of TLS extensions:</b> Browsers began randomizing the order of TLS extensions in their ClientHello messages. This change meant that the JA3 fingerprints, which relied on the sequential order of these extensions, would vary with each connection, making it unreliable for identifying unique clients​. (Further information can be found at <a href="https://www.stamus-networks.com/blog/ja3-fingerprints-fade-browsers-embrace-tls-extension-randomization"><u>Stamus Networks</u></a>.)​</p></li><li><p><b>Inconsistencies across tools</b>: Different tools and databases that implemented JA3 fingerprinting often produced varying results due to discrepancies in how they handled TLS extensions and other protocol elements. This inconsistency hindered the effectiveness of JA3 fingerprints for reliable cross-organization sharing and threat intelligence.​ (Further information can be found at <a href="https://fingerprint.com/blog/limitations-ja3-fingerprinting-accurate-device-identification/"><u>Fingerprint</u></a>.)​</p></li><li><p><b>Limited scope and lack of adaptability</b>: JA3 focused solely on elements within the TLS ClientHello packet, covering only a narrow portion of the OSI model’s layers. This limited scope often missed crucial context about a client's environment. Additionally, as newer transport layer protocols like QUIC became popular, JA3’s methodology – originally designed for older client implementations of TLS and not including modern protocols – proved ineffective.</p></li></ul>
    <div>
      <h2>Enter JA4 fingerprint</h2>
      <a href="#enter-ja4-fingerprint">
        
      </a>
    </div>
    <p>In response to these challenges, <a href="https://foxio.io/"><u>FoxIO</u></a> developed JA4, a successor to JA3 that offers a more robust, adaptable, and reliable method for fingerprinting TLS clients across various protocols, including emerging standards like QUIC. Officially launched in September 2023, JA4 is part of the broader <a href="https://blog.foxio.io/ja4%2B-network-fingerprinting"><u>JA4+ suite</u></a> that includes fingerprints for multiple protocols such as TLS, HTTP, and SSH. This suite is designed to be interpretable by both humans and machines, thereby enhancing threat detection and security analysis capabilities.</p><p>JA4 fingerprint is resistant to the randomization of TLS extensions and incorporates additional useful dimensions, such as Application Layer Protocol Negotiation (ALPN), which were not part of JA3. The introduction of JA4 has been met with positive reception in the cybersecurity community, with several open-source tools and commercial products beginning to incorporate it into their systems, including <a href="https://developers.cloudflare.com/bots/concepts/ja3-ja4-fingerprint/"><u>Cloudflare</u></a>. The JA4 fingerprint is available under the <a href="https://github.com/FoxIO-LLC/ja4/blob/main/License%20FAQ.md"><u>BSD 3-Clause license</u></a>, promoting seamless upgrades from JA3. Other fingerprints within the suite, such as JA4S (TLS Server Response) and JA4H (HTTP Client Fingerprinting), are licensed under the proprietary FoxIO License, which is designed for broader use but requires specific arrangements for commercial monetization.</p><p>Let’s take a look at specific JA4 fingerprint example, representing the latest version of Google Chrome on Linux:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7gjWV3tr6fAzSFNq9Z8Xeu/360f0079d987ebc8f8c61f4596b158be/2361-2.png" />
          </figure><ol><li><p><b>Protocol Identifier (t): </b>Indicates the use of TLS over TCP. This identifier is crucial for determining the underlying protocol, distinguishing it from <i>q</i> for QUIC or <i>d</i> for DTLS.</p></li><li><p><b>TLS Version (13): </b>Represents TLS version 1.3, confirming that the client is using one of the latest secure protocols. The version number is derived from analyzing the highest version supported in the ClientHello, excluding any <a href="https://www.rfc-editor.org/rfc/rfc8701.html"><u>GREASE</u></a> values.</p></li><li><p><b>SNI Presence (d): </b>The presence of a domain name in the <a href="https://www.cloudflare.com/en-gb/learning/ssl/what-is-sni/"><u>Server Name Indication</u></a>. This indicates that the client specifies a domain (d), rather than an IP address (i would indicate the absence of SNI).</p></li><li><p><b>Cipher Suites Count (15): </b>Reflects the total number of cipher suites included in the ClientHello, excluding any GREASE values. It provides insight into the cryptographic options the client is willing to use.</p></li><li><p><b>Extensions Count (16): </b>Indicates the count of distinct extensions presented by the client in the ClientHello. This measure helps identify the range of functionalities or customizations the client supports.</p></li><li><p><b>ALPN Values (h2): </b>Represents the Application-Layer Protocol Negotiation protocol, in this case, HTTP/2, which indicates the protocol preferences of the client for optimized web performance.</p></li><li><p><b>Cipher Hash (8daaf6152771): </b>A truncated SHA256 hash of the list of cipher suites, sorted in hexadecimal order. This unique hash serves as a compact identifier for the client’s cipher suite preferences.</p></li><li><p><b>Extension Hash (02713d6af862): </b>A truncated SHA256 hash of the sorted list of extensions combined with the list of signature algorithms. This hash provides a unique identifier that helps differentiate clients based on the extensions and signature algorithms they support.</p></li></ol><p>Here is a <a href="https://www.wireshark.org/"><u>Wireshark</u></a> example of TLS ClientHello from the latest Chrome on Linux querying <a href="https://www.cloudflare.com"><u>https://www.cloudflare.com</u></a>:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3a1jNGnnYTNZbyshIvWhtb/ead13d6dfdcef44a433bdd3f9c72952e/2361-3.png" />
          </figure><p>Integrating JA4 support into Cloudflare required rethinking our approach to parsing TLS ClientHello messages, which were previously handled in separate implementations across C, Lua, and Go. Recognizing the need to boost performance and ensure memory safety, we developed a new Rust-based crate, client-hello-parser. This unified parser not only simplifies modifications by centralizing all related logic but also prepares us for future transitions, such as replacing nginx with an upcoming Rust-based service. Additionally, this streamlined parser facilitates the exposure of JA4 fingerprints across our platform, improving the integration with Cloudflare's firewall rules, Workers, and analytics systems.</p>
    <div>
      <h2>Parsing ClientHello</h2>
      <a href="#parsing-clienthello">
        
      </a>
    </div>
    <p>client-hello-parser is an internal Rust crate designed for parsing TLS ClientHello messages. It aims to simplify the process of analyzing TLS traffic by providing a straightforward way to decode and inspect the initial handshake messages sent by clients when establishing TLS connections. This crate efficiently populates a ClientHelloParsed struct with relevant parsed fields, including version 1 and version 2 fingerprints, and JA3 and JA4 hashes, which are essential for network traffic analysis and fingerprinting.</p><p>Key benefits of the client-hello-parser library include:</p><ul><li><p><b>Optimized memory usage</b>: The library achieves amortized zero heap allocations, verified through extensive testing with the <a href="https://crates.io/crates/dhat"><u>dhat</u></a> crate to track memory allocations. Utilizing the <a href="https://crates.io/crates/tinyvec"><u>tiny_vec</u></a> crate, it begins with stack allocations for small vectors backed by fixed-size arrays, resorting to heap allocations only when these vectors exceed their initial size. This method ensures efficient reuse of all vectors, maintaining amortized zero heap allocations.</p></li><li><p><b>Memory safety:</b> Reinforced by Rust's robust borrow checker and complemented by extensive fuzzing, which has helped identify and resolve potential security vulnerabilities previously undetected in C implementations.</p></li><li><p><b>Ultra-low latency</b>: The parser benefits from using <a href="https://crates.io/crates/faster-hex"><u>faster_hex</u></a> for efficient hex encoding/decoding, which utilizes SIMD instructions to speed up processing. The use of Rust iterators also helps in optimizing performance, often allowing the compiler to generate SIMD-optimized assembly code. This efficiency is further enhanced through the use of BigEndianIterator, which allows for efficient streaming-like processing of TLS ClientHello bytes in a single pass.</p></li></ul><p>Parser benchmark results:</p>
            <pre><code>client_hello_benchmark/parse/parse-short-502
                        time:   [497.15 ns 497.23 ns 497.33 ns]
                        thrpt:  [2.0107 Melem/s 2.0111 Melem/s 2.0115 Melem/s]
client_hello_benchmark/parse/parse-long-1434
                        time:   [992.82 ns 993.55 ns 994.99 ns]
                        thrpt:  [1.0050 Melem/s 1.0065 Melem/s 1.0072 Melem/s]</code></pre>
            <p>
The benchmark results demonstrate that the parser efficiently handles different sizes of ClientHello messages, with shorter messages being processed at a rate of approximately 2 million elements per second, and longer messages at around 1 million elements per second, showcasing the effectiveness of SIMD optimizations and Rust's iterator performance in real-world applications.</p><p><b>Robust testing suite:</b> Includes dozens of real-life TLS ClientHello message examples, with parsed components verified against Wireshark with <a href="https://github.com/fullylegit/ja3"><u>JA3</u></a> and <a href="https://github.com/FoxIO-LLC/ja4/tree/main/wireshark"><u>JA4</u></a> plugins. Additionally, <a href="https://github.com/rust-fuzz/cargo-fuzz"><u>Cargo fuzzer</u></a> with memory sanitizer ensures no memory leaks or edge cases leading to core dumps. Backward compatibility tests with the legacy C parser, imported as a dependency and called via FFI, confirm that both parsers yield equivalent results.</p><p><b>Seamless integration with nginx</b>: The crate, compiled as a dynamic library, is linked to the nginx binary, ensuring a smooth transition from the legacy parser to the new Rust-based parser through backwards compatibility tests.</p><p>The transition to a new Rust-based parser has enabled the retirement of multiple implementations across different languages (C, Lua, and Go), significantly enhancing performance and parser robustness against edge cases. This shift also facilitates the easier integration of new features and business logic for parsing TLS ClientHello messages, streamlining future expansions and security updates.</p><p>With Cloudflare JA4 fingerprints implemented on our network, we were left with another problem to solve. When JA3 was released, we saw some scenarios where customers were surprised by traffic from a new JA3 fingerprint and blocked it, only to find the fingerprint was a new browser release, or an OS update had caused a change in the fingerprint used by their mobile device. By giving customers just a hash, customers still lack context. We wanted to give our customers the necessary context to help them make informed decisions about the safety of a fingerprint, so they can act quickly and confidently on it. As more of our customers embrace AI, we’ve heard more demand from our customers to break out the signals that power our bot detection. These customers want to run complex models on proprietary data that has to stay in their control, but they want to have Cloudflare’s unique perspective on Internet traffic when they do it. To us, both use cases sounded like the same problem. </p>
    <div>
      <h2>Enter JA4 Signals </h2>
      <a href="#enter-ja4-signals">
        
      </a>
    </div>
    <p>In the ever-evolving landscape of web security, traditional fingerprinting techniques like JA3 and JA4 have proven invaluable for identifying and managing web traffic. However, these methods alone are not sufficient to address the sophisticated tactics employed by malicious agents. Fingerprints can be easily spoofed, they change frequently, and traffic patterns and behaviors are constantly evolving. This is where JA4 Signals come into play, providing a robust and comprehensive approach to traffic analysis.</p><p>JA4 Signals are inter-request features computed based on the last hour of all traffic that Cloudflare sees globally. On a daily basis, we analyze over <b>15 million</b> unique JA4 fingerprints generated from more than 500 million user agents and billions of IP addresses. This breadth of data enables JA4 Signals to provide aggregated statistics that offer deeper insights into global traffic patterns – far beyond what single-request or connection fingerprinting can achieve. These signals are crucial for enhancing security measures, whether through simple firewall rules, Workers scripts, or advanced machine learning models.</p><p>Let's consider a specific example of JA4 Signals from a Firewall events activity log, which involves the latest version of Chrome:</p><p>This example highlights that a particular HTTP request received a Bot Score of 95, suggesting it likely originated from a human user operating a browser rather than an automated program or a bot. Analyzing JA4 Signals in this context provides deeper insight into the behavior of this client (latest Linux Chrome) in comparison to other network clients and their respective JA4 fingerprints. Here are a few examples of the signals our customers can see on any request:</p><table><tr><td><p><b><u>JA4 Signal</u></b></p></td><td><p><b><u>Description</u></b></p></td><td><p><b><u>Value example</u></b></p></td><td><p><b><u>Interpretation</u></b></p></td></tr><tr><td><p>browser_ratio_1h</p></td><td><p>The ratio of requests originating from browser-based user agents for the JA4 fingerprint in the last hour. Higher values suggest a higher proportion of browser-based requests.</p></td><td><p>0.942</p></td><td><p>Indicates a 94.2% browser-based request rate for this JA4.</p></td></tr><tr><td><p>cache_ratio_1h</p></td><td><p>The ratio of cacheable responses for the JA4 fingerprint in the last hour. Higher values suggest a higher proportion of responses that can be cached.</p></td><td><p>0.534</p></td><td><p>Shows a 53.4% cacheable response rate for this JA4.</p></td></tr><tr><td><p>h2h3_ratio_1h</p></td><td><p>The ratio of HTTP/2 and HTTP/3 requests combined with the total number of requests for the JA4 fingerprint in the last hour. Higher values indicate a higher proportion of HTTP/2 and HTTP/3 requests compared to other protocol versions.</p></td><td><p>0.987</p></td><td><p>Reflects a 98.7% rate of HTTP/2 and HTTP/3 requests.</p></td></tr><tr><td><p>reqs_quantile_1h</p></td><td><p>The quantile position of the JA4 fingerprint based on the number of requests across all fingerprints in the last hour. Higher values indicate a relatively higher number of requests compared to other fingerprints.</p></td><td><p>1</p></td><td><p>High volume of requests compared to other JA4s.</p></td></tr></table><p>The JA4 fingerprint and JA4 Signals are now available in the Firewall Rules UI, Bot Analytics and Workers. Customers can now use these fields to write custom rules, rate-limiting rules, transform rules, or Workers logic using JA4 fingerprint and JA4 Signals. </p><p>Let's demonstrate how to use JA4 Signals with the following Worker example. This script processes incoming requests by parsing and categorizing JA4 Signals, providing a clear structure for further analysis or rule application within Cloudflare Workers:</p>
            <pre><code>/**
 * Event listener for 'fetch' events. This triggers on every request to the worker.
 */
addEventListener('fetch', event =&gt; {
  event.respondWith(handleRequest(event.request))
})

/**
 * Main handler for incoming requests.
 * @param {Request} request - The incoming request object from the fetch event.
 * @returns {Response} A response object with JA4 Signals in JSON format.
 */
async function handleRequest(request) {
  // Safely access the ja4Signals object using optional chaining, which prevents errors if properties are undefined.
  const ja4Signals = request.cf?.botManagement?.ja4Signals || {};

  // Construct the response content, including both the original ja4Signals and the parsed signals.
  const responseContent = {
    ja4Signals: ja4Signals,
    jaSignalsParsed: parseJA4Signals(ja4Signals)
  };

  // Return a JSON response with appropriate headers.
  return new Response(JSON.stringify(responseContent), {
    status: 200,
    headers: {
      "content-type": "application/json;charset=UTF-8"
    }
  })
}

/**
 * Parses the JA4 Signals into categorized groups based on their names.
 * @param {Object} ja4Signals - The JA4 Signals object that may contain various metrics.
 * @returns {Object} An object with categorized JA4 Signals: ratios, ranks, and quantiles.
 */
function parseJA4Signals(ja4Signals) {
  // Define the keys for each category of signals.
  const ratios = ['h2h3_ratio_1h', 'heuristic_ratio_1h', 'browser_ratio_1h', 'cache_ratio_1h'];
  const ranks = ['uas_rank_1h', 'paths_rank_1h', 'reqs_rank_1h', 'ips_rank_1h'];
  const quantiles = ['reqs_quantile_1h', 'ips_quantile_1h'];

  // Return an object with each category containing only the signals that are present.
  return {
    ratios: filterKeys(ja4Signals, ratios),
    ranks: filterKeys(ja4Signals, ranks),
    quantiles: filterKeys(ja4Signals, quantiles)
  };
}

/**
 * Filters the keys in the ja4Signals object that match the list of specified keys and are not undefined.
 * @param {Object} ja4Signals - The JA4 Signals object.
 * @param {Array&lt;string&gt;} keys - An array of keys to filter from the ja4Signals object.
 * @returns {Object} A filtered object containing only the specified keys that are present in ja4Signals.
 */
function filterKeys(ja4Signals, keys) {
  const filtered = {};
  // Iterate over the specified keys and add them to the filtered object if they exist in ja4Signals.
  keys.forEach(key =&gt; {
    // Check if the key exists and is not undefined to handle optional presence of each signal.
    if (ja4Signals &amp;&amp; ja4Signals[key] !== undefined) {
      filtered[key] = ja4Signals[key];
    }
  });
  return filtered;
}</code></pre>
            
    <div>
      <h2><b>Benefits of JA4 Signals</b></h2>
      <a href="#benefits-of-ja4-signals">
        
      </a>
    </div>
    <ul><li><p><b>Comprehensive traffic analysis</b>: JA4 Signals aggregate data over an hour to provide a holistic view of traffic patterns. This method enhances the ability to identify emerging threats and abnormal behaviors by analyzing changes over time rather than in isolation.</p></li><li><p><b>Precision in anomaly detection</b>: Leveraging detailed inter-request features, JA4 Signals enable the precise detection of anomalies that may be overlooked by single-request fingerprinting. This leads to more accurate identification of sophisticated cyber threats.</p></li><li><p><b>Globally scalable insights</b>: By synthesizing data at a global scale, JA4 Signals harness the strength of Cloudflare’s network intelligence. This extensive analysis makes the system less susceptible to manipulation and provides a resilient foundation for security protocols.</p></li><li><p><b>Dynamic security enforcement</b>: JA4 Signals can dynamically inform security rules, from simple firewall configurations to complex machine learning algorithms. This adaptability ensures that security measures evolve in tandem with changing traffic patterns and emerging threats.</p></li><li><p><b>Reduction in false positives and negatives</b>: With the detailed insights provided by JA4 Signals, security systems can distinguish between legitimate and malicious traffic more effectively, reducing the occurrence of false positives and negatives and improving overall system reliability.</p></li></ul>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>The introduction of JA4 fingerprint and JA4 Signals marks a significant milestone in advancing Cloudflare’s security offerings, including Bot Management and <a href="https://www.cloudflare.com/ddos/"><u>DDoS protection</u></a>. These tools not only enhance the robustness of our traffic analysis but also showcase the continuous evolution of our network fingerprinting techniques. The efficiency of computing JA4 fingerprints enables real-time detection and response to emerging threats. Similarly, by leveraging aggregated statistics and inter-request features, JA4 Signals provide deep insights into traffic patterns at speeds measured in microseconds, ensuring that no detail is too small to be captured and analyzed.</p><p>These security features are underpinned by the scalable techniques and open-sourced libraries outlined in <a href="https://blog.cloudflare.com/scalable-machine-learning-at-cloudflare"><u>"Every request, every microsecond: scalable machine learning at Cloudflare"</u></a>. This discussion highlights how Cloudflare's innovations not only analyze vast amounts of data but also transform this analysis into actionable, reliable, and dynamically adaptable security measures.</p><p>Any Enterprise business with a bot problem will benefit from Cloudflare’s unique JA4 implementation and our perspective on bot traffic, but customers who run their own internal threat models will also benefit from access to data insights from a network that processes over 50 million requests per second. Please <a href="https://www.cloudflare.com/plans/enterprise/contact/"><u>get in touch</u></a> with us to learn more about our Bot Management offering.</p> ]]></content:encoded>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Threat Intelligence]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Application Services]]></category>
            <guid isPermaLink="false">4sRriOEqIpi6j3IvpnSB6B</guid>
            <dc:creator>Alex Bocharov</dc:creator>
            <dc:creator>Adam Martinetti</dc:creator>
        </item>
        <item>
            <title><![CDATA[Making WAF ML models go brrr: saving decades of processing time]]></title>
            <link>https://blog.cloudflare.com/making-waf-ai-models-go-brr/</link>
            <pubDate>Thu, 25 Jul 2024 13:00:46 GMT</pubDate>
            <description><![CDATA[ In this post, we discuss performance optimizations we've implemented for our WAF ML product. We'll guide you through code examples, benchmarks, and we'll share the impressive latency reduction numbers ]]></description>
            <content:encoded><![CDATA[ <p>We made our WAF Machine Learning models <b>5.5x</b> faster, reducing execution time by approximately <b>82%</b>, from <b>1519</b> to <b>275</b> microseconds! Read on to find out how we achieved this remarkable improvement.</p><p><a href="https://developers.cloudflare.com/waf/about/waf-attack-score/">WAF Attack Score</a> is Cloudflare's machine learning (ML)-powered layer built on top of our <a href="https://developers.cloudflare.com/waf/">Web Application Firewall (WAF)</a>. Its goal is to complement the WAF and detect attack bypasses that we haven't encountered before. This has proven invaluable in <a href="/detecting-zero-days-before-zero-day">catching zero-day vulnerabilities</a>, like the one detected in <a href="/how-cloudflares-ai-waf-proactively-detected-ivanti-connect-secure-critical-zero-day-vulnerability">Ivanti Connect Secure</a>, before they are publicly disclosed and enhancing our customers' protection against emerging and unknown threats.</p><p>Since its <a href="/waf-ml">launch in 2022</a>, WAF attack score adoption has grown exponentially, now protecting millions of Internet properties and running real-time inference on tens of millions of requests per second. The feature's popularity has driven us to seek performance improvements, enabling even broader customer use and enhancing Internet security.</p><p>In this post, we will discuss the performance optimizations we've implemented for our WAF ML product. We'll guide you through specific code examples and benchmark numbers, demonstrating how these enhancements have significantly improved our system's efficiency. Additionally, we'll share the impressive latency reduction numbers observed after the rollout.</p><p>Before diving into the optimizations, let's take a moment to review the inner workings of the WAF Attack Score, which powers our WAF ML product.</p>
    <div>
      <h2>WAF Attack Score system design</h2>
      <a href="#waf-attack-score-system-design">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Bis9LE38A3aK4k7HEn7k9/44ae7b31096471a5256961715f8c7991/unnamed--4--6.png" />
            
            </figure><p>Cloudflare's WAF attack score identifies various traffic types and attack vectors (<a href="https://www.cloudflare.com/learning/security/threats/how-to-prevent-sql-injection/">SQLi</a>, <a href="https://www.cloudflare.com/learning/security/how-to-prevent-xss-attacks/">XSS</a>, Command Injection, etc.) based on structural or statistical content properties. Here's how it works during inference:</p><ol><li><p><b>HTTP Request Content</b>: Start with raw HTTP input.</p></li><li><p><b>Normalization &amp; Transformation</b>: Standardize and clean the data, applying normalization, content substitutions, and de-duplication.</p></li><li><p><b>Feature Extraction</b>: Tokenize the transformed content to generate statistical and structural data.</p></li><li><p><b>Machine Learning Model Inference</b>: Analyze the extracted features with pre-trained models, mapping content representations to classes (e.g., XSS, SQLi or <a href="https://www.cloudflare.com/learning/security/what-is-remote-code-execution/">RCE</a>) or scores.</p></li><li><p><b>Classification Output in WAF</b>: Assign a score to the input, ranging from 1 (likely malicious) to 99 (likely clean), guiding security actions.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ZzHRYXU27VYB5F3F3QjXf/9e5248610a1e89ac8c73a446925abb69/cfce15fb-ce84-4489-a05a-6872b9e502b8.png" />
            
            </figure><p>Next, we will explore feature extraction and inference optimizations.</p>
    <div>
      <h2>Feature extraction optimizations</h2>
      <a href="#feature-extraction-optimizations">
        
      </a>
    </div>
    <p>In the context of the WAF Attack Score ML model, feature extraction or pre-processing is essentially a process of tokenizing the given input and producing a float tensor of 1 x m size:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7DIxHJ5zLkdeknndiNGbk0/e802888a2212ddfcae688f1c4201587f/8cc41311-3a09-4c39-b47c-9dc449760ee2.png" />
            
            </figure><p>In our initial pre-processing implementation, this is achieved via a sliding window of 3 bytes over the input with the help of Rust’s <a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html">std::collections::HashMap</a> to look up the tensor index for a given ngram.</p>
    <div>
      <h3>Initial benchmarks</h3>
      <a href="#initial-benchmarks">
        
      </a>
    </div>
    <p>To establish performance baselines, we've set up four benchmark cases representing example inputs of various lengths, ranging from 44 to 9482 bytes. Each case exemplifies typical input sizes, including those for a request body, user agent, and URI. We run benchmarks using the <a href="https://bheisler.github.io/criterion.rs/book/getting_started.html">Criterion.rs</a> statistics-driven micro-benchmarking tool:</p>
            <pre><code>RUSTFLAGS="-C opt-level=3 -C target-cpu=native" cargo criterion</code></pre>
            <p>Here are initial numbers for these benchmarks executed on a Linux laptop with a 13th Gen Intel® Core™ i7-13800H processor:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Pre-processing time, μs</span></th>
    <th><span>Throughput, MiB/s</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>36.40</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td><span>33.83</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>28.94</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>30.24</span></td>
  </tr>
</tbody></table><p>An important observation from these results is that pre-processing time correlates with the length of the input string, with throughput ranging from 28 MiB/s to 36 MiB/s. This suggests that considerable time is spent iterating over longer input strings. Optimizing this part of the process could significantly enhance performance. The dependency of processing time on input size highlights a key area for performance optimization. To validate this, we should examine where the processing time is spent by analyzing flamegraphs created from a 100-second profiling session visualized using <a href="https://www.honeycomb.io/blog/golang-observability-using-the-new-pprof-web-ui-to-debug-memory-usage">pprof</a>:</p>
            <pre><code>RUSTFLAGS="-C opt-level=3 -C target-cpu=native" cargo criterion -- --profile-time 100
 
go tool pprof -http=: target/criterion/profile/preprocessing/avg-body-1000/profile.pb</code></pre>
            
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/WGhFT3j6vn4QGFOmdyNGO/8dd1c6e4d171cd2c407af7bf4d9a9ac7/unnamed--5--6.png" />
            
            </figure><p>Looking at the pre-processing flamegraph above, it's clear that most of the time was spent on the following two operations:</p>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>std::collections::hash::map::HashMap&lt;K,V,S&gt;::get</span></td>
    <td><span>61.8%</span></td>
  </tr>
  <tr>
    <td><span>regex::regex::bytes::Regex::replace_all</span></td>
    <td><span>18.5%</span></td>
  </tr>
</tbody></table><p>Let's tackle the HashMap lookups first. Lookups are happening inside the <i>tensor_populate_ngrams</i> function, where input is split into windows of 3 bytes representing ngram and then lookup inside two hash maps:</p>
            <pre><code>fn tensor_populate_ngrams(tensor: &amp;mut [f32], input: &amp;[u8]) {   
   // Populate the NORM ngrams
   let mut unknown_norm_ngrams = 0;
   let norm_offset = 1;
 
   for s in input.windows(3) {
       match NORM_VOCAB.get(s) {
           Some(pos) =&gt; {
               tensor[*pos as usize + norm_offset] += 1.0f32;
           }
           None =&gt; {
               unknown_norm_ngrams += 1;
           }
       };
   }
 
   // Populate the SIG ngrams
   let mut unknown_sig_ngrams = 0;
   let sig_offset = norm_offset + NORM_VOCAB.len();
 
   let res = SIG_REGEX.replace_all(&amp;input, b"#");
 
   for s in res.windows(3) {
       match SIG_VOCAB.get(s) {
           Some(pos) =&gt; {
               // adding +1 here as the first position will be the unknown_sig_ngrams
               tensor[*pos as usize + sig_offset + 1] += 1.0f32;
           }
           None =&gt; {
               unknown_sig_ngrams += 1;
           }
       }
   }
}</code></pre>
            <p>So essentially the pre-processing function performs a ton of hash map lookups, the volume of which depends on the size of the input string, e.g. 1469 lookups for the given benchmark case <i>avg-body-1000</i>.</p>
    <div>
      <h3>Optimization attempt #1: HashMap → Aho-Corasick</h3>
      <a href="#optimization-attempt-1-hashmap-aho-corasick">
        
      </a>
    </div>
    <p>Rust hash maps are generally quite fast. However, when that many lookups are being performed, it's not very cache friendly.</p><p>So can we do better than hash maps, and what should we try first? The answer is the <a href="https://docs.rs/aho-corasick/latest/aho_corasick/">Aho-Corasick library</a>.</p><p>This library provides multiple pattern search principally through an implementation of the <a href="https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm">Aho-Corasick algorithm</a>, which builds a fast finite state machine for executing searches in linear time.</p><p>We can also tune Aho-Corasick settings based on this recommendation:</p><blockquote><p><i>“You might want to use</i> <a href="https://docs.rs/aho-corasick/1.1.3/aho_corasick/struct.AhoCorasickBuilder.html#method.kind"><i>AhoCorasickBuilder::kind</i></a> <i>to set your searcher to always use</i> <a href="https://docs.rs/aho-corasick/1.1.3/aho_corasick/enum.AhoCorasickKind.html#variant.DFA"><i>AhoCorasickKind::DFA</i></a> <i>if search speed is critical and memory usage isn’t a concern.”</i></p></blockquote>
            <pre><code>static ref NORM_VOCAB_AC: AhoCorasick = AhoCorasick::builder().kind(Some(AhoCorasickKind::DFA)).build(&amp;[    
    "abc",
    "def",
    "wuq",
    "ijf",
    "iru",
    "piw",
    "mjw",
    "isn",
    "od ",
    "pro",
    ...
]).unwrap();</code></pre>
            <p>Then we use the constructed AhoCorasick dictionary to lookup ngrams using its <a href="https://docs.rs/aho-corasick/latest/aho_corasick/struct.AhoCorasick.html#method.find_overlapping_iter">find_overlapping_iter</a> method:</p>
            <pre><code>for mat in NORM_VOCAB_AC.find_overlapping_iter(&amp;input) {
    tensor_input_data[mat.pattern().as_usize() + 1] += 1.0;
}</code></pre>
            <p>We ran benchmarks and compared them against the baseline times shown above:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Aho-Corasick time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>129.59</span></td>
    <td><span>-47.84% or 1.64x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td>	<span>16.47</span></td>
    <td><span>-41.56% or 1.71x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>1.01</span></td>
    <td><span>-30.38% or 1.44x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>1.90</span></td>
    <td><span>-33.60% or 1.51x</span></td>
  </tr>
</tbody></table><p>That's substantially better – Aho-Corasick DFA does wonders.</p>
    <div>
      <h3>Optimization attempt #2: Aho-Corasick → match</h3>
      <a href="#optimization-attempt-2-aho-corasick-match">
        
      </a>
    </div>
    <p>One would think optimization with Aho-Corasick DFA is enough and that it seems unlikely that anything else can beat it. Yet, we can throw Aho-Corasick away and simply use the Rust match statement and let the compiler do the optimization for us!</p>
            <pre><code>#[inline]
const fn norm_vocab_lookup(ngram: &amp;[u8; 3]) -&gt; usize {     
    match ngram {
        b"abc" =&gt; 1,
        b"def" =&gt; 2,
        b"wuq" =&gt; 3,
        b"ijf" =&gt; 4,
        b"iru" =&gt; 5,
        b"piw" =&gt; 6,
        b"mjw" =&gt; 7,
        b"isn" =&gt; 8,
        b"od " =&gt; 9,
        b"pro" =&gt; 10,
        ...
        _ =&gt; 0,
    }
}```</code></pre>
            <p>Here's how it performs in practice, based on the assembly generated by the <a href="https://godbolt.org/z/dqTq5n5Y3">Godbolt compiler explorer</a>. The corresponding assembly code efficiently implements this lookup by employing a jump table and byte-wise comparisons to determine the return value based on input sequences, optimizing for quick decisions and minimal branching. Although the example only includes ten ngrams, it's important to note that in applications like our WAF Attack Score ML models, we deal with thousands of ngrams. This simple match-based approach outshines both HashMap lookups and the Aho-Corasick method.</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Match time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td>	<span>112.96</span></td>
    <td><span>-54.54% or 2.20x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td>	<span>13.12</span></td>
    <td><span>-53.45% or 2.15x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>0.75</span></td>
    <td><span>-48.37% or 1.94x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>1.4076</span></td>
    <td><span>-50.91% or 2.04x</span></td>
  </tr>
</tbody></table><p>Switching to match gave us another 7-18% drop in latency, depending on the case.</p>
    <div>
      <h3>Optimization attempt #3: Regex → WindowedReplacer</h3>
      <a href="#optimization-attempt-3-regex-windowedreplacer">
        
      </a>
    </div>
    <p>So, what exactly is the purpose of <i>Regex::replace_all</i> in pre-processing? Regex is defined and used like this:</p>
            <pre><code>pub static SIG_REGEX: Lazy&lt;Regex&gt; =
    Lazy::new(|| RegexBuilder::new("[a-z]+").unicode(false).build().unwrap());
    ... 
    let res = SIG_REGEX.replace_all(&amp;input, b"#");
    for s in res.windows(3) {
        tensor[sig_vocab_lookup(s.try_into().unwrap())] += 1.0;
    }</code></pre>
            <p>Essentially, all we need is to:</p><ol><li><p>Replace every sequence of lowercase letters in the input with a single byte "#".</p></li><li><p>Iterate over replaced bytes in a windowed fashion with a step of 3 bytes representing an ngram.</p></li><li><p>Look up the ngram index and increment it in the tensor.</p></li></ol><p>This logic seems simple enough that we could implement it more efficiently with a single pass over the input and without any allocations:</p>
            <pre><code>type Window = [u8; 3];
type Iter&lt;'a&gt; = Peekable&lt;std::slice::Iter&lt;'a, u8&gt;&gt;;

pub struct WindowedReplacer&lt;'a&gt; {
    window: Window,
    input_iter: Iter&lt;'a&gt;,
}

#[inline]
fn is_replaceable(byte: u8) -&gt; bool {
    matches!(byte, b'a'..=b'z')
}

#[inline]
fn next_byte(iter: &amp;mut Iter) -&gt; Option&lt;u8&gt; {
    let byte = iter.next().copied()?;
    if is_replaceable(byte) {
        while iter.next_if(|b| is_replaceable(**b)).is_some() {}
        Some(b'#')
    } else {
        Some(byte)
    }
}

impl&lt;'a&gt; WindowedReplacer&lt;'a&gt; {
    pub fn new(input: &amp;'a [u8]) -&gt; Option&lt;Self&gt; {
        let mut window: Window = Default::default();
        let mut iter = input.iter().peekable();
        for byte in window.iter_mut().skip(1) {
            *byte = next_byte(&amp;mut iter)?;
        }
        Some(WindowedReplacer {
            window,
            input_iter: iter,
        })
    }
}

impl&lt;'a&gt; Iterator for WindowedReplacer&lt;'a&gt; {
    type Item = Window;

    #[inline]
    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt; {
        for i in 0..2 {
            self.window[i] = self.window[i + 1];
        }
        let byte = next_byte(&amp;mut self.input_iter)?;
        self.window[2] = byte;
        Some(self.window)
    }
}</code></pre>
            <p>By utilizing the <i>WindowedReplacer</i>, we simplify the replacement logic:</p>
            <pre><code>if let Some(replacer) = WindowedReplacer::new(&amp;input) {                
    for ngram in replacer.windows(3) {
        tensor[sig_vocab_lookup(ngram.try_into().unwrap())] += 1.0;
    }
}</code></pre>
            <p>This new approach not only eliminates the need for allocating additional buffers to store replaced content, but also leverages Rust's iterator optimizations, which the compiler can more effectively optimize. You can view an example of the assembly output for this new iterator at the provided <a href="https://godbolt.org/z/fjaoP7z6Y">Godbolt link</a>.</p><p>Now let's benchmark this and compare against the original implementation:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Match time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td>	<span>51.00</span></td>
    <td><span>-79.47% or 4.87x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td>	<span>5.53</span></td>
    <td><span>-80.36% or 5.09x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>0.40</span></td>
    <td><span>-72.11% or 3.59x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>0.69</span></td>
    <td><span>-76.07% or 4.18x</span></td>
  </tr>
</tbody></table><p>The new letters replacement implementation has doubled the preprocessing speed compared to the previously optimized version using match statements, and it is four to five times faster than the original version!</p>
    <div>
      <h3>Optimization attempt #4: Going nuclear with branchless ngram lookups</h3>
      <a href="#optimization-attempt-4-going-nuclear-with-branchless-ngram-lookups">
        
      </a>
    </div>
    <p>At this point, 4-5x improvement might seem like a lot and there is no point pursuing any further optimizations. After all, using an ngram lookup with a match statement has beaten the following methods, with benchmarks omitted for brevity:</p>
<table><thead>
  <tr>
    <th><span>Lookup method</span></th>
    <th><span>Description</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html"><span>std::collections::HashMap</span></a></td>
    <td><span>Uses </span><a href="https://github.com/rust-lang/hashbrown"><span>Google’s SwissTable</span></a><span> design with SIMD lookups to scan multiple hash entries in parallel. </span></td>
  </tr>
  <tr>
    <td><a href="https://docs.rs/aho-corasick/latest/aho_corasick/#"><span>Aho-Corasick</span></a><span> matcher with and without </span><a href="https://docs.rs/aho-corasick/latest/aho_corasick/dfa/struct.DFA.html"><span>DFA</span></a></td>
    <td><span>Also utilizes SIMD instructions in some cases.</span></td>
  </tr>
  <tr>
    <td><a href="https://crates.io/crates/phf"><span>phf crate</span></a><span> </span></td>
    <td><span>A library to generate efficient lookup tables at compile time using </span><a href="https://en.wikipedia.org/wiki/Perfect_hash_function"><span>perfect hash functions</span></a><span>.</span></td>
  </tr>
  <tr>
    <td><a href="https://crates.io/crates/ph"><span>ph crate</span></a></td>
    <td><span>Another Rust library of data structures based on perfect hashing. </span></td>
  </tr>
  <tr>
    <td><a href="https://crates.io/crates/quickphf"><span>quickphf crate</span></a></td>
    <td><span>A Rust crate that allows you to use static compile-time generated hash maps and hash sets using </span><a href="https://arxiv.org/abs/2104.10402"><span>PTHash perfect hash functions</span></a><span>.</span></td>
  </tr>
</tbody></table><p>However, if we look again at <a href="https://godbolt.org/z/dqTq5n5Y3">the assembly of the norm_vocab_lookup function</a>, it is clear that the execution flow has to perform a bunch of comparisons using <i>cmp</i> instructions. This creates many branches for the CPU to handle, which can lead to branch mispredictions. Branch mispredictions occur when the CPU incorrectly guesses the path of execution, causing delays as it discards partially completed instructions and fetches the correct ones. By reducing or eliminating these branches, we can avoid these mispredictions and improve the efficiency of the lookup process. How can we get rid of those branches when there is a need to look up thousands of unique ngrams?</p><p>Since there are only 3 bytes in each ngram, we can build two lookup tables of 256 x 256 x 256 size, storing the ngram tensor index. With this naive approach, our memory requirements will be: 256 x 256 x 256 x 2 x 2 = 64 MB, which seems like a lot.</p><p>However, given that we only care about ASCII bytes 0..127, then memory requirements can be lower: 128 x 128 x 128 x 2 x 2 = 8 MB, which is better. However, we will need to check for bytes &gt;= 128, which will introduce a branch again.</p><p>So can we do better? Considering that the actual number of distinct byte values used in the ngrams is significantly less than the total possible 256 values, we can reduce memory requirements further by employing the following technique:</p><p>1. To avoid the branching caused by comparisons, we use precomputed offset lookup tables. This means instead of comparing each byte of the ngram during each lookup, we precompute the positions of each possible byte in a lookup table. This way, we replace the comparison operations with direct memory accesses, which are much faster and do not involve branching. We build an ngram bytes offsets lookup const array, storing each unique ngram byte offset position multiplied by the number of unique ngram bytes:</p>
            <pre><code>const NGRAM_OFFSETS: [[u32; 256]; 3] = [
    [
        // offsets of first byte in ngram
    ],
    [
        // offsets of second byte in ngram
    ],
    [
        // offsets of third byte in ngram
    ],
];</code></pre>
            <p>2. Then to obtain the ngram index, we can use this simple const function:</p>
            <pre><code>#[inline]
const fn ngram_index(ngram: [u8; 3]) -&gt; usize {
    (NGRAM_OFFSETS[0][ngram[0] as usize]
        + NGRAM_OFFSETS[1][ngram[1] as usize]
        + NGRAM_OFFSETS[2][ngram[2] as usize]) as usize
}</code></pre>
            <p>3. To look up the tensor index based on the ngram index, we construct another const array at compile time using a list of all ngrams, where N is the number of unique ngram bytes:</p>
            <pre><code>const NGRAM_TENSOR_IDX: [u16; N * N * N] = {
    let mut arr = [0; N * N * N];
    arr[ngram_index(*b"abc")] = 1;
    arr[ngram_index(*b"def")] = 2;
    arr[ngram_index(*b"wuq")] = 3;
    arr[ngram_index(*b"ijf")] = 4;
    arr[ngram_index(*b"iru")] = 5;
    arr[ngram_index(*b"piw")] = 6;
    arr[ngram_index(*b"mjw")] = 7;
    arr[ngram_index(*b"isn")] = 8;
    arr[ngram_index(*b"od ")] = 9;
    ...
    arr
};</code></pre>
            <p>4. Finally, to update the tensor based on given ngram, we lookup the ngram index, then the tensor index, and then increment it with help of <a href="https://doc.rust-lang.org/std/primitive.slice.html#method.get_unchecked_mut">get_unchecked_mut</a>, which avoids unnecessary (in this case) boundary checks and eliminates another source of branching:</p>
            <pre><code>#[inline]
fn update_tensor_with_ngram(tensor: &amp;mut [f32], ngram: [u8; 3]) {
    let ngram_idx = ngram_index(ngram);
    debug_assert!(ngram_idx &lt; NGRAM_TENSOR_IDX.len());
    unsafe {
        let tensor_idx = *NGRAM_TENSOR_IDX.get_unchecked(ngram_idx) as usize;
        debug_assert!(tensor_idx &lt; tensor.len());
        *tensor.get_unchecked_mut(tensor_idx) += 1.0;
    }
}</code></pre>
            <p>This logic works effectively, passes correctness tests, and most importantly, it's completely branchless! Moreover, the memory footprint of used lookup arrays is tiny – just ~500 KiB of memory – which easily fits into modern CPU L2/L3 caches, ensuring that expensive cache misses are rare and performance is optimal.</p><p>The last trick we will employ is loop unrolling for ngrams processing. By taking 6 ngrams (corresponding to 8 bytes of the input array) at a time, the compiler can unroll the second loop and auto-vectorize it, leveraging parallel execution to improve performance:</p>
            <pre><code>const CHUNK_SIZE: usize = 6;

let chunks_max_offset =
    ((input.len().saturating_sub(2)) / CHUNK_SIZE) * CHUNK_SIZE;
for i in (0..chunks_max_offset).step_by(CHUNK_SIZE) {
    for ngram in input[i..i + CHUNK_SIZE + 2].windows(3) {
        update_tensor_with_ngram(tensor, ngram.try_into().unwrap());
    }
}</code></pre>
            <p>Tying up everything together, our final pre-processing benchmarks show the following:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Branchless time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>21.53</span></td>
    <td><span>-91.33% or 11.54x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td><span>2.33</span></td>
    <td><span>-91.73% or 12.09x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td>	<span>0.26</span></td>
    <td><span>-82.34% or 5.66x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td>	<span>0.43</span></td>
    <td><span>-84.92% or 6.63x</span></td>
  </tr>
</tbody></table><p>The longer input is, the higher the latency drop will be due to branchless ngram lookups and loop unrolling, ranging from <b>six to twelve times faster</b> than baseline implementation.</p><p>After trying various optimizations, the final version of pre-processing retains optimization attempts 3 and 4, using branchless ngram lookup with offset tables and a single-pass non-allocating replacement iterator.</p><p>There are potentially more CPU cycles left on the table, and techniques like memory pre-fetching and manual SIMD intrinsics could speed this up a bit further. However, let's now switch gears into looking at inference latency a bit closer.</p>
    <div>
      <h2>Model inference optimizations</h2>
      <a href="#model-inference-optimizations">
        
      </a>
    </div>
    
    <div>
      <h3>Initial benchmarks</h3>
      <a href="#initial-benchmarks">
        
      </a>
    </div>
    <p>Let’s have a look at original performance numbers of the WAF Attack Score ML model, which uses <a href="https://github.com/tensorflow/tensorflow/releases/tag/v2.6.0">TensorFlow Lite 2.6.0</a>:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Inference time, μs</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>inference/long-body-9482</span></td>
    <td><span>247.31</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-url-44</span></td>
    <td><span>246.40</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-ua-91</span></td>
    <td><span>246.88</span></td>
  </tr>
</tbody></table><p>Model inference is actually independent of the original input length, as inputs are transformed into tensors of predetermined size during the pre-processing phase, which we optimized above. From now on, we will refer to a singular inference time when benchmarking our optimizations.</p><p>Digging deeper with profiler, we observed that most of the time is spent on the following operations:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3uy64gatRk8PfdnpRz5Xm5/0d3da469c30e5941524289c1b13574c5/unnamed--6--6.png" />
            
            </figure>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>tflite::tensor_utils::PortableMatrixBatchVectorMultiplyAccumulate</span></td>
    <td><span>42.46%</span></td>
  </tr>
  <tr>
    <td><span>tflite::tensor_utils::PortableAsymmetricQuantizeFloats</span></td>
    <td><span>30.59%</span></td>
  </tr>
  <tr>
    <td><span>tflite::optimized_ops::SoftmaxImpl</span></td>
    <td><span>12.02%</span></td>
  </tr>
  <tr>
    <td><span>tflite::reference_ops::MaximumMinimumBroadcastSlow</span></td>
    <td><span>5.35%</span></td>
  </tr>
  <tr>
    <td><span>tflite::ops::builtin::elementwise::LogEval</span></td>
    <td><span>4.13%</span></td>
  </tr>
</tbody></table><p>The most expensive operation is matrix multiplication, which boils down to iteration within <a href="https://github.com/tensorflow/tensorflow/blob/v2.6.0/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc#L119-L136">three nested loops</a>:</p>
            <pre><code>void PortableMatrixBatchVectorMultiplyAccumulate(const float* matrix,
                                                 int m_rows, int m_cols,
                                                 const float* vector,
                                                 int n_batch, float* result) {
  float* result_in_batch = result;
  for (int b = 0; b &lt; n_batch; b++) {
    const float* matrix_ptr = matrix;
    for (int r = 0; r &lt; m_rows; r++) {
      float dot_prod = 0.0f;
      const float* vector_in_batch = vector + b * m_cols;
      for (int c = 0; c &lt; m_cols; c++) {
        dot_prod += *matrix_ptr++ * *vector_in_batch++;
      }
      *result_in_batch += dot_prod;
     ++result_in_batch;
    }
  }
}</code></pre>
            <p>This doesn’t look very efficient and many <a href="https://en.algorithmica.org/hpc/algorithms/matmul/">blogs</a> and <a href="https://www.cs.utexas.edu/~flame/pubs/GotoTOMS_revision.pdf">research papers</a> have been written on how matrix multiplication can be optimized, which basically boils down to:</p><ul><li><p><b>Blocking</b>: Divide matrices into smaller blocks that fit into the cache, improving cache reuse and reducing memory access latency.</p></li><li><p><b>Vectorization</b>: Use SIMD instructions to process multiple data points in parallel, enhancing efficiency with vector registers.</p></li><li><p><b>Loop Unrolling</b>: Reduce loop control overhead and increase parallelism by executing multiple loop iterations simultaneously.</p></li></ul><p>To gain a better understanding of how these techniques work, we recommend watching this video, which brilliantly depicts the process of matrix multiplication:</p>
<p></p>
    <div>
      <h3>Tensorflow Lite with AVX2</h3>
      <a href="#tensorflow-lite-with-avx2">
        
      </a>
    </div>
    <p>TensorFlow Lite does, in fact, support SIMD matrix multiplication – we just need to enable it and re-compile the TensorFlow Lite library:</p>
            <pre><code>if [[ "$(uname -m)" == x86_64* ]]; then
    # On x86_64 target x86-64-v3 CPU to enable AVX2 and FMA.
    arguments+=("--copt=-march=x86-64-v3")
fi</code></pre>
            <p>After running profiler again using the SIMD-optimized TensorFlow Lite library:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6NmJhJoYG42ZZhU41m0Uj5/1d9fce45d44f98b41375d6a56f1a7cac/unnamed--7--5.png" />
            
            </figure><p>Top operations as per profiler output:</p>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>tflite::tensor_utils::SseMatrixBatchVectorMultiplyAccumulateImpl</span></td>
    <td><span>43.01%</span></td>
  </tr>
  <tr>
    <td><span>tflite::tensor_utils::NeonAsymmetricQuantizeFloats</span></td>
    <td><span>22.46%</span></td>
  </tr>
  <tr>
    <td><span>tflite::reference_ops::MaximumMinimumBroadcastSlow</span></td>
    <td><span>7.82%</span></td>
  </tr>
  <tr>
    <td><span>tflite::optimized_ops::SoftmaxImpl</span></td>
    <td><span>6.61%</span></td>
  </tr>
  <tr>
    <td><span>tflite::ops::builtin::elementwise::LogEval</span></td>
    <td><span>4.63%</span></td>
  </tr>
</tbody></table><p>Matrix multiplication now uses <a href="https://github.com/tensorflow/tensorflow/blob/15ec568b5505727c940b651aeb2a9643b504086c/tensorflow/lite/kernels/internal/optimized/sse_tensor_utils.cc#L161-L199">AVX2 instructions</a>, which uses blocks of 8x8 to multiply and accumulate the multiplication result.</p><p>Proportionally, matrix multiplication and <a href="https://www.cloudflare.com/learning/ai/what-is-quantization/">quantization</a> operations take a similar time share when compared to non-SIMD version, however in absolute numbers, it’s almost twice as fast when SIMD optimizations are enabled:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>SIMD time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
    <td><span>130.07</span></td>
    <td><span>-47.19% or 1.89x</span></td>
  </tr>
</tbody></table><p>Quite a nice performance boost just from a few lines of build config change!</p>
    <div>
      <h3>Tensorflow Lite with XNNPACK</h3>
      <a href="#tensorflow-lite-with-xnnpack">
        
      </a>
    </div>
    <p>Tensorflow Lite comes with a useful benchmarking tool called <a href="https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/benchmark">benchmark_model</a>, which also has a built-in profiler.</p><p>The tool can be built locally using the command:</p>
            <pre><code>bazel build -j 4 --copt=-march=native -c opt tensorflow/lite/tools/benchmark:benchmark_model</code></pre>
            <p>After building, benchmarks were run with different settings:</p>
<table><thead>
  <tr>
    <th><span>Benchmark run</span></th>
    <th><span>Inference time, μs</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=false</span></td>
    <td><span>105.61</span></td>
  </tr>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=true --xnnpack_force_fp16=true</span></td>
    <td><span>111.95</span></td>
  </tr>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=true</span></td>
    <td><span>49.05</span></td>
  </tr>
</tbody></table><p>Tensorflow Lite with XNNPACK enabled emerges as a leader, achieving ~50% latency reduction, when compared to the original Tensorflow Lite implementation.</p><p>More technical details about XNNPACK can be found in these blog posts:</p><ul><li><p><a href="https://blog.tensorflow.org/2022/06/Profiling-XNNPACK-with-TFLite.html">Profiling XNNPACK with TFLite</a></p></li><li><p><a href="https://blog.tensorflow.org/2024/04/faster-dynamically-quantized-inference-with-xnnpack.html">Faster Dynamically Quantized Inference with XNNPack</a></p></li></ul><p>Re-running benchmarks with XNNPack enabled, we get the following results:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span><br /><span>TFLite 2.6.0</span></th>
    <th><span>SIMD time, μs</span><br /><span>TFLite 2.6.0</span></th>
    <th><span>SIMD time, μs</span><br /><span>TFLite 2.16.1</span></th>
    <th><span>SIMD + XNNPack time, μs</span><br /><span>TFLite 2.16.1</span></th>
    <th><span>Optimization</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
    <td><span>130.07</span></td>
    <td><span>115.17</span></td>
    <td><span>56.22</span></td>
    <td><span>-77.17% or 4.38x</span></td>
  </tr>
</tbody></table><p>By upgrading TensorFlow Lite from 2.6.0 to 2.16.1 and enabling SIMD optimizations along with the XNNPack, we were able to decrease WAF ML model inference time more than <b>four-fold</b>, achieving a <b>77.17%</b> reduction.</p>
    <div>
      <h2>Caching inference result</h2>
      <a href="#caching-inference-result">
        
      </a>
    </div>
    <p>While making code faster through pre-processing and inference optimizations is great, it's even better when code doesn't need to run at all. This is where caching comes in. <a href="https://en.wikipedia.org/wiki/Amdahl%27s_law">Amdahl's Law</a> suggests that optimizing only parts of a program has diminishing returns. By avoiding redundant executions with caching, we can achieve significant performance gains beyond the limitations of traditional code optimization.</p><p>A simple key-value cache would quickly occupy all available memory on the server due to the high cardinality of URLs, HTTP headers, and HTTP bodies. However, because "everything on the Internet has an L-shape" or more specifically, follows a <a href="https://en.wikipedia.org/wiki/Zipf%27s_law">Zipf's law</a> distribution, we can optimize our caching strategy.</p><p><a href="https://en.wikipedia.org/wiki/Zipf%27s_law">Zipf</a>'<a href="https://en.wikipedia.org/wiki/Zipf%27s_law">s law</a> states that in many natural datasets, the frequency of any item is inversely proportional to its rank in the frequency table. In other words, a few items are extremely common, while the majority are rare. By analyzing our request data, we found that URLs, HTTP headers, and even HTTP bodies follow this distribution. For example, here is the user agent header frequency distribution against its rank:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/50OWcB7Buza1Jp77ePY75X/e25e66e7665fccc454df026e5ca37729/unnamed--8--3.png" />
            
            </figure><p>By caching the top-N most frequently occurring inputs and their corresponding inference results, we can ensure that both pre-processing and inference are skipped for the majority of requests. This is where the <a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU">Least Recently Used (LRU)</a> cache comes in – frequently used items stay hot in the cache, while the least recently used ones are evicted.</p><p>We use <a href="https://github.com/openresty/lua-resty-lrucache">lua-resty-mlcache</a> as our caching solution, allowing us to share cached inference results between different Nginx workers via a shared memory dictionary. The LRU cache effectively exploits the <a href="https://en.wikipedia.org/wiki/Space%E2%80%93time_tradeoff">space-time trade-off</a>, where we trade a small amount of memory for significant CPU time savings.</p><p>This approach enables us to achieve a <b>~70%</b> cache hit ratio, significantly reducing latency further, as we will analyze in the final section below.</p>
    <div>
      <h2>Optimization results</h2>
      <a href="#optimization-results">
        
      </a>
    </div>
    <p>The optimizations discussed in this post were rolled out in several phases to ensure system correctness and stability.</p><p>First, we enabled SIMD optimizations for TensorFlow Lite, which reduced WAF ML total execution time by approximately <b>41.80%,</b> decreasing from <b>1519</b> ➔ <b>884 μs</b> on average.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/15SMdamloYpjyUy5ZwH9o0/ab4ec787f870d27a45ff513db1f696c8/unnamed--9--3.png" />
            
            </figure><p>Next, we upgraded TensorFlow Lite from version 2.6.0 to 2.16.1, enabled XNNPack, and implemented pre-processing optimizations. This further reduced WAF ML total execution time by <b>~40.77%</b>, bringing it down from <b>932</b> ➔ <b>552 μs</b> on average. The initial average time of 932 μs was slightly higher than the previous 884 μs due to the increased number of customers using this feature and the months that passed between changes.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/01EuBB1eVopVjUjWsVvwrK/0d908285bd4296d75f5c98918cf1a561/unnamed--10--3.png" />
            
            </figure><p>Lastly, we introduced LRU caching, which led to an additional reduction in WAF ML total execution time by <b>~50.18%</b>, from <b>552</b> ➔ <b>275 μs</b> on average.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6epSwp5jz4ZMaVfdwahZnN/8c23c1b6a90bf301f9e7f6566d4f3295/unnamed--11--3.png" />
            
            </figure><p>Overall, we cut WAF ML execution time by <b>~81.90%</b>, decreasing from <b>1519</b> ➔ <b>275 μs</b>, or <b>5.5x</b> faster!</p><p>To illustrate the significance of this: with Cloudflare’s average rate of 9.5 million requests per second passing through WAF ML, saving <b>1244 microseconds</b> per request equates to saving ~<b>32 years</b> of processing time every single day! That’s in addition to the savings of <b>523 microseconds</b> per request or <b>65 years</b> of processing time per day demonstrated last year in our <a href="/scalable-machine-learning-at-cloudflare">Every request, every microsecond: scalable machine learning at Cloudflare</a> post about our Bot Management product.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We hope you enjoyed reading about how we made our WAF ML models go brrr, just as much as we enjoyed implementing these optimizations to bring scalable WAF ML to more customers on a truly global scale.</p><p>Looking ahead, we are developing even more sophisticated ML security models. These advancements aim to bring our <a href="https://www.cloudflare.com/application-services/products/waf/">WAF</a> and <a href="https://www.cloudflare.com/application-services/products/bot-management/">Bot Management</a> products to the next level, making them even more useful and effective for our customers.</p> ]]></content:encoded>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Optimization]]></category>
            <category><![CDATA[Rust]]></category>
            <category><![CDATA[AI WAF]]></category>
            <category><![CDATA[WAF Attack Score]]></category>
            <guid isPermaLink="false">6y0Im81Uj2lKntznfYHfUY</guid>
            <dc:creator>Alex Bocharov</dc:creator>
        </item>
        <item>
            <title><![CDATA[Application Security report: 2024 update]]></title>
            <link>https://blog.cloudflare.com/application-security-report-2024-update/</link>
            <pubDate>Thu, 11 Jul 2024 17:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare’s updated 2024 view on Internet cyber security trends spanning global traffic insights, bot traffic insights, API traffic insights, and client-side risks ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/QISWKhi85GFq3Aqcj9NSX/a983a69c4df14e83712ecc0beb71117a/AD_4nXftYZ9tWp6nRYAEltNHH2LVZZDWKRMZn4Y8oTwdLKuFY-wcPHiULhXzJouGXdjVVDpCeR9T63J_cCxqSzKoq4QsgeXVxQ7MmkL5GS0muw5jhWFRr1fhfpVoH314" />
            
            </figure><p>Over the last twelve months, the Internet security landscape has changed dramatically. Geopolitical uncertainty, coupled with an active 2024 voting season in many countries across the world, has led to a substantial increase in malicious traffic activity across the Internet. In this report, we take a look at Cloudflare’s perspective on Internet application security.</p><p>This report is the fourth edition of our Application Security Report and is an official update to our <a href="/application-security-report-q2-2023">Q2 2023 report</a>. New in this report is a section focused on client-side security within the context of web applications.</p><p>Throughout the report we discuss various insights. From a global standpoint, mitigated traffic across the whole network now averages 7%, and WAF and Bot mitigations are the source of over half of that. While DDoS attacks remain the number one attack vector used against web applications, targeted CVE attacks are also worth keeping an eye on, as we have seen exploits as fast as 22 minutes after a proof of concept was released.</p><p>Focusing on bots, about a third of all traffic we observe is automated, and of that, the vast majority (93%) is not generated by bots in Cloudflare’s verified list and is potentially malicious.</p><p>API traffic is also still growing, now accounting for 60% of all traffic, and maybe more concerning, is that organizations have up to a quarter of their API endpoints not accounted for.</p><p>We also touch on client side security and the proliferation of third-party integrations in web applications. On average, enterprise sites integrate 47 third-party endpoints according to Page Shield data.</p><p>It is also worth mentioning that since the last report, our network, from which we gather the data and insights, is bigger and faster: we are now processing an average of 57 million HTTP requests/second (<b>+23.9%</b> YoY) and 77 million at peak (<b>+22.2%</b> YoY). From a DNS perspective, we are handling 35 million DNS queries per second (<b>+40%</b> YoY). This is the sum of authoritative and resolver requests served by our infrastructure.</p><p>Maybe even more noteworthy, is that, focusing on HTTP requests only, in Q1 2024 Cloudflare blocked an average of 209 billion cyber threats each day (<b>+86.6%</b> YoY). That is a substantial increase in relative terms compared to the same time last year.</p><p>As usual, before we dive in, we need to define our terms.</p>
    <div>
      <h2>Definitions</h2>
      <a href="#definitions">
        
      </a>
    </div>
    <p>Throughout this report, we will refer to the following terms:</p><ul><li><p><b>Mitigated traffic:</b> any eyeball HTTP* request that had a “terminating” action applied to it by the Cloudflare platform. These include the following actions: <code>BLOCK</code>, <a href="https://developers.cloudflare.com/fundamentals/get-started/concepts/cloudflare-challenges/#legacy-captcha-challenge"><code>CHALLENGE</code></a>, <a href="https://developers.cloudflare.com/fundamentals/get-started/concepts/cloudflare-challenges/#js-challenge"><code>JS_CHALLENGE</code></a> and <a href="https://developers.cloudflare.com/fundamentals/get-started/concepts/cloudflare-challenges/#managed-challenge-recommended"><code>MANAGED_CHALLENGE</code></a>. This does not include requests that had the following actions applied: <code>LOG</code>, <code>SKIP</code>, <code>ALLOW</code>. They also accounted for a relatively small percentage of requests. Additionally, we improved our calculation regarding the <code>CHALLENGE</code> type actions to ensure that only unsolved challenges are counted as mitigated. A detailed <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/actions/">description of actions</a> can be found in our developer documentation. This has not changed from last year’s report.</p></li><li><p><b>Bot traffic/automated traffic</b>: any HTTP* request identified by Cloudflare’s <a href="https://www.cloudflare.com/products/bot-management/">Bot Management</a> system as being generated by a bot. This includes requests with a <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">bot score</a> between <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">1 and 29</a> inclusive. This has not changed from last year’s report.</p></li><li><p><b>API traffic</b>: any HTTP* request with a response content type of XML or JSON. Where the response content type is not available, such as for mitigated requests, the equivalent Accept content type (specified by the user agent) is used instead. In this latter case, API traffic won’t be fully accounted for, but it still provides a good representation for the purposes of gaining insights. This has not changed from last year’s report.</p></li></ul><p>Unless otherwise stated, the time frame evaluated in this post is the period from April 1, 2023, through March 31, 2024, inclusive.</p><p>Finally, please note that the data is calculated based only on traffic observed across the Cloudflare network and does not necessarily represent overall HTTP traffic patterns across the Internet.</p><p><sup>*When referring to HTTP traffic we mean both HTTP and HTTPS.</sup></p>
    <div>
      <h2>Global traffic insights</h2>
      <a href="#global-traffic-insights">
        
      </a>
    </div>
    
    <div>
      <h3>Average mitigated daily traffic increases to nearly 7%</h3>
      <a href="#average-mitigated-daily-traffic-increases-to-nearly-7">
        
      </a>
    </div>
    <p>Compared to the prior 12-month period, Cloudflare mitigated a higher percentage of application layer traffic and layer 7 (L7) DDoS attacks between Q2 2023 and Q1 2024, growing from 6% to 6.8%.</p><p><b>Figure 1:</b> Percent of mitigated HTTP traffic increasing over the last 12 months</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5HrbJsLZMv12tBdVLAJEwk/56519fe3c06a1996324ba7a0e710fe5e/unnamed-6.png" />
            
            </figure><p>During large global attack events, we can observe spikes of mitigated traffic approaching 12% of all HTTP traffic. These are much larger spikes than we have ever observed across our entire network.</p>
    <div>
      <h3>WAF and Bot mitigations accounted for 53.9% of all mitigated traffic</h3>
      <a href="#waf-and-bot-mitigations-accounted-for-53-9-of-all-mitigated-traffic">
        
      </a>
    </div>
    <p>As the Cloudflare platform continues to expose additional signals to identify potentially malicious traffic, customers have been actively using these signals in WAF Custom Rules to improve their security posture. Example signals include our <a href="https://developers.cloudflare.com/waf/about/waf-attack-score/">WAF Attack Score</a>, which identifies malicious payloads, and our <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">Bot Score</a>, which identifies automated traffic.</p><p>After WAF and Bot mitigations, HTTP DDoS rules are the second-largest contributor to mitigated traffic. IP reputation, that uses our <a href="https://developers.cloudflare.com/waf/tools/security-level/">IP threat score</a> to block traffic, and access rules, which are simply IP and country blocks, follow in third and fourth place.</p><p><b>Figure 2: Mitigated traffic by Cloudflare product group</b></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/l9emHl05MUfrpqsLehyMr/51e8d8d327a5d78d90126de82bebcc38/unnamed--5--3.png" />
            
            </figure>
    <div>
      <h3>CVEs exploited as fast as 22 minutes after proof-of-concept published</h3>
      <a href="#cves-exploited-as-fast-as-22-minutes-after-proof-of-concept-published">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/security/threats/zero-day-exploit/">Zero-day exploits</a> (also called zero-day threats) are increasing, as is the speed of weaponization of disclosed CVEs. In 2023, 97 zero-days were <a href="https://cloud.google.com/blog/topics/threat-intelligence/2023-zero-day-trends">exploited in the wild</a>, and that’s along with a 15% increase of disclosed <a href="https://www.cve.org/About/Overview">CVEs</a> between 2022 and 2023.</p><p>Looking at CVE exploitation attempts against customers, Cloudflare mostly observed scanning activity, followed by command injections, and some exploitation attempts of vulnerabilities that had PoCs available online, including Apache <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-50164">CVE-2023-50164</a> and <a href="https://nvd.nist.gov/vuln/detail/cve-2022-33891">CVE-2022-33891</a>, Coldfusion <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-29298">CVE-2023-29298</a> <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-38203">CVE-2023-38203</a> and <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-26360">CVE-2023-26360</a>, and MobileIron <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-35082">CVE-2023-35082</a>.</p><p>This trend in CVE exploitation attempt activity indicates that attackers are going for the easiest targets first, and likely having success in some instances given the continued activity around old vulnerabilities.</p><p>As just one example, Cloudflare observed exploitation attempts of <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-27198">CVE-2024-27198</a> (JetBrains TeamCity authentication bypass) at 19:45 UTC on March 4, just 22 minutes after proof-of-concept code was published.</p><p><b>Figure 3:</b> JetBrains TeamCity authentication bypass timeline</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2193b87OL8QLpaE3hxF7RP/06b61f3bdcac2d4ce8364a4b408e35f4/image8-2.png" />
            
            </figure><p>The speed of exploitation of disclosed CVEs is often quicker than the speed at which humans can create WAF rules or create and deploy patches to mitigate attacks. This also applies to our own internal security analyst team that maintains the WAF Managed Ruleset, which has led us to <a href="/detecting-zero-days-before-zero-day">combine the human written signatures with an ML-based approach</a> to achieve the best balance between low false positives and speed of response.</p><p>CVE exploitation campaigns from specific threat actors are clearly visible when we focus on a subset of CVE categories. For example, if we filter on CVEs that result in remote code execution (RCE), we see clear attempts to exploit Apache and Adobe installations towards the end of 2023 and start of 2024 along with a notable campaign targeting Citrix in May of this year.</p><p><b>Figure 4:</b> Worldwide daily number of requests for Code Execution CVEs</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5A2f3Shrcp7rw6zmE9VoNa/90dd0ab1a3e9a80dddfc3c893bebb283/unnamed--1--4.png" />
            
            </figure><p>Similar views become clearly visible when focusing on other CVEs or specific attack categories.</p>
    <div>
      <h3>DDoS attacks remain the most common attack against web applications</h3>
      <a href="#ddos-attacks-remain-the-most-common-attack-against-web-applications">
        
      </a>
    </div>
    <p>DDoS attacks remain the most common attack type against web applications, with DDoS comprising 37.1% of all mitigated application traffic over the time period considered.</p><p><b>Figure 5:</b> Volume of HTTP DDoS attacks over time</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3578XXGADnTHyYT6Kdf6ez/19dc83ad5c2b4989d0542f39fb755fa5/unnamed--6--3.png" />
            
            </figure><p>We saw a large increase in volumetric attacks in February and March 2024. This was partly the result of improved detections deployed by our teams, in addition to increased attack activity. In the first quarter of 2024 alone, Cloudflare’s automated defenses mitigated 4.5 million unique DDoS attacks, an amount equivalent to 32% of all the DDoS attacks Cloudflare mitigated in 2023. Specifically, application layer HTTP DDoS attacks increased by 93% YoY and 51% quarter-over-quarter (QoQ).</p><p>Cloudflare correlates DDoS attack traffic and defines unique attacks by looking at event start and end times along with target destination.</p><p>Motives for launching DDoS attacks range from targeting specific organizations for financial gains (ransom), to testing the capacity of botnets, to targeting institutions and countries for political reasons. As an example, Cloudflare observed a 466% increase in DDoS attacks on Sweden after its acceptance to the NATO alliance on March 7, 2024. This mirrored the DDoS pattern observed during Finland’s NATO acceptance in 2023. The size of DDoS attacks themselves are also increasing.</p><p>In August 2023, Cloudflare mitigated a hyper-volumetric <a href="/zero-day-rapid-reset-http2-record-breaking-ddos-attack">HTTP/2 Rapid Reset</a> DDoS attack that peaked at 201 million requests per second (rps) – three times larger than any previously observed attack. In the attack, threat actors exploited a zero-day vulnerability in the HTTP/2 protocol that had the potential to incapacitate nearly any server or application supporting HTTP/2. This underscores how menacing DDoS vulnerabilities are for unprotected organizations.</p><p>Gaming and gambling became the most targeted sector by DDoS attacks, followed by Internet technology companies and cryptomining.</p><p><b>Figure 6:</b> Largest HTTP DDoS attacks as seen by Cloudflare, by year</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1FYxByBvHz2MQQ8WhKErWk/a7f757447c04820ea5a642838b3e5e10/image1.jpg" />
            
            </figure>
    <div>
      <h2>Bot traffic insights</h2>
      <a href="#bot-traffic-insights">
        
      </a>
    </div>
    <p>Cloudflare has continued to invest heavily in our bot detection systems. In early July, we declared <a href="/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click">AIndependence</a> to help preserve a safe Internet for content creators, offering a brand new “easy button” to <a href="https://www.cloudflare.com/learning/ai/how-to-block-ai-crawlers/">block all AI bots</a>. It’s available for all customers, including those on our free tier.</p><p>Major progress has also been made in other complementary systems such as our Turnstile offering, a user-friendly, privacy-preserving alternative to CAPTCHA.</p><p>All these systems and technologies help us better identify and differentiate human traffic from automated bot traffic.</p>
    <div>
      <h3>On average, bots comprise one-third of all application traffic</h3>
      <a href="#on-average-bots-comprise-one-third-of-all-application-traffic">
        
      </a>
    </div>
    <p>31.2% of all application traffic processed by Cloudflare is bot traffic. This percentage has stayed relatively consistent (hovering at about 30%) over the past three years.</p><p>The term bot traffic may carry a negative connotation, but in reality bot traffic is not necessarily good or bad; it all depends on the purpose of the bots. Some are “good” and perform a needed service, such as customer service chatbots and authorized search engine crawlers. But some bots misuse an online product or service and need to be blocked.</p><p>Different application owners may have different criteria for what they deem a “bad” bot. For example, some organizations may want to <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">block a content scraping bot</a> that is being deployed by a competitor to undercut on prices, whereas an organization that does not sell products or services may not be as concerned with content scraping. Known, good bots are classified by Cloudflare as “verified bots.”</p>
    <div>
      <h3>93% of bots we identified were unverified bots, and potentially malicious</h3>
      <a href="#93-of-bots-we-identified-were-unverified-bots-and-potentially-malicious">
        
      </a>
    </div>
    <p>Unverified bots are often created for disruptive and harmful purposes, such as hoarding inventory, launching DDoS attacks, or attempting to take over an account via brute force or credential stuffing. Verified bots are those that are known to be safe, such as search engine crawlers, and Cloudflare aims to verify all major legitimate bot operators. <a href="https://radar.cloudflare.com/traffic/verified-bots">A list of all verified bots</a> can be found in our documentation.</p><p>Attackers leveraging bots focus most on industries that could bring them large financial gains. For example, consumer goods websites are often the target of inventory hoarding, price scraping run by competition or automated applications aimed at exploiting some sort of arbitrage (for example, sneaker bots). This type of abuse can have a significant financial impact on the target organization.</p><p><b>Figure 8:</b> Industries with the highest median daily share of bot traffic</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/XIeyHN59gsaqxq0OQvCKV/4e23e2b081263ae09c6ca3de6aac2cdd/unnamed--7--3.png" />
            
            </figure>
    <div>
      <h2>API traffic insights</h2>
      <a href="#api-traffic-insights">
        
      </a>
    </div>
    <p>Consumers and end users expect dynamic web and mobile experiences powered by APIs. For businesses, APIs fuel competitive advantages, greater business intelligence, faster cloud deployments, integration of new AI capabilities, and more.</p><p>However, APIs introduce new risks by providing outside parties additional attack surfaces with which to access applications and databases which also need to be secured. As a consequence, numerous attacks we observe are now targeting API endpoints first rather than the traditional web interfaces.</p><p>The additional security concerns are of course not slowing down adoption of API first applications.</p>
    <div>
      <h3>60% of dynamic (non cacheable) traffic is API-related</h3>
      <a href="#60-of-dynamic-non-cacheable-traffic-is-api-related">
        
      </a>
    </div>
    <p>This is a two percentage point increase compared to last year’s report. Of this 60%, about 4% on average is mitigated by our security systems.</p><p><b>Figure 9</b>: Share of mitigated API traffic</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/YmPWYVWpG250GqjO2noHu/63582e53d5f43cda2068385ea9713976/unnamed--3--3.png" />
            
            </figure><p>A substantial spike is visible around January 11-17 that accounts for almost a 10% increase in traffic share alone for that period. This was due to a specific customer zone receiving attack traffic that was mitigated by a WAF Custom Rule.</p><p>Digging into mitigation sources for API traffic, we see the WAF being the largest contributor, as standard malicious payloads are commonly applicable to both API endpoints and standard web applications.</p><p><b>Figure 10:</b> API mitigated traffic broken down by product group</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/76D0iSJOzvx4ArJYIXIfLI/a4bf06a320cc8e9cc03b7da2ab6f35b3/unnamed--4--3.png" />
            
            </figure>
    <div>
      <h2>A quarter of APIs are “shadow APIs”</h2>
      <a href="#a-quarter-of-apis-are-shadow-apis">
        
      </a>
    </div>
    <p>You cannot protect what you cannot see. And, many organizations lack accurate API inventories, even when they believe they can correctly identify API traffic.</p><p>Using our proprietary machine learning model that scans not just known API calls, but all HTTP requests (identifying API traffic that may be going unaccounted for), we found that organizations had 33% more public-facing API endpoints than they knew about. This number was the median, and it was calculated by comparing the number of API endpoints detected through machine learning based discovery vs. customer-provided session identifiers.</p><p>This suggests that nearly a quarter of APIs are “shadow APIs” and may not be properly inventoried and secured.</p>
    <div>
      <h2>Client-side risks</h2>
      <a href="#client-side-risks">
        
      </a>
    </div>
    <p>Most organizations’ web apps rely on separate programs or pieces of code from third-party providers (usually coded in JavaScript). The use of third-party scripts accelerates modern web app development and allows organizations to ship features to market faster, without having to build all new app features in-house.</p><p>Using Cloudflare's client side security product, <a href="https://developers.cloudflare.com/page-shield/">Page Shield</a>, we can get a view on the popularity of third party libraries used on the Internet and the risk they pose to organizations. This has become very relevant recently due to the <a href="http://polyfill.io">Polyfill.io incident</a> that affected more than one hundred thousand sites.</p>
    <div>
      <h3>Enterprise applications use 47 third-party scripts on average</h3>
      <a href="#enterprise-applications-use-47-third-party-scripts-on-average">
        
      </a>
    </div>
    <p>Cloudflare’s typical enterprise customer uses an average of 47 third-party scripts, and a median of 20 third-party scripts. The average is much higher than the median due to SaaS providers, who often have thousands of subdomains which may all use third-party scripts. Here are some of the top third-party script providers Cloudflare customers commonly use:</p><ul><li><p>Google (Tag Manager, Analytics, Ads, Translate, reCAPTCHA, YouTube)</p></li><li><p>Meta (Facebook Pixel, Instagram)</p></li><li><p>Cloudflare (Web Analytics)</p></li><li><p>jsDelivr</p></li><li><p>New Relic</p></li><li><p>Appcues</p></li><li><p>Microsoft (Clarity, Bing, LinkedIn)</p></li><li><p>jQuery</p></li><li><p>WordPress (Web Analytics, hosted plugins)</p></li><li><p>Pinterest</p></li><li><p>UNPKG</p></li><li><p>TikTok</p></li><li><p>Hotjar</p></li></ul><p>While useful, third-party software dependencies are often loaded directly by the end-user’s browser (i.e. they are loaded client-side) placing organizations and their customers at risk given that organizations have no direct control over third-party security measures. For example, in the retail sector, 18% of all data breaches <a href="https://www.verizon.com/business/resources/reports/dbir/">originate from Magecart style attacks</a>, according to Verizon’s 2024 Data Breach Investigations Report.</p>
    <div>
      <h3>Enterprise applications connect to nearly 50 third-parties on average</h3>
      <a href="#enterprise-applications-connect-to-nearly-50-third-parties-on-average">
        
      </a>
    </div>
    <p>Loading a third-party script into your website poses risks, even more so when that script “calls home” to submit data to perform the intended function. A typical example here is Google Analytics: whenever a user performs an action, the Google Analytics script will submit data back to the Google servers. We identify these as connections.</p><p>On average, each enterprise website connects to 50 separate third-party destinations, with a median of 15. Each of these connections also poses a potential client-side security risk as attackers will often use them to exfiltrate additional data going unnoticed.</p><p>Here are some of the top third-party connections Cloudflare customers commonly use:</p><ul><li><p>Google (Analytics, Ads)</p></li><li><p>Microsoft (Clarity, Bing, LinkedIn)</p></li><li><p>Meta (Facebook Pixel)</p></li><li><p>Hotjar</p></li><li><p>Kaspersky</p></li><li><p>Sentry</p></li><li><p>Criteo</p></li><li><p>tawk.to</p></li><li><p>OneTrust</p></li><li><p>New Relic</p></li><li><p>PayPal</p></li></ul>
    <div>
      <h2>Looking forward</h2>
      <a href="#looking-forward">
        
      </a>
    </div>
    <p>This application security report is also <a href="https://www.cloudflare.com/2024-application-security-trends/">available in PDF format</a> with additional recommendations on how to address many of the concerns raised, along with additional insights.</p><p>We also publish many of our reports with dynamic charts on <a href="https://radar.cloudflare.com/reports">Cloudflare Radar</a>, making it an excellent resource to keep up to date with the state of the Internet.</p> ]]></content:encoded>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[API]]></category>
            <guid isPermaLink="false">78VdVl96em2bFvHmZ4jeHj</guid>
            <dc:creator>Michael Tremante</dc:creator>
            <dc:creator>Sabina Zejnilovic</dc:creator>
            <dc:creator>Catherine Newcomb</dc:creator>
        </item>
        <item>
            <title><![CDATA[General availability for WAF Content Scanning for file malware protection]]></title>
            <link>https://blog.cloudflare.com/waf-content-scanning-for-malware-detection/</link>
            <pubDate>Thu, 07 Mar 2024 14:00:14 GMT</pubDate>
            <description><![CDATA[ Announcing the General Availability of WAF Content Scanning, protecting your web applications and APIs from malware by scanning files in-transit ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6Kt17OxA0rO7EXenzZGJXf/b2410be6e9de67c10ee488c6c23ac60d/TXqgLUZ0L11n0fBPaEzi9DYuGJ_QGmAxLbfS9xKb6c_N9nBhFQhsQ4TsJ7kU82ADmgLjkM6EWmZXDBO_5OX4urYAeca428kjsFf2MM8RWBUsNtkg0gEO75D-brm4.png" />
            
            </figure><p>File upload is a common feature in many web applications. Applications may allow users to upload files like images of flood damage to file an insurance claim, PDFs like resumes or cover letters to apply for a job, or other documents like receipts or income statements. However, beneath the convenience lies a potential threat, since allowing unrestricted file uploads can expose the web server and your enterprise network to significant risks related to <a href="https://www.cloudflare.com/network-services/solutions/enterprise-network-security/">security</a>, privacy, and compliance.</p><p>Cloudflare recently introduced <a href="/waf-content-scanning/">WAF Content Scanning</a>, our in-line <a href="https://www.cloudflare.com/application-services/solutions/">malware file detection and prevention solution</a> to stop malicious files from reaching the web server, offering our Enterprise WAF customers an additional line of defense against security threats.</p><p>Today, we're pleased to announce that the feature is now generally available. It will be automatically rolled out to existing WAF Content Scanning customers before the end of March 2024.</p><p>In this blog post we will share more details about the new version of the feature, what we have improved, and reveal some of the technical challenges we faced while building it. This feature is available to Enterprise WAF customers as an add-on license, contact your account team to get it.</p>
    <div>
      <h2>What to expect from the new version?</h2>
      <a href="#what-to-expect-from-the-new-version">
        
      </a>
    </div>
    <p>The feedback from the early access version has resulted in additional improvements. The main one is expanding the maximum size of scanned files from 1 MB to 15 MB. This change required a complete redesign of the solution's architecture and implementation. Additionally, we are improving the dashboard visibility and the overall analytics experience.</p><p>Let's quickly review how malware scanning operates within our WAF.</p>
    <div>
      <h2>Behind the scenes</h2>
      <a href="#behind-the-scenes">
        
      </a>
    </div>
    <p>WAF Content Scanning operates in a few stages: users activate and configure it, then the scanning engine detects which requests contain files, the files are sent to the scanner returning the scan result fields, and finally users can build custom rules with these fields. We will dig deeper into each step in this section.</p>
    <div>
      <h3>Activate and configure</h3>
      <a href="#activate-and-configure">
        
      </a>
    </div>
    <p>Customers can enable the feature via the <a href="https://developers.cloudflare.com/waf/about/content-scanning/api-calls/#enable-waf-content-scanning">API</a>, or through the Settings page in the dashboard (Security → Settings) where a new section has been added for <a href="https://developers.cloudflare.com/waf/about/#detection-versus-mitigation">incoming traffic detection</a> configuration and enablement. As soon as this action is taken, the enablement action gets distributed to the Cloudflare network and begins scanning incoming traffic.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/33blcVizOJx9iZiSqAzX3Y/5bdd6e83500ebf66d842a92854515b4e/image1-27.png" />
            
            </figure><p>Customers can also add a <a href="https://developers.cloudflare.com/waf/about/content-scanning/#2-optional-configure-a-custom-scan-expression">custom configuration</a> depending on the file upload method, such as a base64 encoded file in a JSON string, which allows the specified file to be parsed and scanned automatically.</p><p>In the example below, the customer wants us to look at JSON bodies for the key “file” and scan them.</p><p>This rule is written using the <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/">wirefilter syntax</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2bZfebbWfiQfchZpKJv75q/6088e2458deff944c3965647be3249ef/Scanning-all-incoming-requests-for-file-malware.png" />
            
            </figure>
    <div>
      <h3>Engine runs on traffic and scans the content</h3>
      <a href="#engine-runs-on-traffic-and-scans-the-content">
        
      </a>
    </div>
    <p>As soon as the feature is activated and configured, the scanning engine runs the pre-scanning logic, and identifies content automatically via heuristics. In this case, the engine logic does not rely on the <i>Content-Type</i> header, as it’s easy for attackers to manipulate. When relevant content or a file has been found**,** the engine connects to the <a href="https://developers.cloudflare.com/cloudflare-one/policies/gateway/http-policies/antivirus-scanning/">antivirus (AV) scanner</a> in our <a href="https://www.cloudflare.com/zero-trust/solutions/">Zero Trust solution</a> to perform a thorough analysis and return the results of the scan. The engine uses the scan results to propagate useful fields that customers can use.</p>
    <div>
      <h3>Integrate with WAF</h3>
      <a href="#integrate-with-waf">
        
      </a>
    </div>
    <p>For every request where a file is found, the scanning engine returns various <a href="https://developers.cloudflare.com/waf/about/content-scanning/#content-scanning-fields">fields</a>, including:</p>
            <pre><code>cf.waf.content_scan.has_malicious_obj,
cf.waf.content_scan.obj_sizes,
cf.waf.content_scan.obj_types, 
cf.waf.content_scan.obj_results</code></pre>
            <p>The scanning engine integrates with the WAF where customers can use those fields to <a href="https://developers.cloudflare.com/waf/custom-rules/">create custom WAF rules</a> to address various use cases. The basic use case is primarily blocking malicious files from reaching the web server. However, customers can construct more complex logic, such as enforcing constraints on parameters such as file sizes, file types, endpoints, or specific paths.</p>
    <div>
      <h2>In-line scanning limitations and file types</h2>
      <a href="#in-line-scanning-limitations-and-file-types">
        
      </a>
    </div>
    <p>One question that often comes up is about the file types we detect and scan in WAF Content Scanning. Initially, addressing this query posed a challenge since HTTP requests do not have a definition of a “file”, and scanning all incoming HTTP requests does not make sense as it adds extra processing and latency. So, we had to decide on a definition to spot HTTP requests that include files, or as we call it, “uploaded content”.</p><p>The WAF Content Scanning engine makes that decision by filtering out certain content types identified by heuristics. Any content types not included in a predefined list, such as <code>text/html</code>, <code>text/x-shellscript</code>, <code>application/json</code>, and <code>text/xml</code>, are considered uploaded content and are sent to the scanner for examination. This allows us to scan a <a href="https://crates.io/crates/infer#supported-types">wide range</a> of content types and file types without affecting the performance of all requests by adding extra processing. The wide range of files we scan includes:</p><ul><li><p>Executable (e.g., <code>.exe</code>, <code>.dll</code>, <code>.wasm</code>)</p></li><li><p>Documents (e.g., <code>.doc</code>, <code>.docx</code>, <code>.pdf</code>, <code>.ppt</code>, <code>.xls</code>)</p></li><li><p>Compressed (e.g., <code>.7z</code>, <code>.gz</code>, <code>.zip</code>, <code>.rar</code>)</p></li><li><p>Image (e.g., <code>.jpg</code>, <code>.png</code>, <code>.gif</code>, <code>.webp</code>, <code>.tif</code>)</p></li><li><p>Video and audio files within the 15 MB file size range.</p></li></ul><p>The file size scanning limit of 15 Megabytes comes from the fact that the in-line file scanning as a feature is running in real time, which offers safety to the web server and instant access to clean files, but also impacts the whole request delivery process. Therefore, it’s crucial to scan the payload without causing significant delays or interruptions; namely increased CPU time and latency.</p>
    <div>
      <h2>Scaling the scanning process to 15 MB</h2>
      <a href="#scaling-the-scanning-process-to-15-mb">
        
      </a>
    </div>
    <p>In the early design of the product, we built a system that could handle requests with a maximum body size of 1 MB, and increasing the limit to 15 MB had to happen without adding any extra latency. As mentioned, this latency is not added to all requests, but only to the requests that have uploaded content. However, increasing the size with the same design would have increased the latency by 15x for those requests.</p><p>In this section, we discuss how we previously managed scanning files embedded in JSON request bodies within the former architecture as an example, and why it was challenging to expand the file size using the same design, then compare the same example with the changes made in the new release to overcome the extra latency in details.</p>
    <div>
      <h3>Old architecture used for the Early Access release</h3>
      <a href="#old-architecture-used-for-the-early-access-release">
        
      </a>
    </div>
    <p>In order for customers to use the content scanning functionality in scanning files embedded in JSON request bodies, they had to configure a rule like:</p>
            <pre><code>lookup_json_string(http.request.body.raw, “file”)</code></pre>
            <p>This means we should look in the request body but only for the “file” key, which in the image below contains a base64 encoded string for an image.</p><p>When the request hits our Front Line (FL) NGINX proxy, we buffer the request body. This will be in an in-memory buffer, or written to a temporary file if the size of the request body exceeds the NGINX configuration of <a href="https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size">client_body_buffer_size</a>. Then, our WAF engine executes the lookup_json_string function and returns the base64 string which is the content of the file key. The base64 string gets sent via Unix Domain Sockets to our malware scanner, which does MIME type detection and returns a verdict to the file upload scanning module.</p><p>This architecture had a bottleneck that made it hard to expand on: the expensive latency fees we had to pay. The request body is first buffered in NGINX and then copied into our WAF engine, where rules are executed. The malware scanner will then receive the execution result — which, in the worst scenario, is the entire request body — over a Unix domain socket. This indicates that once NGINX buffers the request body, we send and buffer it in two other services.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2OZumKn4Bar00t8BxfPuz6/bf2ffb663817b3092dccc2acd2701374/Screenshot-2024-03-07-at-12.31.52.png" />
            
            </figure>
    <div>
      <h3>New architecture for the General Availability release</h3>
      <a href="#new-architecture-for-the-general-availability-release">
        
      </a>
    </div>
    <p>In the new design, the requirements were to scan larger files (15x larger) while not compromising on performance. To achieve this, we decided to bypass our WAF engine, which is where we introduced the most latency.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3e2jggqBgIMdZaAwQPkiq9/01f31f022d7ef735cdb536041a28f25b/Screenshot-2024-03-07-at-12.32.42.png" />
            
            </figure><p>In the new architecture, we made the malware scanner aware of what is needed to execute the rule, hence bypassing the Ruleset Engine (RE). For example, the configuration “lookup_json_string(http.request.body.raw, “file”)”, will be represented roughly as:</p>
            <pre><code>{
   Function: lookup_json_string
   Args: [“file”]
}</code></pre>
            <p>This is achieved by walking the <a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract Syntax Tree</a> (AST) when the rule is configured, and deploying the sample struct above to our global network. The struct’s values will be read by the malware scanner, and rule execution and malware detection will happen within the same service. This means we don’t need to read the request body, execute the rule in the Ruleset Engine (RE) module, and then send the results over to the malware scanner.</p><p>The malware scanner will now read the request body from the temporary file directly, perform the rule execution, and return the verdict to the file upload scanning module.</p><p>The file upload scanning module populates these <a href="https://developers.cloudflare.com/waf/about/content-scanning/#content-scanning-fields">fields</a>, so they can be used to write custom rules and take actions. For example:</p>
            <pre><code>all(cf.waf.content_scan.obj_results[*] == "clean")</code></pre>
            <p>This module also enriches our logging pipelines with these fields, which can then be read in <a href="https://developers.cloudflare.com/logs/about/">Log Push</a>, <a href="https://developers.cloudflare.com/logs/edge-log-delivery/">Edge Log Delivery</a>, Security Analytics, and Firewall Events in the dashboard. For example, this is the security log in the Cloudflare dashboard (Security → Analytics) for a web request that triggered WAF Content Scanning:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2XGS4YhMjcm2rLRg9znwVr/9f1e5dcd67808f3bba13b80296a1aa42/image5-15.png" />
            
            </figure>
    <div>
      <h2>WAF content scanning detection visibility</h2>
      <a href="#waf-content-scanning-detection-visibility">
        
      </a>
    </div>
    <p>Using the concept of incoming traffic detection, WAF Content Scanning enables users to identify hidden risks through their traffic signals in the analytics before blocking or mitigating matching requests. This reduces false positives and permits security teams to make decisions based on well-informed data. Actually, this isn't the only instance in which we apply this idea, as we also do it for a number of other products, like WAF Attack Score and Bot Management.</p><p>We have integrated helpful information into our security products, like Security Analytics, to provide this data visibility. The <b>Content Scanning</b> tab, located on the right sidebar, displays traffic patterns even if there were no WAF rules in place. The same data is also reflected in the sampled requests, and you can create new rules from the same view.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6M1QR4dFLFsv0sG8xQ7ezj/83ec1b533b3b2c490451d6624685a26b/image7-4.png" />
            
            </figure><p>On the other hand, if you want to fine-tune your security settings, you will see better visibility in Security Events, where these are the requests that match specific rules you have created in WAF.</p><p>Last but not least, in our <a href="https://developers.cloudflare.com/logs/reference/log-fields/zone/http_requests/">Logpush</a> datastream, we have included the scan fields that can be selected to send to any external log handler.</p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Before the end of March 2024, all current and new customers who have enabled WAF Content Scanning will be able to scan uploaded files up to 15 MB. Next, we'll focus on improving how we handle files in the rules, including adding a dynamic header functionality. Quarantining files is also another important feature we will be adding in the future. If you're an Enterprise customer, reach out to your account team for more information and to get access.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[WAF Rules]]></category>
            <category><![CDATA[Content Scanning]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[General Availability]]></category>
            <category><![CDATA[Anti Malware]]></category>
            <guid isPermaLink="false">018GZnJIhpYLWge6uKNfnd</guid>
            <dc:creator>Radwa Radwan</dc:creator>
            <dc:creator>Paschal Obba</dc:creator>
            <dc:creator>Shreya Shetty</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare announces Firewall for AI]]></title>
            <link>https://blog.cloudflare.com/firewall-for-ai/</link>
            <pubDate>Mon, 04 Mar 2024 14:02:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is one of the first providers to safeguard LLM models and users in the era of AI ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5EdkABBZiYVEgdEQ42QaUf/c73d263a1fbae676983868a314e2acf5/WAF-for-AI.png" />
            
            </figure><p>Today, Cloudflare is announcing the development of Firewall for AI, a protection layer that can be deployed in front of <a href="https://www.cloudflare.com/en-gb/learning/ai/what-is-large-language-model/">Large Language Models (LLMs)</a> to identify abuses before they reach the models.</p><p>While AI models, and specifically LLMs, are surging, customers tell us that they are concerned about the <a href="https://blog.cloudflare.com/best-practices-sase-for-ai/">best strategies to secure their own LLMs</a>. Using LLMs as part of Internet-connected applications introduces new vulnerabilities that can be exploited by bad actors.</p><p>Some of the vulnerabilities affecting traditional web and API applications apply to the LLM world as well, including injections or <a href="https://www.cloudflare.com/learning/security/what-is-data-exfiltration/">data exfiltration</a>. However, there is a new set of threats that are now relevant because of the way LLMs work. For example, researchers have <a href="https://thehackernews.com/2024/02/new-hugging-face-vulnerability-exposes.html">recently discovered</a> a vulnerability in an AI collaboration platform that allows them to hijack models and perform unauthorized actions.</p><p>Firewall for AI is an advanced <a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/">Web Application Firewall (WAF)</a> specifically tailored for applications using LLMs. It will comprise a set of tools that can be deployed in front of applications to detect vulnerabilities and provide visibility to model owners. The tool kit will include products that are already part of WAF, such as Rate Limiting and Sensitive Data Detection, and a new protection layer which is currently under development. This new validation analyzes the prompt submitted by the end user to identify attempts to exploit the model to extract data and other abuse attempts. Leveraging the size of Cloudflare network, Firewall for AI runs as close to the user as possible, allowing us to identify attacks early and protect both end user and models from abuses and attacks.</p><p>Before we dig into how Firewall for AI works and its full feature set, let’s first examine what makes LLMs unique, and the <a href="https://www.cloudflare.com/learning/security/what-is-an-attack-surface/">attack surfaces</a> they introduce. We’ll use the <a href="https://www.cloudflare.com/learning/ai/owasp-top-10-risks-for-llms/">OWASP Top 10 for LLMs</a> as a reference.</p>
    <div>
      <h2>Why are LLMs different from traditional applications?</h2>
      <a href="#why-are-llms-different-from-traditional-applications">
        
      </a>
    </div>
    <p>When considering LLMs as Internet-connected applications, there are two main differences compared with more traditional web apps.</p><p>First, the way users interact with the product. Traditional apps are deterministic in nature. Think about a bank application — it’s defined by a set of operations (check my balance, make a transfer, etc.). The security of the business operation (and data) can be obtained by controlling the fine set of operations accepted by these endpoints: “GET /balance” or “POST /transfer”.</p><p>LLM operations are non-deterministic by design. To start with, LLM interactions are based on natural language, which makes identifying problematic requests harder than matching attack signatures. Additionally, unless a response is cached, LLMs typically provide a different response every time — even if the same input prompt is repeated. This makes limiting the way a user interacts with the application much more difficult. This poses a threat to the user as well, in terms of being exposed to misinformation that weakens the trust in the model.</p><p>Second, a big difference is how the application control plane interacts with the data. In traditional applications, the control plane (code) is well separated from the data plane (database). The defined operations are the only way to interact with the underlying data (e.g. show me the history of my payment transactions). This allows security practitioners to focus on adding checks and guardrails to the control plane and thus protecting the database indirectly.</p><p>LLMs are different in that the training data becomes part of the model itself through the training process, making it extremely difficult to control how that data is shared as a result of a user prompt. Some architectural solutions are being explored, such as separating LLMs into different levels and segregating data. However, no silver bullet has yet been found.</p><p>From a security perspective, these differences allow attackers to craft new attack vectors that can target LLMs and fly under the radar of existing security tools designed for traditional web applications.</p>
    <div>
      <h3>OWASP LLM Vulnerabilities</h3>
      <a href="#owasp-llm-vulnerabilities">
        
      </a>
    </div>
    <p>The <a href="https://owasp.org/">OWASP</a> foundation <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">released a list of</a> the top 10 classes of vulnerabilities for LLMs, providing a useful framework for thinking about <a href="https://www.cloudflare.com/learning/ai/what-is-ai-security/">how to secure language models</a>. Some of the threats are reminiscent of the <a href="https://owasp.org/www-project-top-ten/">OWASP top 10 for web applications</a>, while others are specific to language models.</p><p>Similar to web applications, some of these vulnerabilities can be best addressed when the LLM application is designed, developed, and trained. For example, <a href="https://www.cloudflare.com/learning/ai/data-poisoning/"><i>Training Data Poisoning</i></a> can be carried out by introducing vulnerabilities in the training data set used to train new models. Poisoned information is then presented to the user when the model is live. <i>Supply Chain Vulnerabilities</i> and <i>Insecure Plugin Design</i> are vulnerabilities introduced in components added to the model, like third-party software packages. Finally, managing authorization and permissions is crucial when dealing with <i>Excessive Agency</i>, where unconstrained models can perform unauthorized actions within the broader application or infrastructure.</p><p>Conversely, <i>Prompt Injection</i>, <i>Model Denial of Service</i>, and <i>Sensitive Information Disclosure</i> can be mitigated by adopting a proxy security solution like Cloudflare Firewall for AI. In the following sections, we will give more details about these vulnerabilities and discuss how Cloudflare is optimally positioned to mitigate them.</p>
    <div>
      <h3>LLM deployments</h3>
      <a href="#llm-deployments">
        
      </a>
    </div>
    <p>Language model risks also depend on the deployment model. Currently, we see three main deployment approaches: internal, public, and product LLMs. In all three scenarios, you need to protect models from abuses, protect any proprietary data stored in the model, and protect the end user from misinformation or from exposure to inappropriate content.</p><ul><li><p><b>Internal LLMs:</b> Companies develop LLMs to support the workforce in their daily tasks. These are considered corporate assets and shouldn’t be accessed by non-employees. Examples include an AI co-pilot trained on sales data and customer interactions used to generate tailored proposals, or an LLM trained on an internal knowledge base that can be queried by engineers.</p></li><li><p><b>Public LLMs:</b> These are LLMs that can be accessed outside the boundaries of a corporation. Often these solutions have free versions that anyone can use and they are often trained on general or public knowledge. Examples include <a href="https://openai.com/gpt-4">GPT</a> from OpenAI or <a href="https://www.anthropic.com/product">Claude</a> from Anthropic.</p></li><li><p><b>Product LLM:</b> From a corporate perspective, LLMs can be part of a product or service offered to their customers. These are usually self-hosted, tailored solutions that can be made available as a tool to interact with the company resources. Examples include customer support chatbots or <a href="/security-analytics-ai-assistant/">Cloudflare AI Assistant</a>.</p></li></ul><p>From a risk perspective, the difference between Product and Public LLMs is about who carries the impact of successful attacks. Public LLMs are considered a threat to data because data that ends up in the model can be accessed by virtually anyone. This is one of the reasons many corporations advise their employees not to use confidential information in prompts for publicly available services. Product LLMs can be considered a threat to companies and their intellectual property if models had access to proprietary information during training (by design or by accident).</p>
    <div>
      <h2>Firewall for AI</h2>
      <a href="#firewall-for-ai">
        
      </a>
    </div>
    <p>Cloudflare Firewall for AI will be deployed like a traditional WAF, where every API request with an LLM prompt is scanned for patterns and signatures of possible attacks.</p><p>Firewall for AI can be deployed in front of models hosted on the Cloudflare <a href="/workers-ai">Workers AI</a> platform or models hosted on any other third party infrastructure. It can also be used alongside Cloudflare <a href="https://developers.cloudflare.com/ai-gateway/">AI Gateway</a>, and customers will be able to control and set up Firewall for AI using the WAF control plane.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3kwApAqMHjSChjXkdc3H89/09efa7f0ed81746bf77c62376457d1c8/image1-1.png" />
            
            </figure><p><i>Firewall for AI works like a traditional web application firewall. It is deployed in front of an LLM application and scans every request to identify attack signatures</i></p>
    <div>
      <h3>Prevent volumetric attacks</h3>
      <a href="#prevent-volumetric-attacks">
        
      </a>
    </div>
    <p>One of the threats listed by OWASP is Model Denial of Service. Similar to traditional applications, a <a href="https://www.cloudflare.com/learning/ddos/glossary/denial-of-service/">DoS attack</a> is carried out by consuming an exceptionally high amount of resources, resulting in reduced service quality or potentially increasing the costs of running the model. Given the amount of resources LLMs require to run, and the unpredictability of user input, this type of attack can be detrimental.</p><p>This risk can be mitigated by adopting rate limiting policies that control the rate of requests from individual sessions, therefore limiting the context window. By proxying your model through Cloudflare today, you get <a href="https://www.cloudflare.com/ddos/">DDoS protection</a> out of the box. You can also use Rate Limiting and <a href="/advanced-rate-limiting/">Advanced Rate Limiting</a> to manage the rate of requests allowed to reach your model by setting a maximum rate of request performed by an individual IP address or API key during a session.</p>
    <div>
      <h3>Identify sensitive information with Sensitive Data Detection</h3>
      <a href="#identify-sensitive-information-with-sensitive-data-detection">
        
      </a>
    </div>
    <p>There are two use cases for sensitive data, depending on whether you own the model and data, or you want to prevent users from sending data into public LLMs.</p><p>As defined by <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">OWASP</a>, <i>Sensitive Information Disclosure</i> happens when LLMs inadvertently reveal confidential data in the responses, leading to unauthorized data access, privacy violations, and security breaches. One way to prevent this is to add strict prompt validations. Another approach is to identify when personally identifiable information (PII) leaves the model. This is relevant, for example, when a model was trained with a company knowledge base that may include sensitive information, such asPII (like social security number), proprietary code, or algorithms.</p><p>Customers using LLM models behind Cloudflare WAF can employ the Sensitive Data Detection (SDD) WAF managed ruleset to identify certain PII being returned by the model in the response. Customers can review the SDD matches on WAF Security Events. Today, SDD is offered as a set of managed rules designed to scan for financial information (such as credit card numbers) as well as secrets (API keys). As part of the roadmap, we plan to allow customers to create their own custom fingerprints.</p><p>The other use case is intended to prevent users from sharing PII or other sensitive information with external LLM providers, such as OpenAI or Anthropic. To protect from this scenario, we plan to expand SDD to scan the request prompt and integrate its output with AI Gateway where, alongside the prompt's history, we detect if certain sensitive data has been included in the request. We will start by using the existing SDD rules, and we plan to allow customers to write their own custom signatures. Relatedly, obfuscation is another feature we hear a lot of customers talk about. Once available, the expanded SDD will allow customers to obfuscate certain sensitive data in a prompt before it reaches the model. SDD on the request phase is being developed.</p>
    <div>
      <h2>Preventing model abuses</h2>
      <a href="#preventing-model-abuses">
        
      </a>
    </div>
    <p>Model abuse is a broader category of abuse. It includes approaches like “prompt injection” or submitting requests that generate hallucinations or lead to responses that are inaccurate, offensive, inappropriate, or simply off-topic.</p><p>Prompt Injection is an attempt to manipulate a language model through specially crafted inputs, causing unintended responses by the LLM. The results of an injection can vary, from extracting sensitive information to influencing decision-making by mimicking normal interactions with the model. A classic example of prompt injection is manipulating a CV to affect the output of <a href="https://kai-greshake.de/posts/inject-my-pdf/">resume screening tools</a>.</p><p>A common use case we hear from customers of our AI Gateway is that they want to avoid their application generating toxic, offensive, or problematic language. The risks of not controlling the outcome of the model include reputational damage and harming the end user by providing an unreliable response.</p><p>These types of abuse can be managed by adding an additional layer of protection that sits in front of the model. This layer can be trained to block injection attempts or block prompts that fall into categories that are inappropriate.</p>
    <div>
      <h3>Prompt and response validation</h3>
      <a href="#prompt-and-response-validation">
        
      </a>
    </div>
    <p>Firewall for AI will run a series of detections designed to identify prompt injection attempts and other abuses, such as making sure the topic stays within the boundaries defined by the model owner. Like other existing WAF features, Firewall for AI will automatically look for prompts embedded in HTTP requests or allow customers to create rules based on where in the JSON body of the request the prompt can be found.</p><p>Once enabled, the Firewall will analyze every prompt and provide a score based on the likelihood that it’s malicious. It will also tag the prompt based on predefined categories. The score ranges from 1 to 99 which indicates the likelihood of a prompt injection, with 1 being the most likely.</p><p>Customers will be able to create WAF rules to block or handle requests with a particular score in one or both of these dimensions. You’ll be able to combine this score with other existing signals (like bot score or attack score) to determine whether the request should reach the model or should be blocked. For example, it could be combined with a bot score to identify if the request was malicious and generated by an automated source.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4dxfO29U9BurRgBykPOao0/5aa1619fa5ea3414b7954c78771d1360/Slice-1.png" />
            
            </figure><p><i>Detecting prompt injections and prompt abuse is part of the scope of Firewall for AI. Early iteration of the product design</i></p><p>Besides the score, we will assign tags to each prompt that can be used when creating rules to prevent prompts belonging to any of these categories from reaching their model. For example, customers will be able to create rules to block specific topics. This includes prompts using words categorized as offensive, or linked to religion, sexual content, or politics, for example.</p>
    <div>
      <h2>How can I use Firewall for AI? Who gets this?</h2>
      <a href="#how-can-i-use-firewall-for-ai-who-gets-this">
        
      </a>
    </div>
    <p>Enterprise customers on the Application Security Advanced offering can immediately start using Advanced Rate Limiting and Sensitive Data Detection (on the response phase). Both products can be found in the WAF section of the Cloudflare dashboard. Firewall for AI’s prompt validation feature is currently under development and a beta version will be released in the coming months to all Workers AI users. Sign up to <a href="https://cloudflare.com/lp/firewall-for-ai/">join the waiting list</a> and get notified when the feature becomes available.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>Cloudflare is one of the first security providers launching a set of <a href="https://www.cloudflare.com/ai-security/">tools to secure AI applications</a>. Using Firewall for AI, customers can control what prompts and requests reach their language models, reducing the risk of abuses and data exfiltration. Stay tuned to learn more about how AI application security is evolving.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[LLM]]></category>
            <category><![CDATA[Application Services]]></category>
            <guid isPermaLink="false">6mqhKmVt1dGOhO5xNsli3k</guid>
            <dc:creator>Daniele Molteni</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare launches AI Assistant for Security Analytics]]></title>
            <link>https://blog.cloudflare.com/security-analytics-ai-assistant/</link>
            <pubDate>Mon, 04 Mar 2024 14:00:29 GMT</pubDate>
            <description><![CDATA[ Introducing AI Assistant for Security Analytics. Now it is easier than ever to get powerful insights about your web security. Use the new integrated natural language query interface to explore Security Analytics ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1XqHKAmbIZ4NBeFBXsnaFp/4d66b61833021c41d054dbfd5d8d23c6/AI-Assistant-for-Security-AnalyticsNatural-Language.png" />
            
            </figure><p>Imagine you are in the middle of an attack on your most crucial production application, and you need to understand what’s going on. How happy would you be if you could simply log into the Dashboard and type a question such as: “Compare attack traffic between US and UK” or “Compare rate limiting blocks for automated traffic with rate limiting blocks from human traffic” and see a time series chart appear on your screen without needing to select a complex set of filters?</p><p>Today, we are introducing an AI assistant to help you query your security event data, enabling you to more quickly discover anomalies and potential security attacks. You can now use plain language to interrogate Cloudflare analytics and let us do the magic.</p>
    <div>
      <h2>What did we build?</h2>
      <a href="#what-did-we-build">
        
      </a>
    </div>
    <p>One of the big challenges when analyzing a spike in traffic or any anomaly in your traffic is to create filters that isolate the root cause of an issue. This means knowing your way around often complex dashboards and tools, knowing where to click and what to filter on.</p><p>On top of this, any traditional security dashboard is limited to what you can achieve by the way data is stored, how databases are indexed, and by what fields are allowed when creating filters. With our Security Analytics view, for example, it was difficult to compare time series with different characteristics. For example, you couldn’t compare the traffic from IP address x.x.x.x with automated traffic from Germany without opening multiple tabs to Security Analytics and filtering separately. From an engineering perspective, it would be extremely hard to build a system that allows these types of unconstrained comparisons.</p><p>With the AI Assistant, we are removing this complexity by leveraging our Workers AI platform to build a tool that can help you query your HTTP request and security event data and generate time series charts based on a request formulated with natural language. Now the AI Assistant does the hard work of figuring out the necessary filters and additionally can plot multiple series of data on a single graph to aid in comparisons. This new tool opens up a new way of interrogating data and logs, unconstrained by the restrictions introduced by traditional dashboards.</p><p>Now it is easier than ever to get powerful insights about your application security by using plain language to interrogate your data and better understand how Cloudflare is protecting your business. The new AI Assistant is located in the Security Analytics dashboard and works seamlessly with the existing filters. The answers you need are just a question away.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/65fA9saL0RoHlbErGhKGhL/53e0498be059490a3d442ea383136d8e/Screenshot-2024-02-29-at-13.35.32.png" />
            
            </figure>
    <div>
      <h2>What can you ask?</h2>
      <a href="#what-can-you-ask">
        
      </a>
    </div>
    <p>To demonstrate the capabilities of AI Assistant, we started by considering the questions that we ask ourselves every day when helping customers to deploy the best security solutions for their applications.</p><p>We’ve included some clickable examples in the dashboard to get you started.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7lHKu9aErFzilFDlPId4lL/80a67fb2e3e558ea0a4626ff166fdbd3/ai-analytics.png" />
            
            </figure><p>You can use the AI Assistant to</p><ul><li><p>Identify the source of a spike in attack traffic by asking: “Compare attack traffic between US and UK”</p></li><li><p>Identify root cause of 5xx errors by asking: “Compare origin and edge 5xx errors”</p></li><li><p>See which browsers are most commonly used by your users by asking:”Compare traffic across major web browsers”</p></li><li><p>For an ecommerce site, understand what percentage of users visit vs add items to their shopping cart by asking: “Compare traffic between /api/login and /api/basket”</p></li><li><p>Identify bot attacks against your ecommerce site by asking: “Show requests to /api/basket with a bot score less than 20”</p></li><li><p>Identify the HTTP versions used by clients by asking: “Compare traffic by each HTTP version”</p></li><li><p>Identify unwanted automated traffic to specific endpoints by asking: “Show POST requests to /admin with a Bot Score over 30”</p></li></ul><div>
  
</div><p>You can start from these when exploring the AI Assistant.</p>
    <div>
      <h2>How does it work?</h2>
      <a href="#how-does-it-work">
        
      </a>
    </div>
    <p>Using Cloudflare’s powerful <a href="https://ai.cloudflare.com/">Workers AI</a> global network inference platform, we were able to use one of the off-the-shelf large language models (LLMs) offered on the platform to convert customer queries into GraphQL filters. By teaching an AI model about the available filters we have on our Security Analytics GraphQL dataset, we can have the AI model turn a request such as “<i>Compare attack traffic on /api and /admin endpoints</i>”  into a matching set of structured filters:</p>
            <pre><code>```
[
  {“name”: “Attack Traffic on /api”, “filters”: [{“key”: “clientRequestPath”, “operator”: “eq”, “value”: “/api”}, {“key”: “wafAttackScoreClass”, “operator”: “eq”, “value”: “attack”}]},
  {“name”: “Attack Traffic on /admin”, “filters”: [{“key”: “clientRequestPath”, “operator”: “eq”, “value”: “/admin”}, {“key”: “wafAttackScoreClass”, “operator”: “eq”, “value”: “attack”}]}
]
```</code></pre>
            <p>Then, using the filters provided by the AI model, we can make requests to our <a href="https://developers.cloudflare.com/analytics/graphql-api/">GraphQL APIs</a>, gather the requisite data, and plot a data visualization to answer the customer query.</p><p>By using this method, we are able to keep customer information private and avoid exposing any security analytics data to the AI model itself, while still allowing humans to query their data with ease. This ensures that your queries will never be used to train the model. And because Workers AI hosts a local instance of the LLM on Cloudflare’s own network, your queries and resulting data never leave Cloudflare’s network.</p>
    <div>
      <h2>Future Development</h2>
      <a href="#future-development">
        
      </a>
    </div>
    <p>We are in the early stages of developing this capability and plan to rapidly extend the capabilities of the Security Analytics AI Assistant. Don’t be surprised if we cannot handle some of your requests at the beginning. At launch, we are able to support basic inquiries that can be plotted in a time series chart such as “show me” or “compare” for any currently filterable fields.</p><p>However, we realize there are a number of use cases that we haven’t even thought of, and we are excited to release the Beta version of AI Assistant to all Business and Enterprise customers to let you test the feature and see what you can do with it. We would love to hear your feedback and learn more about what you find useful and what you would like to see in it next. With future versions, you’ll be able to ask questions such as “Did I experience any attacks yesterday?” and use AI to automatically generate WAF rules for you to apply to mitigate them.</p>
    <div>
      <h2>Beta availability</h2>
      <a href="#beta-availability">
        
      </a>
    </div>
    <p>Starting today, AI Assistant is available for a select few users and rolling out to all Business and Enterprise customers throughout March. Look out for it and try for free and let us know what you think by using the <a href="https://docs.google.com/forms/d/e/1FAIpQLSfKtXvPvKUZpjoKZa93ceTk_NAdRY4CF_PpjvFwZwa69o7i6A/viewform?entry.2073820081=Account%20security%20analytics">Feedback</a> link at the top of the Security Analytics page.</p><p>Final pricing will be determined prior to general availability.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Workers AI]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Analytics]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Application Services]]></category>
            <guid isPermaLink="false">7rHa5ZDtie6BcqcvMDndWH</guid>
            <dc:creator>Jen Sells</dc:creator>
            <dc:creator>Harley Turan</dc:creator>
        </item>
    </channel>
</rss>