Skip to content

feat(route/cloudflarestatus): add full-text blog feed - #23590

Merged
TonyRL merged 2 commits into
DIYgod:masterfrom
ljh12138164:feat/cloudflare-blog
Oct 29, 2026
Merged

TonyRL merged 2 commits into
DIYgod:masterfrom
ljh12138164:feat/cloudflare-blog

Conversation

@ljh12138164

@ljh12138164 ljh12138164 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Involved Issue / 该 PR 相关 Issue

Follow-up to #23543, which was closed after the Cloudflare Status feed was fixed upstream in 9e67787. This PR focuses on the Blog feed.

Example for the Proposed Route(s) / 路由地址示例

/cloudflare/blog

New RSS Route Checklist / 新 RSS 路由检查表

  • New Route / 新的路由
  • Anti-bot or rate limit / 反爬/频率限制
    • If yes, do your code reflect this sign? / 如果有,代码是否有对应措施?
  • Date and time / 日期和时间
    • Parsed / 可以解析
    • Correct time zone / 时区正确
  • New package added / 添加了新的包
  • Puppeteer

Note / 说明

Adds a full-text Cloudflare Blog feed at /cloudflarestatus/blog.

The official RSS feed provides the article list, authors, publication dates, categories, GUIDs, and cover-image enclosures. The route fetches article pages for the full content, including inline images, code blocks, and copyable prompts that may be missing from the RSS feed.

Article content is cached, relative URLs are resolved, and copyable prompts are converted into code blocks. Article requests run with a concurrency limit of three.

This PR adds one route file under the existing cloudflarestatus namespace. It does not modify the Status route or require additional packages, authentication, or browser automation.

@github-actions github-actions Bot added route auto: ready to review Human review will come in after lint issues and merge conflicts are fixed labels Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Successfully generated as following:

http://localhost:1200/cloudflarestatus/blog - Success ✔️
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Cloudflare Blog</title>
    <link>https://blog.cloudflare.com/</link>
    <atom:link href="http://localhost:1200/cloudflarestatus/blog" rel="self" type="application/rss+xml"></atom:link>
    <description>Technical deep dives, product updates, and insights from the teams that are helping to build a better Internet. - Powered by RSSHub</description>
    <generator>RSSHub</generator>
    <webMaster>contact@rsshub.app (RSSHub)</webMaster>
    <language>en-us</language>
    <image>
      <url>https://blog.cloudflare.com/favicon.ico</url>
      <title>Cloudflare Blog</title>
      <link>https://blog.cloudflare.com/</link>
    </image>
    <lastBuildDate>Fri, 16 Oct 2026 01:38:31 GMT</lastBuildDate>
    <ttl>5</ttl>
    <item>
      <title>A fully programmable secure web gateway</title>
      <description>&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Every secure web gateway on the market works the same way: traffic matches a condition. A terminal action fires. Allow, Block, Isolate, Log. This model has been the foundation of network security for nearly 30 years, and it handles the common case well. But it has a ceiling, and customers with complex environments hit that ceiling regularly.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Earlier this year, we shared our vision to build a &lt;a href=&quot;https://blog.cloudflare.com/programmable-sase/&quot;&gt;&lt;u&gt;truly programmable SASE platform&lt;/u&gt;&lt;/a&gt;. We also outlined how the term &lt;em&gt;programmability&lt;/em&gt;&amp;nbsp;has become diluted by the security industry. Most vendors claim programmability because they have public APIs, Terraform providers, webhooks, and alerting. Cloudflare offers all of those things too,&amp;nbsp;but that’s not enough. True programmability means running your own code — arbitrary logic that you wrote for your specific environment — inline in the policy evaluation path, at the moment a security decision is made.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Today, we’re excited to announce Cloudflare is bringing true programmability to Cloudflare Gateway and DLP (Data Loss Prevention) by integrating it with the entirety of our edge computing platform. We are releasing a new type of Gateway action, &lt;em&gt;Forward&lt;/em&gt;, and custom validation functions, available to all Zero Trust plans. These capabilities allow you to use a Cloudflare Worker to transform and manipulate traffic, or to bring your own data to policy evaluation.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;The trade-off that every security team faces&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;For as long as firewalls have existed, businesses have faced a binary choice. You can maintain your own security detection engine — your own firewall, your own proxy infrastructure — with high maintenance overhead and low portability, in exchange for maximum customization. Or, you can accept the constraints of a vendor, offloading the considerable maintenance cost, at the expense of flexibility to solve problems specific to your environment.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;In six years of building Cloudflare Gateway, we have heard from thousands of customers struggling with this trade-off. A security team migrating access controls for a critical internal application needs to inject HTTP headers based on JSON Web Token (JWT) claims from their identity provider. The data exists in the request context, but Gateway cannot read the JWT and write the header. So the team stands up a pool of NGINX proxies solely to perform this transformation. That infrastructure now must be patched, monitored, and secured... indefinitely.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Another team wants a Slack notification the moment an employee signs up for a new SaaS service. The policy engine can detect the sign-up event, but it can only Allow or Block. So the team builds a Logpush-to-SIEM-to-Slack pipeline with a 5 to 15 minute delay and no guarantee of delivery. And piles on yet another piece of infrastructure.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Dozens of enterprise customers have asked for warning pages that prompt users for justification before allowing access to sensitive destinations. Most then want to customize the ensuing behavior based on additional context about who the user is and the level of access requested. But serving customized, dynamic responses from a policy engine is exceedingly difficult.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;We have offered customers many extension points over the years. But along with every other firewall vendor, it is impossible to build features to cover threat vectors as quickly as they can appear. However, we also recognize that the best solutions are those which are infinitely extensible to your environment.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Why only Cloudflare can solve this problem&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Cloudflare is not just a firewall, or a secure web gateway, a content delivery network, or an edge service. Cloudflare is a composable compute platform. Cloudflare Workers already allows customers to run complex logic on our network edge from any of our 330+ locations worldwide. &lt;a href=&quot;https://www.cloudflare.com/products/gateway/&quot;&gt;&lt;u&gt;Cloudflare Gateway&lt;/u&gt;&lt;/a&gt;&amp;nbsp;already evaluates and enforces security policy on user traffic at those same locations, on the same machines, in the same data centers.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Only Cloudflare runs both distributed customer compute&amp;nbsp;and a full-featured secure web gateway and firewall in the same globally distributed network. We have the unique opportunity and ability to combine those functions into the industry’s first &lt;em&gt;completely&lt;/em&gt;&amp;nbsp;programmable and customizable SASE platform.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Gateway and Workers were built on the same infrastructure from the beginning. When Gateway forwards traffic to a Worker, that dispatch is a local function call. There is no hairpinning. There is no additional latency from crossing a network boundary. This is the first time that customers will have absolute control over how their proxied traffic is processed, without compromise, using code that they can write and execute without maintaining any sort of infrastructure.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Standalone SASE providers without their own compute platform require you to deploy automation in a separate cloud, manually configure webhooks, and accept the round-trip latency and management overhead of stitching together disconnected systems. No other vendor in this space has a programmable edge compute platform co-located with their security gateway. As threats advance at AI-powered speed, this will provide much needed flexibility and agility for security organizations.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Two Gateway entry points: &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action and&amp;nbsp;&lt;em&gt;Custom Functions&lt;/em&gt;&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A new Gateway action type called &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;and a new policy resource called a &lt;em&gt;Custom Function&lt;/em&gt;&amp;nbsp;are two distinct ways to call a Worker from a Gateway policy. The Forward action is available in public beta today, and Custom Functions will be available before the end of the year.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action: traffic transformation and proxy&lt;/h3&gt;&lt;figure class=&quot;emdash-image pt-portable-image&quot; data-astro-cid-7nvefuv6=&quot;&quot;&gt;&lt;div class=&quot;pt-portable-image-frame&quot; data-image-placeholder-frame=&quot;&quot; data-astro-cid-7nvefuv6=&quot;&quot;&gt;&lt;img src=&quot;https://blog.cloudflare.com/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M507276YAA7DE1F190GB1Z4C.png&amp;amp;w=715&amp;amp;h=368&amp;amp;f=webp&amp;amp;fit=cover&amp;amp;position=center&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; data-image-placeholder-media=&quot;true&quot; data-lightbox-src=&quot;/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M507276YAA7DE1F190GB1Z4C.png&amp;amp;w=1999&amp;amp;h=1028&amp;amp;q=100&amp;amp;f=webp&quot; data-lightbox-width=&quot;1999&quot; data-lightbox-height=&quot;1028&quot; data-astro-cid-7nvefuv6=&quot;true&quot; sizes=&quot;(min-width: 715px) 715px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;715&quot; height=&quot;368&quot; class=&quot;pt-portable-image-media&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;You can customize HTTP traffic behavior with a new &lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/traffic-policies/order-of-enforcement/&quot;&gt;&lt;u&gt;policy action&lt;/u&gt;&lt;/a&gt;&amp;nbsp;called &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;that routes the matched HTTP request to a Worker as a proxy. Policies with the &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action are evaluated for traffic&amp;nbsp;allowed by HTTP policies. The first matching &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;rule will then be applied to your traffic, and the traffic will be sent to its bound Cloudflare Worker. The Worker acts as inline middleware: it receives the full headers and request body. Your logic can then choose to modify either one (or take another asynchronous action of some kind), forward the request to the origin, receive the response, can modify that too, and return the final response to the user.&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { WorkerEntrypoint } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;cloudflare:workers&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; GatewayMiddlewareContext,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; GatewayMiddlewareNext,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;} &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;@cloudflare/zt-types&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayMiddleware&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-fff&quot;&gt; WorkerEntrypoint&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; handle&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt; request&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Request&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt; context&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayMiddlewareContext&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt; next&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayMiddlewareNext&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; )&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Promise&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt; // Read a value from the Gateway context&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; clientIP&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; context.srcIp;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt; // Add headers before the request reaches the origin&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; request.headers.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;X-Gateway-Client-IP&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, clientIP);&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt; // Forward upstream and get the response&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; response&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; await&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; next&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(request);&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt; // Modify the response before it reaches the user&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; response.headers.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;X-Processed-By&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;gateway-middleware&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; response;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Gateway handles the TCP connections, TLS termination and re-encryption, certificate management, and HTTP version negotiation. The Worker is responsible only for the transformation logic. You get a customizable, proxy-like extension point for your existing security stack, with none of the operational cost of hosting a traditional HTTP proxy.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Your Workers also do not have to transform the request. A rule&#39;s sole purpose can be to proxy a request to a Worker that receives the full context of the matched request asynchronously: send a Slack message, write to &lt;a href=&quot;https://developers.cloudflare.com/r2/&quot;&gt;&lt;u&gt;R2&lt;/u&gt;&lt;/a&gt;, log to an external pipeline, call a webhook, update a &lt;a href=&quot;https://developers.cloudflare.com/kv/&quot;&gt;&lt;u&gt;KV&lt;/u&gt;&lt;/a&gt;&amp;nbsp;store. The traffic can continue to its destination, unbothered.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Custom functions: inline policy evaluation&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;/p&gt;&lt;figure class=&quot;emdash-image pt-portable-image&quot; data-astro-cid-7nvefuv6=&quot;&quot;&gt;&lt;div class=&quot;pt-portable-image-frame&quot; data-image-placeholder-frame=&quot;&quot; data-astro-cid-7nvefuv6=&quot;&quot;&gt;&lt;img src=&quot;https://blog.cloudflare.com/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M50728P8Y5D8FDVHH1XYCHZA.png&amp;amp;w=715&amp;amp;h=386&amp;amp;f=webp&amp;amp;fit=cover&amp;amp;position=center&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; data-image-placeholder-media=&quot;true&quot; data-lightbox-src=&quot;/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M50728P8Y5D8FDVHH1XYCHZA.png&amp;amp;w=1999&amp;amp;h=1080&amp;amp;q=100&amp;amp;f=webp&quot; data-lightbox-width=&quot;1999&quot; data-lightbox-height=&quot;1080&quot; data-astro-cid-7nvefuv6=&quot;true&quot; sizes=&quot;(min-width: 715px) 715px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;715&quot; height=&quot;386&quot; class=&quot;pt-portable-image-media&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A custom function calls out to a Worker inline during Gateway policy evaluation and returns a value. The function is then exposed as a selector in the Gateway policy builder, and the selector is evaluated against its values. The selector is usable in the condition of any network or HTTP Gateway rule, the same way a built-in selector like &lt;code&gt;Source IP&lt;/code&gt;&amp;nbsp;or &lt;code&gt;Content Category&lt;/code&gt;&amp;nbsp;works today.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The Worker receives context about the request: source IP, destination, user identity, device posture, HTTP headers, and more, depending on the policy phase. The Worker returns a typed value (string, number, or boolean) that Gateway uses in rule conditions. The contract is simple: data in, value out.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Here is a custom function that parses a JWT &lt;code&gt;Authorization&lt;/code&gt;&amp;nbsp;header and returns the user&#39;s role:&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayCustomSelector&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-fff&quot;&gt; WorkerEntrypoint&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; compute&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayContext&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Promise&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; authHeader&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; ctx.request.headers.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; if&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;authHeader) &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;anonymous&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; token&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; authHeader.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;Bearer &quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; payload&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; JSON&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;atob&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(token.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;]));&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; payload.groups?.[&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;??&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;With this function deployed, an administrator can create an HTTP policy rule: &lt;strong&gt;Custom Function &quot;JWT Role&quot; contains &quot;finance_contractor&quot;&lt;/strong&gt;&amp;nbsp;with an action of Allow. The custom function becomes part of the rule condition, evaluated alongside every other selector.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Custom functions are not limited to HTTP traffic. Because they receive identity, device posture, and connection metadata instead of the full HTTP request, you can use them in the Gateway Network policy rule builder with arbitrary Layer 4 port and protocol traffic as well.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The Worker itself can do anything a Worker can already do — call external APIs, read from KV or D1, or invoke Workers AI. But from Gateway&#39;s perspective, the function is deterministic: data in, value out.&lt;/p&gt;&lt;h4 data-astro-cid-zeirrc35=&quot;&quot;&gt;When to use a custom function or a &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action&lt;/h4&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Custom functions are designed for quick, bounded, stateless evaluations of data which can return a shaped response. You should think of their use similarly to data that can already be evaluated in Gateway selectors; that is, calculations on data that exist within a set of criteria, e.g. “Ports within this range,” or “URL paths that match this regex pattern.” The power comes from being able to extend your structured evaluations with arbitrary or internal sources of data, for which you’ll see some examples below.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action requires a little more planning and preparation. It can be used for powerful transformations inline with users’ live requests, and can manipulate them in complex ways both on the egress and return to the origin service. These should be thought of as transformation functions, something that very few enterprise security proxies even conceptualize today. Workers that use the &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action should be targeted and designed carefully to avoid adverse effects on the end user’s overall experience.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;What you can build&lt;/h2&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Purpose justification and interstitial pages&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A Worker intercepts a request to a sensitive destination and returns an interstitial page requiring the end user to provide a written justification for access. The Worker calls &lt;a href=&quot;https://developers.cloudflare.com/kv/&quot;&gt;&lt;u&gt;Cloudflare KV&lt;/u&gt;&lt;/a&gt;&amp;nbsp;to write a session with a TTL, so the user is only prompted once per configured period. It writes the user&#39;s identity and their stated justification to &lt;a href=&quot;https://developers.cloudflare.com/d1/&quot;&gt;&lt;u&gt;Cloudflare D1&lt;/u&gt;&lt;/a&gt;, creating an audit trail. Or, you can use &lt;a href=&quot;https://developers.cloudflare.com/hyperdrive/&quot;&gt;&lt;u&gt;Hyperdrive&lt;/u&gt;&lt;/a&gt;&amp;nbsp;to write that record to any internal database you already operate.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;This has been one of our most-requested features for over four years. With a Worker able to process and manipulate HTTP traffic,&amp;nbsp;it&#39;s easy to build to your own standards.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Dynamic HTTP header injection&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A custom function parses a JWT from the request&#39;s &lt;code&gt;Authorization&lt;/code&gt;&amp;nbsp;header, extracts the user&#39;s role or group membership, and returns it as a selector value. A Gateway rule matches on that value and sets an &lt;code&gt;X-App-Role&lt;/code&gt;&amp;nbsp;header on the upstream request. No NGINX proxy pool. No additional infrastructure to maintain.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;File inspection and logging&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;When a file download matches certain criteria, a Worker can send the file to a third-party sandboxing service for detonation and analysis. Or it can write the file in its entirety to &lt;a href=&quot;https://developers.cloudflare.com/r2/&quot;&gt;&lt;u&gt;Cloudflare R2&lt;/u&gt;&lt;/a&gt;&amp;nbsp;as a permanent record for later inspection, without the file ever leaving the Cloudflare network.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Real-time alerting on policy match&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A Worker bound to a Forward policy receives traffic whenever a data loss prevention (DLP) profile matches. The Worker sends a message to a Slack channel or PagerDuty endpoint with the user&#39;s email, the rule that fired, and the destination URL.&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; default&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; invoke&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; GatewayContext&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Env&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Promise&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; await&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; fetch&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(env.&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt;SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; method: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; body: &lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; text: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;`DLP alert: ${&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;} triggered &quot;${&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;}&quot; accessing ${&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;}`&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; })&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Complex evaluation logic&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Traditional expression builders for firewalls are not designed for the kind of computation some organizations need at evaluation time. If you maintain internal risk scoring systems that perform behavioral analysis across multiple data sources, or if you have complex maps of users, groups, and conditional memberships where multiple criteria must be independently true, you can use a custom function as the computational extension that evaluates all of that logic and returns a single value to Gateway.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Performance and reliability&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Because Gateway and Workers services run on the same machines in the Cloudflare network, dispatching to a Worker does not introduce a network hop. The performance impact is limited to the execution time of your Worker code itself.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;When a custom function fails — throws an exception, times out, or returns an unexpected value — you configure the fallback behavior per function. &lt;strong&gt;Default&lt;/strong&gt;&amp;nbsp;&lt;strong&gt;values&lt;/strong&gt;&amp;nbsp;are required in the custom function contract, so that it’s easy to determine behavior.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Availability and pricing&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The &lt;em&gt;Forward&lt;/em&gt;&amp;nbsp;action and its integration with Workers are available in a public beta&amp;nbsp;starting today, with &lt;em&gt;Custom Functions&lt;/em&gt;&amp;nbsp;expected to be available before the end of the year. At general availability, both will be available for all customers on all plan types.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Traffic dispatched to your Workers is billed as standard Worker requests. The feature works with Workers Free, Workers Paid, and Workers for Enterprise with no restrictions on functionality. Workers Free does have execution time limits and daily request limits, which is worth considering as you scale the volume of Gateway traffic you send to your Workers.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;DLP custom functions for inline detection validation&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A &lt;a href=&quot;https://blog.cloudflare.com/programmable-sase/&quot;&gt;&lt;u&gt;fully programmable SASE platform&lt;/u&gt;&lt;/a&gt;&amp;nbsp;extends beyond just Gateway.&amp;nbsp;Our DLP offering — already integrated across Gateway, AI Gateway, Email Security, and more — now supports custom outcomes through integrations with our Compute platform, as well.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Most data security products operate by looking for data that matches known patterns. Customers can typically define regular expressions, word lists, or similar to operate these detections. They can also improve confidence in matching through the use of keywords or context analysis on the request body. But these methods have a core flaw: these types of detections can &lt;strong&gt;only&lt;/strong&gt;&amp;nbsp;tell you when something matches the &lt;em&gt;pattern&lt;/em&gt;&amp;nbsp;of data relevant to your organization, not whether &lt;em&gt;this specific instance&lt;/em&gt;&amp;nbsp;of data is indicative of data exfiltration or misuse.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;As attackers become increasingly advanced, and agents can be used to ruthlessly exploit systems, improving our ability to accurately detect patterns is not enough. To improve accuracy for the data that matters, you need to know whether the data in question is actively relevant to your organization.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;To solve this problem, most solutions leverage exact data match, but this comes with its own trade-offs. Customers must prepare, maintain, and transfer reference datasets, then decide how comfortable they are allowing a vendor to manage data from their most sensitive systems.&amp;nbsp;&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Custom validation functions for DLP bridges that gap, and they’re available starting today. These custom functions allow customers to define their own validation logic, using their own source of truth, directly inside a Cloudflare Worker… and apply it &lt;em&gt;everywhere&lt;/em&gt;&amp;nbsp;they use DLP to protect their sensitive data.&lt;/p&gt;&lt;h3 data-astro-cid-zeirrc35=&quot;&quot;&gt;Credential and secret verification&lt;/h3&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;When a DLP detection entry is matched, an outbound Worker can be dispatched to run validation logic prior to a policy enforcement decision. If you have profiles to detect the use of GitHub secrets, but only care about active secrets, you can use a Worker to first look up the status of a detected&amp;nbsp;key, return a response from the appropriate GitHub endpoint, and then decide whether or not the DLP profile should match the traffic.&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; DlpValidation,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; DlpValidationInput,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; DlpValidationResult,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;} &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;@cloudflare/zt-types&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; DlpValidationEntrypoint&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-fff&quot;&gt; DlpValidation&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; validate&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;({ &lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;excerpt&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; DlpValidationInput&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Promise&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;DlpValidationResult&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; bytes&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; Uint8Array.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;atob&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(excerpt), (&lt;/span&gt;&lt;span class=&quot;sk-e36209-fff&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; c.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;charCodeAt&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; token&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; TextDecoder&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(bytes.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(start, end));&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; res&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; await&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; fetch&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;https://api.GitHub.com/user&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;, {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; headers: {&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; Authorization: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;`Bearer ${&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;}`&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;User-Agent&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;dlp-GitHub-validator&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; Accept: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;application/vnd.GitHub+json&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; if&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; (res.ok) &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { score: &lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }; &lt;/span&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt;// token is valid and active&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; if&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; (res.status &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt; 401&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { score: &lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt;&quot;veto&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }; &lt;/span&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt;// token is invalid, discard&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { score: &lt;/span&gt;&lt;span class=&quot;sk-005cc5-ffc799&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; };&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;What&#39;s next&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;This is just the beginning of the fully programmable SASE platform. We are actively working on increasing the entry points from which you can dispatch custom functionality to the entire Cloudflare One suite, with Email Security coming next. That doesn’t mean we’re done building: this new architecture will make it easier for us to build first-party features into all Cloudflare One services faster, more flexibly, and with improved developer experience.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;It’s also getting easier every day to &lt;a href=&quot;https://developers.cloudflare.com/changelog/post/2026-06-05-gateway-egress/&quot;&gt;&lt;u&gt;protect your Workers, agents, and their traffic&lt;/u&gt;&lt;/a&gt;&amp;nbsp;using Cloudflare One. If you are an Enterprise customer who would like a strategy session for implementation, a preview of the coming functionality, or to be notified about the custom functions beta, please reach out to your account team.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Your organizational security can now do anything a Cloudflare Worker can do. We can&#39;t wait to see what you build.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/traffic-controls/integrate-workers/forward-traffic/&quot;&gt;&lt;u&gt;Review the Gateway and Workers integration documentation&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/traffic-controls/integrate-workers/worker-templates/&quot;&gt;&lt;u&gt;See example Worker scripts for use in Gateway&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/skills/blob/main/skills/gateway-workers/SKILL.md&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Teach your agent to build with Gateway and Workers&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/data-loss-prevention/detection-entries/custom-validation-workers/&quot;&gt;&lt;u&gt;Learn more about Custom functions&amp;nbsp;for DLP&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;/p&gt;</description>
      <link>https://blog.cloudflare.com/programmable-gateway-dlp/</link>
      <guid isPermaLink="false">01M5072CXFWQ88M9NCXZBSPAF2</guid>
      <pubDate>Thu, 15 Oct 2026 17:11:12 GMT</pubDate>
      <dc:creator>AJ Gerstenhaber, Abe Carryl</dc:creator>
      <enclosure url="https://blog.cloudflare.com/_emdash/api/media/file/01M50725GWYBHA14CTTDWFESC7.png" length="0" type="image/png"></enclosure>
      <category>Cloudflare Gateway</category>
      <category>Cloudflare Workers</category>
      <category>Data Loss Prevention</category>
      <category>Developer Platform</category>
      <category>SASE</category>
    </item>
    <item>
      <title>Deploy with Void</title>
      <description>&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;VoidZero&#39;s tools such as Vite, Vitest, Oxc, and Rolldown — bundled in one toolchain as &lt;a href=&quot;https://viteplus.dev/&quot;&gt;&lt;u&gt;Vite+&lt;/u&gt;&lt;/a&gt;&amp;nbsp;— have made frontend development faster, but building full-stack applications requires more than just a tooling stack. These applications need server routes, databases, local development environments, and a fast and easy way to deploy ideas to production.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;We’re excited to open-source three new products that bring server routing, typed data access, and Cloudflare deployment into a unified Vite workflow.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Void Platform:&lt;/strong&gt;&amp;nbsp;A shared deployment platform for teams to host Void apps on Cloudflare.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Void SDK:&lt;/strong&gt;&amp;nbsp;A composable JavaScript SDK for building full-stack apps with Vite.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Void CLI:&lt;/strong&gt;&amp;nbsp;A CLI for provisioning resources and deploying Vite apps to Cloudflare.&lt;/li&gt;&lt;/ul&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The CLI deploys apps built with the SDK to the Platform. All three products are open-sourced as a single JavaScript package and Vite plugin that you can install via &lt;code&gt;npm install void&lt;/code&gt;. With &lt;a href=&quot;http://void.cloud/&quot;&gt;&lt;u&gt;Void&lt;/u&gt;&lt;/a&gt;, you can build your server and client together, carry types from your database to the UI, and let Void automatically provision the Cloudflare resources that your app uses.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;We originally set out to build a single, private platform for all users to deploy apps to. After &lt;a href=&quot;https://blog.cloudflare.com/voidzero-joins-cloudflare/&quot;&gt;&lt;u&gt;VoidZero joined Cloudflare&lt;/u&gt;&lt;/a&gt;, we adjusted our direction to open-source the platform and allow anyone to install because we saw a growing need: &lt;strong&gt;companies want to encourage vibe-coded internal apps, but are concerned about security and do not want to give cloud access to every employee&lt;/strong&gt;. Void addresses this problem.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Void Platform: a cloud platform for your company&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The Void Platform is fully open source and you can fork it and adapt it to your needs by integrating your company&#39;s systems, customize deployment workflows, build features for your customers, or make it work on other deployment platforms. Use the platform as it is, contribute improvements upstream, or fork it and build only the features you need. The open source code can be used out of the box or as a starting point.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;As an admin of a Void Platform, you control access, set resource limits, inspect deployments and usage through the Void CLI or admin dashboard, and provide guardrails so everyone else can ship serious and vibe coded apps to the same shared platform.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;By installing a Void Platform, your team or customers have a shared deployment environment in your Cloudflare account on top of &lt;a href=&quot;https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/&quot;&gt;&lt;u&gt;Workers for Platforms&lt;/u&gt;&lt;/a&gt;. Void Platform enables:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Faster prototyping&lt;/strong&gt;. Your team can quickly build prototypes, deploy them, and share working apps for feedback, without setting up a separate Cloudflare account or provisioning resources for every project. This reduces the time to ship internal apps from days/weeks to minutes.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Non-technical teams building&lt;/strong&gt;. This workflow also lets teammates who do not normally write code work with coding agents to build and share their own apps. A designer can create an interactive prototype, or an operations teammate can build an internal dashboard, then deploy it to the same platform. All with the right security measures in place.&lt;/li&gt;&lt;/ol&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;To self-host a Void platform, you need:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A Cloudflare account with Workers for Platforms and R2 enabled&lt;/li&gt;&lt;li&gt;A PostgreSQL database&lt;/li&gt;&lt;li&gt;An account with your chosen login provider&lt;/li&gt;&lt;li&gt;A domain for your apps&lt;/li&gt;&lt;/ul&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Then install Void as a cloud platform by running a single command:&lt;/p&gt;&lt;div id=&quot;html-block-52wg9hmzb&quot; class=&quot;html-block&quot;&gt;&lt;div style=&quot;padding-top:61.047027506654835%&quot;&gt;
        &lt;iframe src=&quot;https://customer-eq7kiuol0tk9chox.cloudflarestream.com/affebd0d7251da155e5307f19069c944/iframe?muted=true&amp;amp;preload=true&amp;amp;loop=true&amp;amp;autoplay=true&amp;amp;poster=https%3A%2F%2Fcustomer-eq7kiuol0tk9chox.cloudflarestream.com%2Faffebd0d7251da155e5307f19069c944%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600&quot; loading=&quot;lazy&quot; style=&quot;border:none;position:absolute;top:0;left:0;height:100%;width:100%&quot; allow=&quot;autoplay; encrypted-media; picture-in-picture&quot; allowfullscreen=&quot;true&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Once your platform is set up, approved users can connect to it via the Void CLI for deployment.&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;void connect https://api.orange-company.dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;A user builds their app using the Void SDK, which is what powers Void Platform benefits like authentication, framework detection, resource provisioning, and more. In other words, Void Platform only works because of the accompanying SDK and CLI.&lt;/p&gt;&lt;h2 data-astro-cid-zeirrc35=&quot;&quot;&gt;Void SDK: zero-config infrastructure&lt;/h2&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;a href=&quot;https://void.cloud/&quot;&gt;&lt;u&gt;Void&lt;/u&gt;&lt;/a&gt;&amp;nbsp;turns a Vite app into a full-stack Cloudflare Workers app. You or your agents can write code and Void will automatically infer resource bindings and provision resources such as databases, queues, or AI bindings during deployment.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;To get started, add Void as a Vite plugin:&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { defineConfig } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;vite&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { voidPlugin } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;void&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { voidReact } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &quot;@void/react/plugin&quot;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; default&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; defineConfig&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; plugins: [&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;voidPlugin&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(), &lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;voidReact&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;()],&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;The Void SDK ships with adapters for popular JavaScript UI frameworks such as React and Vue, provides file-based API routing, pre-rendering, caching, islands, and end-to-end type safety from the database to your UI.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;All of Void’s features are optional and composable. Void integrates with existing application frameworks such as Vinext, React Router, SvelteKit, Nuxt, TanStack Start, and Astro. You can use those frameworks for routing and rendering, while Void handles resource APIs using Hono, migrations, deployment, and authentication with Better Auth.&lt;/p&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;Let&#39;s take a look at building a server-rendered page, with types inferred from the database query through to the client:&lt;/p&gt;&lt;div class=&quot;emdash-code&quot;&gt;&lt;pre class=&quot;shiki shiki-themes github-light vesper&quot; tabindex=&quot;0&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-6a737d-8b8b8b94&quot;&gt;// pages/blog.server.ts&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { defineHandler, &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; InferProps } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &#39;void&#39;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { db } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &#39;void/db&#39;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; { posts } &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-032f62-99ffe4&quot;&gt; &#39;@schema&#39;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;sk-005cc5-fff&quot;&gt; loader&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; defineHandler&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; () &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; ({&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; posts: &lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; db.&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;(posts),&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;}));&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
        &lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; Props&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sk-6f42c1-ffc799&quot;&gt; InferProps&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sk-d73a49-a0a0a0&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;sk-24292e-fff&quot;&gt; loader&amp;gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-astro-cid-zeirrc35=&quot;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;emdash-code&quot

@github-actions

Copy link
Copy Markdown
Contributor

Successfully generated as following:

http://localhost:1200/cloudflare/blog - Success ✔️
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Cloudflare Blog</title>
    <link>https://blog.cloudflare.com/</link>
    <atom:link href="http://localhost:1200/cloudflare/blog" rel="self" type="application/rss+xml"></atom:link>
    <description>Technical deep dives, product updates, and insights from the teams that are helping to build a better Internet. - Powered by RSSHub</description>
    <generator>RSSHub</generator>
    <webMaster>contact@rsshub.app (RSSHub)</webMaster>
    <language>en-us</language>
    <image>
      <url>https://blog.cloudflare.com/favicon.ico</url>
      <title>Cloudflare Blog</title>
      <link>https://blog.cloudflare.com/</link>
    </image>
    <lastBuildDate>Thu, 29 Oct 2026 00:21:39 GMT</lastBuildDate>
    <ttl>5</ttl>
    <item>
      <title>Introducing the Cloudflare PHP Capture the Flag challenge</title>
      <description>&lt;p&gt;Last week was one for the Internet security history books. First, &lt;a href=&quot;https://blog.cloudflare.com/emudhra-certificate-compromise/&quot;&gt;&lt;u&gt;eight eMudhra intermediate certificates were compromised&lt;/u&gt;&lt;/a&gt;, creating the possibility of forged certificates that could be used to impersonate servers. Then came &lt;a href=&quot;https://blog.cloudflare.com/php-vulnerabilities-waf-protection/&quot;&gt;&lt;u&gt;php2shell&lt;/u&gt;&lt;/a&gt;: serious vulnerabilities in PHP, the runtime behind a large portion of the Web.&lt;/p&gt;&lt;p&gt;Cloudflare worked around the clock as these events unfolded to protect our customers and help protect the Internet. We shipped client updates and &lt;a href=&quot;https://blog.cloudflare.com/emudhra-certificate-compromise/#our-response&quot;&gt;&lt;u&gt;multiple mitigations&lt;/u&gt;&lt;/a&gt;, updated our web application firewall (WAF) with new rules to block attackers from exploiting the PHP vulnerabilities, and introduced a new feature called &lt;a href=&quot;https://blog.cloudflare.com/full-transaction-waf/&quot;&gt;&lt;u&gt;full transaction detection&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As always in situations like this, these new capabilities were made available on all plans, including Free.&lt;/p&gt;&lt;h2&gt;Put our WAF to the test&lt;/h2&gt;&lt;p&gt;Protecting systems from vulnerabilities like these is always an ongoing process, not a one-time event. The widespread adoption of AI allows attackers to discover new vectors with unprecedented speed and efficiency, so collecting real-world data to test our assumptions and strengthen defenses is essential.&lt;/p&gt;&lt;p&gt;That’s why today we&#39;re launching&amp;nbsp;the &lt;a href=&quot;https://php-rce.cloudflare.app/&quot;&gt;&lt;u&gt;Cloudflare PHP Capture the Flag challenge&lt;/u&gt;&lt;/a&gt;, run through our &lt;a href=&quot;https://hackerone.com/cloudflare&quot;&gt;&lt;u&gt;Bug Bounty program&lt;/u&gt;&lt;/a&gt;. We&#39;ve put a deliberately vulnerable PHP installation behind our WAF, and we&#39;re inviting security researchers on HackerOne to try to bypass the protections and capture a flag.&lt;/p&gt;&lt;h2&gt;How this Capture the Flag (CTF) works&lt;/h2&gt;&lt;p&gt;We are keeping this simple. The challenge focuses on &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2026-109618&quot;&gt;&lt;u&gt;CVE-2026-109618&lt;/u&gt;&lt;/a&gt;&amp;nbsp;and &lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2026-109619&quot;&gt;&lt;u&gt;CVE-2026-109619&lt;/u&gt;&lt;/a&gt;, the two PHP vulnerabilities behind &lt;a href=&quot;https://blog.cloudflare.com/php-vulnerabilities-waf-protection/&quot;&gt;&lt;u&gt;php2shell&lt;/u&gt;&lt;/a&gt;. The target runs stock &lt;a href=&quot;https://www.php.net/releases/8_5_11.php&quot;&gt;&lt;u&gt;PHP 8.5.11&lt;/u&gt;&lt;/a&gt;&amp;nbsp;(with standard PHP extensions), Apache 2 (via mod_php), and an empty index.php inside a &lt;a href=&quot;https://developers.cloudflare.com/containers/&quot;&gt;&lt;u&gt;Cloudflare Container&lt;/u&gt;&lt;/a&gt;, with our default WAF protection rules for these vulnerabilities enabled in front of it. Inside the sandbox is a file called &lt;code&gt;/flag&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The sandbox is reset every few minutes, including the flag file.&lt;/p&gt;&lt;figure class=&quot;emdash-image pt-portable-image&quot;&gt;&lt;div class=&quot;pt-portable-image-frame&quot; data-image-placeholder-frame=&quot;&quot;&gt;&lt;img src=&quot;https://blog.cloudflare.com/_emdash/api/media/file/01M5YGNP9QEXR0RW14AZ0NCBGQ.png&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; data-image-placeholder-media=&quot;true&quot; data-lightbox-src=&quot;/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M5YGNP9QEXR0RW14AZ0NCBGQ.png&amp;amp;w=1999&amp;amp;h=670&amp;amp;q=100&amp;amp;f=webp&quot; data-lightbox-width=&quot;1999&quot; data-lightbox-height=&quot;670&quot; sizes=&quot;(min-width: 715px) 715px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;715&quot; height=&quot;240&quot; class=&quot;pt-portable-image-media&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/div&gt;&lt;figcaption&gt; Diagram of sending the exploit payload, capturing and verifying the flag.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Your mission, should you choose to accept it: &lt;strong&gt;bypass the WAF protections, exploit the PHP sandbox, and recover the contents of /flag&lt;/strong&gt;. You can use your own research tools. The &lt;a href=&quot;https://php-rce.cloudflare.app/&quot;&gt;&lt;u&gt;challenge page&lt;/u&gt;&lt;/a&gt;&amp;nbsp;has the environment details, scope, and flag verification form.&lt;/p&gt;&lt;h2&gt;Challenge requirements&lt;/h2&gt;&lt;p&gt;This&amp;nbsp;limited-time challenge is run via &lt;a href=&quot;https://hackerone.com/cloudflare?type=team&quot;&gt;&lt;u&gt;Cloudflare&#39;s Bug Bounty program on HackerOne&lt;/u&gt;&lt;/a&gt;. All aspects of this challenge are subject to HackerOne &lt;a href=&quot;https://www.hackerone.com/terms/community&quot;&gt;&lt;u&gt;terms&lt;/u&gt;&lt;/a&gt;&amp;nbsp;and the Cloudflare HackerOne &lt;a href=&quot;https://hackerone.com/cloudflare&quot;&gt;&lt;u&gt;program rules&lt;/u&gt;&lt;/a&gt;&amp;nbsp;the (“Bounty Terms”). If you find an eligible bypass, you must follow these requirements in order to claim the bounty:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;All participants must sign up for a HackerOne account and review and agree to the Bounty&amp;nbsp;Terms &lt;strong&gt;&lt;u&gt;before&lt;/u&gt;&lt;/strong&gt;&amp;nbsp;participating in the CTF.&lt;/li&gt;&lt;li&gt;Demonstrate attacker-controlled PHP code or command execution inside the sandbox through an authorized POST request.&lt;/li&gt;&lt;li&gt;Use that remote code execution (RCE) to recover the current contents of /flag, then successfully verify the flag through &lt;a href=&quot;https://php-rce.cloudflare.app/#verification&quot;&gt;&lt;u&gt;the CTF user interface&lt;/u&gt;&lt;/a&gt;&amp;nbsp;(UI). Verify promptly before a reset; retain the successful result for later review.&lt;/li&gt;&lt;li&gt;Submit a private report to Cloudflare on HackerOne. Include PHP CTF in the title and provide:&lt;ol&gt;&lt;li&gt;The endpoint, complete payload, and request sequence, preserving relevant headers, encoding, and body bytes.&lt;/li&gt;&lt;li&gt;Raw request/response captures or a readable proof of concept sufficient to reproduce the full chain.&lt;/li&gt;&lt;li&gt;An explanation of the WAF bypass, executed code or command, and how that execution recovered /flag.&lt;/li&gt;&lt;li&gt;The attempt ID, successful UI verification result, and exploit/verification UTC timestamps. Include the flag privately if needed for verification.&lt;/li&gt;&lt;li&gt;What makes the method or payload materially distinct, and related submissions you know about.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;UI verification does not submit a &lt;a href=&quot;https://hackerone.com/cloudflare&quot;&gt;&lt;u&gt;HackerOne&lt;/u&gt;&lt;/a&gt;&amp;nbsp;report or establish reporting priority. File disclosure without RCE, RCE without successful flag recovery and UI verification, local-only exploits, rediscovery of the known PHP vulnerabilities, and WAF detection differences or partial chains without the full objective are not eligible.&lt;/p&gt;&lt;p&gt;Awards require a &lt;strong&gt;materially distinct Firewall (WAF) bypass method&lt;/strong&gt;, even for the same PHP CVE. Reports using the &lt;strong&gt;same Firewall-bypass mechanism are duplicates&lt;/strong&gt;, regardless of differences in the PHP exploit, payload, RCE technique, or flag-recovery method. New flags, resets, attempt IDs, or cosmetic changes—including equivalent encodings—do not qualify as unique. Equivalent submissions are duplicates even if unfixed; only the first complete, reproducible HackerOne report is considered. Cloudflare makes final duplicate and reward decisions.&lt;/p&gt;&lt;p&gt;We record attempted metadata and request payloads to help analyze reports, so please use test data only. Do not send credentials, personal information, or anything else you would not want included in a research record. Read&amp;nbsp;Cloudflare’s &lt;a href=&quot;https://www.cloudflare.com/privacypolicy/&quot;&gt;&lt;u&gt;privacy notice&lt;/u&gt;&lt;/a&gt;&amp;nbsp;before testing.&lt;/p&gt;&lt;p&gt;Testing is authorized only against the challenge hostname&#39;s WAF-protected &lt;code&gt;/php/*&lt;/code&gt;&amp;nbsp;endpoints&amp;nbsp;(POST method only). Other Cloudflare services, direct access to the underlying infrastructure, the upstream PHP project, and third-party systems are out of scope. No denial of service, high-volume scanning, persistence, social engineering, or attacks on other participants. If you get a 429 or 503, back off.&lt;/p&gt;&lt;p&gt;In the event of any conflict between this blog post and the Bounty Terms, the Bounty Terms&amp;nbsp;shall prevail.&lt;/p&gt;&lt;p&gt;Cloudflare reserves the right to suspend or terminate this challenge at any time. Once the competition is removed from HackerOne, it is officially terminated, so please refer to the Cloudflare HackerOne page for the most up-to-date information on whether this challenge remains open.&lt;/p&gt;&lt;h2&gt;Not a substitute for patching&lt;/h2&gt;&lt;p&gt;Our WAF protects you, but it is not a replacement for fixing vulnerable software. Response blocking can prevent exposed data from reaching an attacker, but it cannot undo actions already performed at the origin. If you run PHP, follow the &lt;a href=&quot;https://www.php.net/security/&quot;&gt;&lt;u&gt;latest PHP security advisories&lt;/u&gt;&lt;/a&gt;&amp;nbsp;and apply the relevant updates.&lt;/p&gt;&lt;p&gt;Last week was a reminder that helping build a better Internet often takes many people—researchers, maintainers, and teams across the industry—doing difficult, urgent work together.&lt;/p&gt;&lt;p&gt;We hope this challenge gives everyone a useful way to join in. Head over to &lt;a href=&quot;https://php-rce.cloudflare.app/&quot;&gt;&lt;u&gt;php-rce.cloudflare.app&lt;/u&gt;&lt;/a&gt;&amp;nbsp;if you want to participate: the flag is there, and we&#39;d like to know if you can get it.&lt;/p&gt;</description>
      <link>https://blog.cloudflare.com/php-ctf/</link>
      <guid isPermaLink="false">01M5YGNW60G1XYREPZQ9W8PSTD</guid>
      <pubDate>Tue, 27 Oct 2026 13:00:00 GMT</pubDate>
      <dc:creator>Celso Martinho, Sven Sauleau, Dan Jones</dc:creator>
      <enclosure url="https://blog.cloudflare.com/_emdash/api/media/file/01M5YGNS8F8NYE3V5QERKYNG79.png" length="0" type="image/png"></enclosure>
      <category>Bug Bounty</category>
      <category>php</category>
      <category>Security</category>
      <category>Vulnerabilities</category>
      <category>WAF</category>
    </item>
    <item>
      <title>What took the Internet offline in Q3 2026</title>
      <description>&lt;p&gt;The Internet can feel invisible when everything is working normally. But when connectivity breaks, the many systems it depends upon become evident in an instant. Because Cloudflare’s global network handles more than 20% of the web’s traffic, it offers a unique perspective of how Internet traffic is behaving. When failures in infrastructure, power, policy, or security disrupt access to the Internet, &lt;a href=&quot;https://radar.cloudflare.com/&quot;&gt;&lt;u&gt;Cloudflare Radar&lt;/u&gt;&lt;/a&gt;&amp;nbsp;can observe the impact by monitoring traffic to our customers. Each quarter, we review the disruptions detected and annotated on Radar, highlighting what happened, where it happened, and the broader conditions that shaped each event.&lt;/p&gt;&lt;p&gt;In this post, we examine the major categories of Internet disruptions observed during the third quarter of 2026, including government-directed shutdowns, power outages and natural disasters.&lt;/p&gt;&lt;h2&gt;Disruptions at a glance&lt;/h2&gt;&lt;p&gt;Between July and September, Internet disruptions were largely driven by failures in the systems the Internet depends on. Power grids failed in Cuba, Honduras, Guam, Ukraine, and several other countries. Natural disasters damaged electricity and telecommunications infrastructure from Nepal to Colombia. Government-directed shutdowns remained the most frequent source of disruption, driven largely by exam-related shutdowns in Iraq, while renewed conflict in Ethiopia’s Tigray region showed how quickly connectivity can become part of a broader political and humanitarian crisis. Outages within the United States, Japan, and Portugal — countries with a relatively strong history of Internet resilience — remind us that no country is immune to disruption.&lt;/p&gt;&lt;p&gt;In total, Cloudflare Radar recorded 49 disruptions during the quarter. Government-directed shutdowns accounted for 19 incidents, including 18 exam shutdowns in Iraq. Power outages followed with 14 incidents, while natural disasters accounted for five. &lt;/p&gt;&lt;iframe class=&quot;emdash-html-block&quot; data-emdash-html-block=&quot;&quot; srcdoc=&quot;&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset=&amp;quot;utf-8&amp;quot;&gt;&lt;base href=&amp;quot;/&amp;quot; target=&amp;quot;_top&amp;quot;&gt;&lt;style&gt;body{margin:0;font-family:system-ui,sans-serif;line-height:1.5}&lt;/style&gt;&lt;script&gt;(() =&gt; {
        const type = &amp;quot;emdash:html-block-frame&amp;quot;;
        const root = document.documentElement;
        const report = () =&gt; {
        const overflow = root.scrollHeight &gt; root.clientHeight ? root.scrollHeight : 0;
        const height = Math.max(root.getBoundingClientRect().height, overflow);
        parent.postMessage({ type, height: Math.ceil(height + innerHeight - root.clientHeight) }, &amp;quot;*&amp;quot;);
        };
        const observer = new ResizeObserver(report);
        observer.observe(root);
        addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, () =&gt; observer.observe(document.body));
        addEventListener(&amp;quot;message&amp;quot;, (event) =&gt; {
        if (event.source === parent &amp;amp;&amp;amp; event.data?.type === type) report();
        });
        addEventListener(
        &amp;quot;securitypolicyviolation&amp;quot;,
        () =&gt; parent.postMessage({ type, blocked: true }, &amp;quot;*&amp;quot;),
        { once: true },
        );
        })();&lt;/script&gt;&lt;/head&gt;&lt;body&gt;&lt;iframe class=&amp;quot;cf-radar-embed&amp;quot; width=&amp;quot;800&amp;quot; height=&amp;quot;530&amp;quot; src=&amp;quot;https://assets.radar.cloudflare.com/blog/q3-2026-internet-disruption-summary/map.html&amp;quot; style=&amp;quot;border:0;max-width:100%;height:440px;max-height:440px;&amp;quot;&gt;&lt;/iframe&gt; &lt;/body&gt;&lt;/html&gt;&quot; sandbox=&quot;allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation&quot; title=&quot;Embedded HTML&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;&lt;iframe class=&quot;emdash-html-block&quot; data-emdash-html-block=&quot;&quot; srcdoc=&quot;&lt;!doctype html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset=&amp;quot;utf-8&amp;quot;&gt;&lt;base href=&amp;quot;/&amp;quot; target=&amp;quot;_top&amp;quot;&gt;&lt;style&gt;body{margin:0;font-family:system-ui,sans-serif;line-height:1.5}&lt;/style&gt;&lt;script&gt;(() =&gt; {
        const type = &amp;quot;emdash:html-block-frame&amp;quot;;
        const root = document.documentElement;
        const report = () =&gt; {
        const overflow = root.scrollHeight &gt; root.clientHeight ? root.scrollHeight : 0;
        const height = Math.max(root.getBoundingClientRect().height, overflow);
        parent.postMessage({ type, height: Math.ceil(height + innerHeight - root.clientHeight) }, &amp;quot;*&amp;quot;);
        };
        const observer = new ResizeObserver(report);
        observer.observe(root);
        addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, () =&gt; observer.observe(document.body));
        addEventListener(&amp;quot;message&amp;quot;, (event) =&gt; {
        if (event.source === parent &amp;amp;&amp;amp; event.data?.type === type) report();
        });
        addEventListener(
        &amp;quot;securitypolicyviolation&amp;quot;,
        () =&gt; parent.postMessage({ type, blocked: true }, &amp;quot;*&amp;quot;),
        { once: true },
        );
        })();&lt;/script&gt;&lt;/head&gt;&lt;body&gt;&lt;iframe class=&amp;quot;cf-radar-embed&amp;quot; width=&amp;quot;800&amp;quot; height=&amp;quot;530&amp;quot; src=&amp;quot;https://assets.radar.cloudflare.com/blog/q3-2026-internet-disruption-summary/timeline.html&amp;quot; style=&amp;quot;border:0;max-width:100%;height:440px;max-height:440px;&amp;quot;&gt;&lt;/iframe&gt; &lt;/body&gt;&lt;/html&gt;&quot; sandbox=&quot;allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation&quot; title=&quot;Embedded HTML&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;&lt;h2&gt;Power failure was a leading cause&amp;nbsp;of disruptions&lt;/h2&gt;&lt;p&gt;The Internet is designed to be distributed and resilient, but that resilience still depends on electricity. When power fails, routers, mobile base stations, data centers, interconnection facilities, and the networks that connect them can fail with it. Over the past three months, that dependency was one of the clearest patterns in Radar’s disruption data. &lt;strong&gt;Power outages were the second-most common cause of disruptions by incident count this quarter, behind government-directed exam shutdowns. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In Cuba, Internet disruptions followed the erratic patterns of an unstable power grid. Radar observed four power-related outages across the quarter, meaning connectivity was affected by grid failures at least once a month. The outages took place July 6, July 14, August 3, and a three-day blackout from September 18 to 20. The traffic volume decreases ranged from 18% on July 14 to 59% on August 3. &lt;/p&gt;&lt;div id=&quot;html-block-2wfrhvyf3&quot; class=&quot;html-block&quot;&gt;&lt;iframe class=&quot;cf-radar-embed&quot; loading=&quot;lazy&quot; scrolling=&quot;no&quot; style=&quot;border:0;max-width:100%&quot; src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-07-01&amp;amp;dateEnd=2026-09-30&amp;amp;location=cu&amp;amp;ref=%2Ftraffic%2Fcu&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; width=&quot;800&quot; height=&quot;443&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Honduras illustrated how a localized infrastructure failure can produce national-level effects. A power failure on September 10 at an interconnection facility affected at least 11 major providers, showing how concentrated traffic exchange points can become single points of failure. The outage lasted approximately three hours, during which HTTP traffic across the country fell by 63%. &lt;/p&gt;&lt;div id=&quot;html-block-oyzz2w56p&quot; class=&quot;html-block&quot;&gt;&lt;iframe class=&quot;cf-radar-embed&quot; loading=&quot;lazy&quot; scrolling=&quot;no&quot; style=&quot;border:0;max-width:100%&quot; src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-10&amp;amp;dateEnd=2026-09-10&amp;amp;location=hn&amp;amp;ref=%2Ftraffic%2Fhn&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; width=&quot;800&quot; height=&quot;443&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Two notable exceptions were the cross-border provider Telecomunicaciones de Guatemala (AS14754) and mobile carrier Celtel (AS52262), which were unaffected. This suggests that their Honduran connectivity may rely more heavily on infrastructure outside the country.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/TrafficVolumeByAsXY?theme=light&amp;amp;dateStart=2026-09-10&amp;amp;dateEnd=2026-09-10&amp;amp;location=hn&amp;amp;metric=HTTP_REQUESTS&amp;amp;ref=%2Ftraffic%2Fhn&quot; title=&quot;Cloudflare Radar - Traffic volume by autonomous system&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;On July 5, a power outage in Sevastopol, Ukraine, caused an eight-hour blackout, with HTTP traffic dropping by 98%. A little over a month later, on August 12, drone strikes targeting energy infrastructure caused another power outage, resulting in a ten-hour Internet disruption and up to a 95% decline in traffic volume. As discussed in more detail below, geopolitical conflict remains a major driver of Internet disruptions. These incidents also show how conflict, energy infrastructure, and Internet connectivity are fundamentally intertwined.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-07-05&amp;amp;dateEnd=2026-07-06&amp;amp;location=694422&amp;amp;ref=%2Ftraffic%2F694422&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-08-12&amp;amp;dateEnd=2026-08-13&amp;amp;location=694422&amp;amp;ref=%2Ftraffic%2F694422&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Also of note: on August 13, a cooling system failure at a data center in the U.S. city of Phoenix caused a near-total drop in Internet traffic from &lt;a href=&quot;https://radar.cloudflare.com/traffic/as22612?dateStart=2026-08-12&amp;amp;dateEnd=2026-08-14&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Namecheap (AS22612)&lt;/a&gt;. Outages such as these will be important to watch as the role of cooling systems becomes increasingly critical.&lt;/p&gt;&lt;p&gt;Beyond the larger outages in Cuba, Honduras, and Ukraine, power-related disruptions also appeared across a wide range of countries, including Eswatini, Botswana, Tajikistan, Kenya, Saint Lucia, Georgia, and Gabon. Some of these events were caused by sudden failures, while others, such as planned load-shedding in Eswatini, reflected deliberate efforts to manage constrained power supply. Their scale and duration varied, but together they point to the same underlying dependency: when power systems become unstable, Internet connectivity often becomes unstable with them.&lt;strong&gt;&amp;nbsp;In total, Radar observed 14 power-related disruptions across 10 countries during the quarter.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;The physical world takes the virtual world offline&lt;/h2&gt;&lt;p&gt;Last quarter, &lt;a href=&quot;https://blog.cloudflare.com/q2-2026-internet-disruption-summary/#natural-disasters-and-electricity-cause-disruptions-in-guam-venezuela-and-tanzania&quot;&gt;&lt;u&gt;Radar reported&lt;/u&gt;&lt;/a&gt;&amp;nbsp;on the impact of Super Typhoon Sinlaku, as it moved through the Mariana Islands, knocking out power and, in turn, Internet connectivity in Guam, where &lt;a href=&quot;https://radar.cloudflare.com/traffic/gu?dateStart=2026-04-12&amp;amp;dateEnd=2026-04-24#http-traffic&quot;&gt;&lt;u&gt;HTTP traffic took four days to return to typical levels&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Super Typhoon Bavi followed Sinlaku by less than three months, giving Guam two major storm-related connectivity disruptions in a single year. Officials appeared to take earlier preparedness steps ahead of Bavi, including declaring a state of emergency before peak storm conditions. Even so, the storm caused widespread power outages. The &lt;a href=&quot;https://www.kuam.com/story/320286593/gpa-begins-recovery-efforts-as-bavi-causes-widespread-outages&quot;&gt;&lt;u&gt;Guam Power Authority&lt;/u&gt;&lt;/a&gt;&amp;nbsp;reported that strong winds brought down key transmission lines, leaving only about 25% of distribution feeders online at one point. From a connectivity perspective, the outcome was familiar: widespread power outages, downed transmission lines, and a multi-day recovery period for Internet traffic.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-07-04&amp;amp;dateEnd=2026-07-11&amp;amp;location=gu&amp;amp;ref=%2Ftraffic%2Fgu&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;In Japan, an earthquake of similar magnitude, 7.1, prompted evacuation orders affecting roughly &lt;a href=&quot;https://en.philenews.com/international/major-quake-in-southern-japan-knocks-out-power-disrupts-transport/&quot;&gt;&lt;u&gt;150,000 people in Kumamoto&lt;/u&gt;&lt;/a&gt;. The impact on Internet connectivity primarily appeared in desktop traffic, while mobile traffic remained largely unaffected.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 568&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/DataExplorerVisualizer?theme=light&amp;amp;dataset=http&amp;amp;path=http%2Ftimeseries&amp;amp;dateStart=2026-07-27&amp;amp;dateEnd=2026-07-28&amp;amp;mainLocation=1858419&amp;amp;timeCompare=true&amp;amp;param_deviceType=DESKTOP&amp;amp;locale=en-US&amp;amp;ref=%2Fexplorer%3FdataSet%3Dhttp%26loc%3D1858419%26dateStart%3D2026-07-27%26dateEnd%3D2026-07-28%26filters%3DdeviceType%25253DDESKTOP%26timeCompare%3D1&quot; title=&quot;Cloudflare Radar - HTTP requests time series for Kumamoto, Japan&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;In Colombia, a magnitude 7.4 earthquake in August caused building collapses, injuries, mass evacuations, and a four-and-a-half-day Internet disruption. Damage to fiber-optic infrastructure, compounded by the wider earthquake aftermath, drove a &lt;a href=&quot;https://radar.cloudflare.com/traffic/as3816?dateStart=2026-08-13&amp;amp;dateEnd=2026-08-14#http-traffic&quot;&gt;&lt;u&gt;significant drop in traffic from Colombia Telecomunicaciones (AS3816)&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-08-09&amp;amp;dateEnd=2026-08-15&amp;amp;location=co&amp;amp;ref=%2Ftraffic%2Fco&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Finally, in Nepal, sudden flash floods swept through the Bhote Koshi and Trishuli river systems on August 26, affecting communities across Rasuwa, Nuwakot, and Dhading districts. The flooding damaged homes, infrastructure, and essential services, including power, which in turn disrupted regional Internet connectivity. The outage recorded on Radar lasted two hours, during which HTTP traffic dropped by up to 18%.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-08-28&amp;amp;dateEnd=2026-08-28&amp;amp;location=np&amp;amp;ref=%2Ftraffic%2Fnp&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;h2&gt;Exam shutdowns continue in Iraq&lt;/h2&gt;&lt;p&gt;Government-directed shutdowns were the largest cause of disruptions in Q3, the majority of which occurred in Iraq with separate scheduled shutdowns occurring throughout the quarter. The shutdowns took place on a strict schedule&amp;nbsp;03:30–04:00 UTC, lasting about 15-90 min each. The majority occurred between August 26 and September 28, with three occurring between July 1 and 8.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-06-01&amp;amp;dateEnd=2026-09-30&amp;amp;location=iq&amp;amp;ref=%2Ftraffic%2Fiq&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Per &lt;a href=&quot;https://pulse.internetsociety.org/en/shutdowns/exams-shutdown-iraq-28-september-2026/&quot;&gt;&lt;u&gt;Internet Society Pulse&lt;/u&gt;&lt;/a&gt;, “In a &lt;a href=&quot;https://pulse.internetsociety.org/en/shutdowns/exams-shutdown-iraq-28-september-2026/#:~:text=In%20a-,video%20message,-%2C%20Minister%20Mustafa%20Sanad&quot;&gt;&lt;u&gt;video message&lt;/u&gt;&lt;/a&gt;, Minister Mustafa Sanad, Iraq&#39;s Minister of Communication, confirmed the shutdown and vowed to develop a digital system that would eliminate the need for centralized exam distribution and, by extension, the need to shut down Internet access on exam days.” Cloudflare Radar will continue to monitor the country’s networks as the development of the new system progresses.&lt;/p&gt;&lt;p&gt;Notably, Syria and Sudan, two countries that have also frequently used exam-related Internet shutdowns in recent years, did not record similar disruptions this quarter. However, this likely reflects differences in exam calendars rather than a clear shift in policy. Radar will continue to monitor whether future national exam periods bring renewed shutdowns in either country.&lt;/p&gt;&lt;h2&gt;Disruptions coincide with political events &amp;nbsp;&lt;/h2&gt;&lt;p&gt;In Ethiopia, renewed conflict in the Tigray region was accompanied by a government-directed Internet shutdown that lasted 10 days. Traffic dropped by 100%, signaling a full-scale shutdown.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-20&amp;amp;dateEnd=2026-10-08&amp;amp;location=444187&amp;amp;ref=%2Ftraffic%2F444187&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;The disruption revived memories of the extensive blockade imposed during Ethiopia’s civil war from 2020 to 2022, when Tigray was largely cut off from telecommunications, electricity, banking services, fuel, and humanitarian aid (&lt;a href=&quot;https://www.france24.com/en/live-news/20260925-internet-disrupted-in-ethiopia-as-conflict-rages&quot;&gt;&lt;u&gt;France24&lt;/u&gt;&lt;/a&gt;), which the World Health Organization &lt;a href=&quot;https://www.who.int/emergencies/situations/crisis-in-tigray-ethiopia&quot;&gt;&lt;u&gt;described&lt;/u&gt;&lt;/a&gt;&amp;nbsp;as a “de facto blockade.” Although this latest outage appears to have remained localized to Tigray, its impact was still visible in country-level traffic, with HTTP traffic falling by up to 30%.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-20&amp;amp;dateEnd=2026-10-08&amp;amp;location=444187&amp;amp;ref=%2Ftraffic%2F444187&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;On September 19, during nationwide elections, fiber-optic cable damage in Russia’s Far East caused regional connectivity disruptions affecting Chukotka, Magadan Oblast, Kamchatka Krai, and Sakhalin Oblast. Rostelecom &lt;a href=&quot;https://therecord.media/rostelecom-cyberattack-disrupts-russian-internet-access&quot;&gt;&lt;u&gt;described&lt;/u&gt;&lt;/a&gt;&amp;nbsp;the incidents as deliberate damage to backbone fiber lines and said connectivity was restored using backup channels. Radar data alone cannot determine whether the cable damage was related to the elections, but the timing is notable.&lt;/p&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-18&amp;amp;dateEnd=2026-09-20&amp;amp;location=2126099&amp;amp;ref=%2Ftraffic%2F2126099&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-18&amp;amp;dateEnd=2026-09-20&amp;amp;location=2123627&amp;amp;ref=%2Ftraffic%2F2123627&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;emdash-iframe&quot; style=&quot;aspect-ratio: 800 / 443&quot;&gt;&lt;iframe src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-18&amp;amp;dateEnd=2026-09-20&amp;amp;location=2125072&amp;amp;ref=%2Ftraffic%2F2125072&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; sandbox=&quot;allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div id=&quot;html-block-189tgbvv2&quot; class=&quot;html-block&quot;&gt;&lt;iframe class=&quot;cf-radar-embed&quot; width=&quot;800&quot; height=&quot;443&quot; src=&quot;https://radar.cloudflare.com/embed/HttpTrafficXY?theme=light&amp;amp;dateStart=2026-09-18&amp;amp;dateEnd=2026-09-20&amp;amp;location=2121529&amp;amp;ref=%2Ftraffic%2F2121529&quot; title=&quot;Cloudflare Radar - HTTP traffic&quot; loading=&quot;lazy&quot; scrolling=&quot;no&quot; style=&quot;border:0;max-width:100%&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;h2&gt;A quarter shaped by shutdowns and power outages, but also resilience&lt;/h2&gt;&lt;p&gt;Across Q3 2026, government-directed shutdowns were the most frequent source of disruption, driven largely by Iraq’s exam-related shutdowns. Power outages were close behind, affecting networks across Cuba, Honduras, Ukraine, Eswatini, Botswana, Tajikistan, Kenya, Saint Lucia, Georgia, and Gabon. Natural disasters and conflict added another layer of disruption, reminding us that Internet resilience depends on far more than routers and cables. It depends on electricity, physical infrastructure, policy decisions, and the ability of networks to route around failure.&lt;/p&gt;&lt;p&gt;Radar also observed outages inside individual networks, including &lt;a href=&quot;https://radar.cloudflare.com/traffic/as19863?dateStart=2026-09-23&amp;amp;dateEnd=2026-09-24&quot;&gt;&lt;u&gt;One Communications (AS19863)&lt;/u&gt;&lt;/a&gt;&amp;nbsp;in Guyana following a &lt;a href=&quot;https://demerarawaves.com/2026/09/23/one-communications-internet-services-being-restored-repairs-to-continue-tonight/&quot;&gt;&lt;u&gt;cable cut&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://radar.cloudflare.com/traffic/as3243?dateStart=2026-09-13&amp;amp;dateEnd=2026-09-15&quot;&gt;&lt;u&gt;MEO (AS3243) in Portugal&lt;/u&gt;&lt;/a&gt;&amp;nbsp;following a reported “&lt;a href=&quot;https://www.theportugalnews.com/news/2026-09-15/meo-hit-by-cyberattack/1086462&quot;&gt;&lt;u&gt;mass attack&lt;/u&gt;&lt;/a&gt;”, &lt;a href=&quot;https://radar.cloudflare.com/traffic/as27653?dateStart=2026-09-22&amp;amp;dateEnd=2026-09-27&quot;&gt;&lt;u&gt;Digicel Haiti (AS27653)&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://radar.cloudflare.com/traffic/as12735?dateStart=2026-07-30&amp;amp;dateEnd=2026-07-31&quot;&gt;&lt;u&gt;TurkNet (AS12735)&lt;/u&gt;&lt;/a&gt;&amp;nbsp;in Turkey, and &lt;a href=&quot;https://radar.cloudflare.com/traffic/as206065?dateStart=2026-09-27&amp;amp;dateEnd=2026-09-28&quot;&gt;&lt;u&gt;Fanap Telecom (AS206065)&lt;/u&gt;&lt;/a&gt;&amp;nbsp;in Iran.&lt;/p&gt;&lt;p&gt;Each of these events demonstrates the Internet’s fragility, but also its resilience. Many disruptions were brief: 14 saw traffic return to typical levels in under an hour, and 16 recovered in less than three hours. But short outages can still have real consequences for the people affected, especially during storms, earthquakes, conflict, or political unrest. Access to the Internet is often access to information, coordination, safety, and help.&lt;/p&gt;&lt;p&gt;Cloudflare Radar will continue to monitor Internet disruptions around the world and share what we see from Cloudflare’s global network. Follow Cloudflare Radar on X &lt;a href=&quot;https://x.com/CloudflareRadar&quot;&gt;&lt;u&gt;@CloudflareRadar&lt;/u&gt;&lt;/a&gt;&amp;nbsp;and Bluesky &lt;a href=&quot;https://bsky.app/profile/radar.cloudflare.com&quot;&gt;&lt;u&gt;@radar.cloudflare.com&lt;/u&gt;&lt;/a&gt;&amp;nbsp;for updates.&lt;/p&gt;</description>
      <link>https://blog.cloudflare.com/q3-2026-internet-disruption-summary/</link>
      <guid isPermaLink="false">01M5G72REK3978980FNZCPDBRR</guid>
      <pubDate>Tue, 27 Oct 2026 13:00:00 GMT</pubDate>
      <dc:creator>Lai Yi Ohlsen</dc:creator>
      <enclosure url="https://blog.cloudflare.com/_emdash/api/media/file/01KW453HMZRQX1BZKZQMN21EG8.png" length="0" type="image/png"></enclosure>
      <category>Internet Shutdown</category>
      <category>Internet Traffic</category>
      <category>Internet Trends</category>
      <category>Outage</category>
      <category>Radar</category>
    </item>
    <item>
      <title>Cross-request KV cache exposure in the GLM-5.3 Workers AI model, and our remediation with SGLang</title>
      <description>&lt;p&gt;On September 8, 2026, we were alerted by a security researcher, Gadi Evron from &lt;a href=&quot;https://www.knostic.ai/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Knostic&lt;/a&gt;, to a tenant isolation issue affecting the GLM-5.3 Workers AI model (&lt;code&gt;@cf/zai-org/glm-5.3&lt;/code&gt;) starting on August 27, 2026. We have remediated the issue, and we restored the model on September 9. We have confirmed that no other model hosted on Workers AI was affected.&lt;/p&gt;&lt;p&gt;Between August 27 and September 9, a small number of customers using the GLM 5.3 Workers AI model received responses that contained data from other customers&#39; requests made to the same model shortly before theirs. In total, 155 responses were affected, all to prompts longer than 681,280 tokens.&lt;/p&gt;&lt;p&gt;After excluding our own testing and the researcher&#39;s, the requests we identified are consistent in timing and volume with ordinary long-context use, not with someone repeatedly exploiting the bug. We found no evidence of deliberate exploitation.&lt;/p&gt;&lt;p&gt;Today we are publishing this report alongside a post from&amp;nbsp;SGLang, the open-source inference engine that we use, as a coordinated disclosure.&amp;nbsp;This post describes the bug that caused this issue, our response timeline, and the subsequent hardening we have conducted on our production SGLang deployments. We also detail our continued efforts with the upstream maintainers of SGLang to address this and similar bugs.&lt;/p&gt;&lt;h2&gt;What happened&lt;/h2&gt;&lt;p&gt;GLM is a text generation model from &lt;a href=&quot;http://z.ai/&quot;&gt;Z.ai&lt;/a&gt;&amp;nbsp;that is built for agentic coding workflows; it is one of the many &lt;a href=&quot;https://developers.cloudflare.com/workers-ai/models/&quot;&gt;&lt;u&gt;models&lt;/u&gt;&lt;/a&gt;&amp;nbsp;available through Workers AI. Gadi Evron submitted a report on September 8 through our HackerOne program stating that very long prompts sent to &lt;code&gt;@cf/zai-org/glm-5.3&lt;/code&gt;&amp;nbsp;on Workers AI sometimes returned text that belonged to other users&#39; sessions. Cloudflare reproduced the issue the next morning and took the model offline within 40 minutes of declaring an incident. We then deployed a corrected configuration and a patched inference engine, and restored service the same day. &amp;nbsp;&lt;/p&gt;&lt;p&gt;This specific report of cross-request KV cache exposure was the result of two overlapping issues. The first was a misconfiguration of the open-source inference engine, SGLang, used by Cloudflare. We deployed GLM 5.3 with a 1,048,576-token context window, but the KV cache pool on our prefill GPUs only had room for 681,280 tokens. We were aware of this mismatch before launch. We expected the engine to return an error for any prompt it could not process, and our long-context tests returned successful responses, so we did not believe this to be an issue.&lt;/p&gt;&lt;p&gt;The second was a bug in how SGLang handled the resulting over-length requests in disaggregated prefill/decode mode. A prompt that did not fit the pool was internally marked as rejected and replaced with a one-token placeholder, but instead of aborting the request and returning a client error, prefill generated the KV cache for the placeholder prompt and transferred it to the decode node. The decode node received a &quot;transfer complete&quot; message and assumed that prefill overwrote the KV cache from previous requests with the full prompt for this request, when in fact it left the majority of the previous state intact. The decode node subsequently generated a response while attending over stale cache pages that still held data from earlier requests. As a result, responses to prompts longer than 681,280 tokens could contain data from other users&#39; GLM 5.3 sessions.&lt;/p&gt;&lt;h2&gt;Immediate remediation&lt;/h2&gt;&lt;p&gt;After &lt;a href=&quot;https://www.cloudflarestatus.com/incidents/jsvvrtk5hvym&quot;&gt;&lt;u&gt;disabling the model&lt;/u&gt;&lt;/a&gt;, we took the following actions to correct this vulnerability before restoring public access to it:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;To fix our configuration, we made the pool hold the full context.&lt;/strong&gt;&amp;nbsp;We adjusted our GLM 5.3 configuration to match our GLM 5.2 configuration, which freed enough GPU memory that the prefill KV pool now holds about 2.04 million tokens, roughly twice the 1,048,576-token context length. A prompt that fits the context window now always fits the pool, so the rejection path is never reached for a valid request. This alone prevents the bug from being exercised.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;To fix the engine, we also made the rejection path safe.&lt;/strong&gt;&amp;nbsp;Relying on pool size alone is fragile: any change to quantization, tensor parallelism, CUDA graph sizes, or a future model version changes the pool size in a way that&#39;s easy to miss. Furthermore, there may be other situations in which the prefill scheduler can reject a request and trigger the same bug. To prevent this, we also patched the engine so that a request carrying a pending rejection is retired at the disaggregation admission queue, with its original error, before any bootstrap, allocation, or KV transfer happens. We proposed this upstream as &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38704&quot;&gt;&lt;u&gt;#38704&lt;/u&gt;&lt;/a&gt;, which also had the decode node verify that the number of tokens transferred matches the number it reserved. The fix was already on SGLang &lt;code&gt;main&lt;/code&gt; in &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/36988&quot;&gt;&lt;u&gt;#36988&lt;/u&gt;&lt;/a&gt;, merged September 6 for a related failure path but not yet released. The maintainers also merged &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38935&quot;&gt;&lt;u&gt;#38935&lt;/u&gt;&lt;/a&gt;, which rejects these requests earlier, following our approach.&lt;/p&gt;&lt;p&gt;We validated both changes against the researcher&#39;s reproduction script and our own canary-marker tests before restoring the model.&lt;/p&gt;&lt;h2&gt;Background: how we serve GLM 5.3&lt;/h2&gt;&lt;p&gt;Workers AI runs GLM 5.3 with SGLang in a disaggregated configuration: a pool of prefill GPUs processes the prompt and produces the model&#39;s KV cache for it, then hands that cache over remote direct memory access (RDMA), via &lt;a href=&quot;https://kvcache-ai.github.io/Mooncake/&quot;&gt;Mooncake&lt;/a&gt;, to a pool of decode GPUs that generate the response. We have written about this architecture before in our posts on &lt;a href=&quot;https://blog.cloudflare.com/high-performance-llms/&quot;&gt;&lt;u&gt;high-performance LLMs&lt;/u&gt;&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;https://blog.cloudflare.com/smaller-faster-safer-models/&quot;&gt;&lt;u&gt;smaller, faster, safer models&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The KV cache in GPU memory is a shared pool of fixed-size pages. Each request is assigned pages when it is admitted and releases them when it finishes. Pages are not currently zeroed between requests; the next request that gets a page simply overwrites it. This approach is common among inference engines and is necessary to achieve the best performance, but it means that the inference engine is responsible for tracking ownership of these memory pages. KV cache page ownership and lifetime tracking has to deal with not just shared ownership within a node (KV cache offload and token generation both access the memory with different lifetimes), but also ownership that is technically shared with the remote prefill node (which holds a simultaneous mutable reference to the page).&lt;/p&gt;&lt;p&gt;Furthermore, the size of this pool is not a configuration value. SGLang sizes it at startup from whatever GPU memory remains after loading the model weights. The model&#39;s advertised context length is a separate configuration value. Nothing forces the two to agree, and it is our job to check that they do.&lt;/p&gt;&lt;h2&gt;Issue one: misconfiguration&lt;/h2&gt;&lt;p&gt;On our GLM 5.3 prefill nodes with our configuration, the pool came to 681,280 tokens while the model&#39;s context length is 1,048,576 tokens. The selected KV pool size is printed by SGLang in logs during startup and exposed as a metric. We were aware of this size mismatch; however, during pre-launch testing we observed successful HTTP status codes and a streaming body with no error frames during benchmarking. We assumed that the engine was capable of gracefully handling the difference between the KV cache pool and requested context window via streaming or some other mechanism.&lt;/p&gt;&lt;p&gt;This was one critical gap in our testing: we only validated HTTP response codes and engine performance at long contexts, without validating model output and coherence.&amp;nbsp;We now check KV pool size against context length directly, from the running engine, before any disaggregated deployment change ships, rather than inferring it from response codes.&lt;/p&gt;&lt;h2&gt;Issue two: SGLang bug&lt;/h2&gt;&lt;p&gt;In v0.5.21, the SGLang team has now addressed this bug in how it was handling prompts longer than the KV pool size. Here’s what was happening before.&lt;/p&gt;&lt;p&gt;When a prompt arrived that was longer than the KV pool could hold, SGLang&#39;s scheduler rejected it. The rejection path (&lt;code&gt;Req.set_finish_with_abort&lt;/code&gt;) recorded the error to be returned to the client and swapped the prompt for a one-token placeholder so that the request could drain through the normal batch machinery without allocating real memory. On a single-node deployment this worked: the placeholder ran, the batch finished, and the client received an error.&lt;/p&gt;&lt;figure class=&quot;emdash-image pt-portable-image&quot;&gt;&lt;div class=&quot;pt-portable-image-frame&quot; data-image-placeholder-frame=&quot;&quot;&gt;&lt;img src=&quot;https://blog.cloudflare.com/_emdash/api/media/file/01M5X2P3TSRNGJ0SWD3QV77X5X.png&quot; alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; data-image-placeholder-media=&quot;true&quot; data-lightbox-src=&quot;/_image?href=https%3A%2F%2Fblog.cloudflare.com%2F_emdash%2Fapi%2Fmedia%2Ffile%2F01M5X2P3TSRNGJ0SWD3QV77X5X.png&amp;amp;w=1280&amp;amp;h=1120&amp;amp;q=100&amp;amp;f=webp&quot; data-lightbox-width=&quot;1280&quot; data-lightbox-height=&quot;1120&quot; sizes=&quot;(min-width: 715px) 715px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-fit=&quot;cover&quot; data-astro-image-pos=&quot;center&quot; width=&quot;715&quot; height=&quot;626&quot; class=&quot;pt-portable-image-media&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p&gt;In disaggregated mode&amp;nbsp;such as we operate, the admission queues on both prefill and decode checked whether a request was &lt;em&gt;finished&lt;/em&gt;, not whether it was &lt;em&gt;rejected&lt;/em&gt;. A rejected request reported itself as live. So:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Bootstrap.&lt;/strong&gt;&amp;nbsp;The router told the decode node the prompt length (8 pages in the diagram). Decode reserved 8 KV pages for the request.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Prefill admission.&lt;/strong&gt;&amp;nbsp;The prefill admission queue admitted any request where &lt;code&gt;req.finished()&lt;/code&gt;&amp;nbsp;was False. A rejected request stored its rejection in &lt;code&gt;to_finish&lt;/code&gt;, not &lt;code&gt;finished_reason&lt;/code&gt;, so &lt;code&gt;finished()&lt;/code&gt;&amp;nbsp;still returned False. The rejected request was admitted.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Prefill forward pass.&lt;/strong&gt;&amp;nbsp;Rejection had already replaced the prompt with a one-token placeholder. Prefill ran a trivial forward pass on that one token.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;KV transfer.&lt;/strong&gt;&amp;nbsp;Prefill sent one page of KV to decode and signaled that the transfer was complete.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Decode admission.&lt;/strong&gt;&amp;nbsp;Decode&#39;s admission queue had the same &lt;code&gt;finished()&lt;/code&gt;&amp;nbsp;check, so it accepted the handoff.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Decode attention.&lt;/strong&gt;&amp;nbsp;Decode started generating and attention read all 8 reserved pages. Only page P0 had been written by this request. Pages P1 to P7 still held what earlier requests left in them: other users&#39; prompts and partial generations.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Response.&lt;/strong&gt;&amp;nbsp;The client got HTTP 200 instead of HTTP 400. &lt;code&gt;prompt_tokens&lt;/code&gt;&amp;nbsp;matched the long prompt and the reply was coherent. It arrived faster than an 8-page prefill should take, and it contained content from other users&#39; KV pages.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Every request over the threshold behaved this way. This bug had been reported to SGLang by another user as issue &lt;a href=&quot;https://github.com/sgl-project/sglang/issues/30233&quot;&gt;&lt;u&gt;#30233&lt;/u&gt;&lt;/a&gt;&amp;nbsp;on July 6, 2026, which Cloudflare noticed while investigating this incident. We had been flagging these types of issues with SGLang since v0.5.10 and this security incident sped up work that Cloudflare had already started in collaboration with the SGLang team. The patch for this issue was released in SGLang v0.5.20, with follow-ups in v0.5.21 and v0.5.22, and is available for all other operators dependent on SGLang to use. We highly recommend all operators update SGLang dependencies to v0.5.22 or later. For more details on specific PRs, read on below.&lt;/p&gt;&lt;p&gt;GLM 5.3 was the only model affected by this bug. Every other disaggregated deployment on Workers AI has KV pools larger than its context length on both prefill and decode, so no request could reach the rejection path. We have applied the engine fix and the hardening described below to every model we serve with SGLang, and our deployment checks require them for every new deployment.&lt;/p&gt;&lt;h2&gt;Timeline&lt;/h2&gt;&lt;p&gt;All times UTC.&lt;/p&gt;&lt;div class=&quot;emdash-table-wrapper&quot;&gt;&lt;table class=&quot;emdash-table&quot; style=&quot;min-width: 192px;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;When&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;What&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Aug 27, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;GLM 5.3 launched on Workers AI with a prefill KV pool smaller than its context window. The exposure was present from launch.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 8, 2026 - 23:11&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Report received via HackerOne.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 08:00&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Cloudflare begins verifying the HackerOne report.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 13:22&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Security incident declared. Product Security reproduced the leak using two independent accounts within 25 minutes.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 14:00&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;After confirming the scope of the issue, GLM 5.3 was set&amp;nbsp;to private. Requests return HTTP 400. Status page updated.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 14:35&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Root cause identified as the prefill pool being smaller than the context length. Canary prefill node with a larger pool confirmed not susceptible.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 14:52&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;All prefill nodes rolled to the corrected configuration.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 19:04&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Full deployment rebuilt with the corrected configuration plus a Cloudflare-authored engine patch that correctly returns errors for requests rejected by the prefill scheduler. Validated against the researcher&#39;s reproduction script.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 9, 2026 - 19:40&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Model restored to public.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 10, 2026&amp;nbsp;- 23:30&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Meeting with the SGLang maintainers (RadixArk CTO and core engineers) to agree on upstream fixes.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 11-19, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Additional hardening rolled to all production SGLang deployments (details below).&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Sep 16-Oct 12, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Upstream SGLang merges the admission fix, per-transfer checksums, abort-ACK preservation, and turns deferred KV release on by default.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Oct 2, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;SGLang v0.5.21 released.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Oct 19, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;SGLang v0.5.22 released.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Oct 26, 2026&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Coordinated publication with the researcher and RadixArk.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h2&gt;Ongoing hardening effort&lt;/h2&gt;&lt;p&gt;This bug belongs to a class of KV cache memory-safety bugs that Cloudflare has been working to address for several months. In each case, a page is freed, reused, or read while something else still has a claim on it. We see two common causes.&lt;/p&gt;&lt;p&gt;The first is page lifetime within a single node. Several tasks on a decode node can hold the same page at once: token generation, offload to host memory, the KV transfer receiver, and the abort and error paths. If one of them frees the page while another is still using it, a new request can be given that page while it is still being read or written. Our earlier fixes for decode offload (&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/24226&quot;&gt;&lt;u&gt;#24226&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/30899&quot;&gt;&lt;u&gt;#30899&lt;/u&gt;&lt;/a&gt;) and double release on grammar errors (&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/30937&quot;&gt;&lt;u&gt;#30937&lt;/u&gt;&lt;/a&gt;) were of this kind.&lt;/p&gt;&lt;p&gt;The second is a race across nodes. When a request is aborted while prefill is still writing its KV cache to decode over RDMA, the writes already sent cannot be recalled. If decode frees those pages right away, those pages can be given to another request, and the late writes land in that request&#39;s KV cache. Cloudflare has contributed to the effort to fix this race through proposed fixes (&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/31357&quot;&gt;&lt;u&gt;#31357&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38961&quot;&gt;&lt;u&gt;#38961&lt;/u&gt;&lt;/a&gt;) and a reproduction script (&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/32564&quot;&gt;&lt;u&gt;#32564&lt;/u&gt;&lt;/a&gt;). In both cases the result is corrupted output, or one user&#39;s data in another user&#39;s response, with no error raised. The bug in this incident was different: a rejected request went through the handoff every time, rather than by a timing accident. But it had the same result: decode reading pages this request never wrote. None of these covered the failure in this incident in which prefill rejected the request, and decode never learned of it.&lt;/p&gt;&lt;p&gt;Since the incident, we have:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Extended deferred release to hold prefill&#39;s source pages as well, and to cover every failure type, not just aborts. We proposed it upstream as &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38961&quot;&gt;&lt;u&gt;#38961&lt;/u&gt;&lt;/a&gt;, which was superseded by &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/40645&quot;&gt;&lt;u&gt;#40645&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/41402&quot;&gt;&lt;u&gt;#41402&lt;/u&gt;&lt;/a&gt;, and &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/41404&quot;&gt;&lt;u&gt;#41404&lt;/u&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Deployed bounded Mooncake transfer batches (&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/32758&quot;&gt;&lt;u&gt;#32758&lt;/u&gt;&lt;/a&gt;, from the SGLang community), so no single transfer call can outlast the release timeout.&lt;/li&gt;&lt;li&gt;Changed our load balancer so a client disconnect no longer aborts a request mid-transfer. It holds the prefill connection until prefill finishes and the decode connection until the first token, then closes both.&lt;/li&gt;&lt;li&gt;Added a check to every disaggregated deployment change: KV pool size measured against context length, deferred release on both roles, transfer batch bounds inside the release timeout, and all required patches applied.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All of these changes were released to our disaggregated production deployments.&lt;/p&gt;&lt;h2&gt;Working with the SGLang team&lt;/h2&gt;&lt;p&gt;We met with the SGLang maintainers at RadixArk on September 10, the day after the incident. We agreed that RadixArk would investigate the race conditions we had reported, upstream the integrity-checking idea, and build reproduction tests for this class of bug.&lt;/p&gt;&lt;p&gt;The following have landed on SGLang &lt;code&gt;main&lt;/code&gt; to address this incident and related KV cache race conditions, and all but one are included in v0.5.22. Operators running disaggregated SGLang should update to v0.5.22 or backport these patches as needed.&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;emdash-table-wrapper&quot;&gt;&lt;table class=&quot;emdash-table&quot; style=&quot;min-width: 384px;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Category&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Pull request&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Release&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;What it does&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Incident&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/36988&quot;&gt;#36988&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;v0.5.20&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Retires aborted prefill requests before their result reaches decode. This stops the exposure in this incident.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Incident&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38935&quot;&gt;#38935&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;v0.5.21&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;Rejects these requests at admission, before any bootstrap, allocation, or KV transfer. Follows the approach in Cloudflare&#39;s draft patch, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/38704&quot;&gt;#38704&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Race&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/39461&quot;&gt;#39461&lt;/a&gt;, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/41612&quot;&gt;#41612&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;v0.5.21, v0.5.22&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;code&gt;sgl-router&lt;/code&gt;&amp;nbsp;cancels both halves of a request on client disconnect or prefill failure.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Race&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/sgl-project/sglang/pull/37454&quot;&gt;#37454&lt;/a&gt;, &lt;a href=&quot;https://github.com/sgl-project/sglang/pull/410

@TonyRL
TonyRL merged commit 97fb1f5 into DIYgod:master Oct 29, 2026
42 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto: ready to review Human review will come in after lint issues and merge conflicts are fixed route

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants