
<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, 04 Apr 2026 11:31:06 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Protection against CVE-2021-45046, the additional Log4j RCE vulnerability]]></title>
            <link>https://blog.cloudflare.com/protection-against-cve-2021-45046-the-additional-log4j-rce-vulnerability/</link>
            <pubDate>Wed, 15 Dec 2021 13:56:13 GMT</pubDate>
            <description><![CDATA[ This vulnerability is actively being exploited and anyone using Log4J should update to version 2.16.0 as soon as possible. Latest version is available on the Log4J download page. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Hot on the heels of CVE-2021-44228 a second Log4J CVE has been filed <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-45046">CVE-2021-45046</a>. The rules that we <a href="/cve-2021-44228-log4j-rce-0-day-mitigation/">previously released for CVE-2021-44228</a> give the same level of protection for this new CVE.</p><p>This vulnerability is actively being exploited and anyone using Log4J should update to version <b>2.16.0</b> as soon as possible, even if you have previously updated to 2.15.0. The latest version can be found on the <a href="https://logging.apache.org/log4j/2.x/download.html">Log4J download page</a>.</p><p>Customers using the Cloudflare WAF have three rules to help mitigate any exploit attempts:</p><table><tr><td><p><b>Rule ID</b></p></td><td><p><b>Description</b></p></td><td><p><b>Default Action</b></p></td></tr><tr><td><p><code>100514 </code>(legacy WAF)
<code>6b1cc72dff9746469d4695a474430f12</code>(new WAF)</p></td><td><p>Log4J Headers</p></td><td><p><code>BLOCK</code></p></td></tr><tr><td><p><code>100515 </code>(legacy WAF)
<code>0c054d4e4dd5455c9ff8f01efe5abb10 </code>(new WAF)</p></td><td><p>Log4J Body</p></td><td><p><code>BLOCK</code></p></td></tr><tr><td><p><code>100516 </code>(legacy WAF)
<code>5f6744fa026a4638bda5b3d7d5e015dd </code>(new WAF)</p></td><td><p>Log4J URL</p></td><td><p><code>BLOCK</code></p></td></tr></table><p>The mitigation has been split across three rules inspecting HTTP headers, body and URL respectively.</p><p>In addition to the above rules we have also released a fourth rule that will protect against a much wider range of attacks at the cost of a higher false positive rate. For that reason we have made it available but not set it to <code>BLOCK</code> by default:</p><table><tr><td><p><b>Rule ID</b></p></td><td><p><b>Description</b></p></td><td><p><b>Default Action</b></p></td></tr><tr><td><p><code>100517 </code>(legacy WAF)
<code>2c5413e155db4365befe0df160ba67d7 </code>(new WAF)</p></td><td><p>Log4J Advanced URI, Headers</p></td><td><p><code>DISABLED</code></p></td></tr></table>
    <div>
      <h3>Who is affected</h3>
      <a href="#who-is-affected">
        
      </a>
    </div>
    <p>Log4J is a powerful Java-based logging library maintained by the Apache Software Foundation.</p><p>In all Log4J versions &gt;= 2.0-beta9 and ← 2.14.1 JNDI features used in configuration, log messages, and parameters can be exploited by an attacker to perform <a href="https://www.cloudflare.com/learning/security/what-is-remote-code-execution/">remote code execution</a>. Specifically, an attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.</p><p>In addition, the previous mitigations for CVE-2021-22448 as seen in version 2.15.0 were not adequate to protect against CVE-2021-45046.</p> ]]></content:encoded>
            <category><![CDATA[Log4J]]></category>
            <category><![CDATA[Log4Shell]]></category>
            <category><![CDATA[WAF Rules]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <guid isPermaLink="false">6pspqKqlsP5qiWZ0SPJahl</guid>
            <dc:creator>Gabriel Gabor</dc:creator>
            <dc:creator>Andre Bluehs</dc:creator>
        </item>
        <item>
            <title><![CDATA[CVE-2021-44228 - Log4j RCE 0-day mitigation]]></title>
            <link>https://blog.cloudflare.com/cve-2021-44228-log4j-rce-0-day-mitigation/</link>
            <pubDate>Fri, 10 Dec 2021 11:39:08 GMT</pubDate>
            <description><![CDATA[ A zero-day exploit affecting the popular Apache Log4j utility (CVE-2021-44228) was made public on December 9, 2021, that results in remote code execution (RCE). ]]></description>
            <content:encoded><![CDATA[ <p></p><p><i>Update: all three WAF rules have now been configured with a default action of </i><code><i>BLOCK</i></code><i>.</i></p><p>A zero-day exploit affecting the popular <a href="https://logging.apache.org/log4j/2.x/index.html">Apache Log4j utility</a> (<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228">CVE-2021-44228</a>) was made public on December 9, 2021, that results in <a href="https://www.cloudflare.com/learning/security/what-is-remote-code-execution/">remote code execution (RCE)</a>.</p><p>This vulnerability is actively being exploited and anyone using Log4j should update to version 2.15.0 as soon as possible. The latest version can already be found on the <a href="https://logging.apache.org/log4j/2.x/download.html">Log4j download page</a>.</p><p>If updating to the latest version is not possible the vulnerability can be mitigated by removing the JndiLookup class from the class path. Additionally, the issue can be mitigated on Log4j versions &gt;=2.10 by setting the system property <code>log4j2.formatMsgNoLookups</code> or the <code>LOG4J_FORMAT_MSG_NO_LOOKUPS</code> environment variable to <code>true</code>.</p><p>Customers using the Cloudflare WAF can also leverage three newly deployed rules to help mitigate any exploit attempts:</p><table><tr><td><p><b>Rule ID</b></p></td><td><p><b>Description</b></p></td><td><p><b>Default Action</b></p></td></tr><tr><td><p><code>100514 </code>(legacy WAF)
<code>6b1cc72dff9746469d4695a474430f12 </code>(new WAF)</p></td><td><p>Log4j Headers</p></td><td><p><code>BLOCK</code></p></td></tr><tr><td><p><code>100515 </code>(legacy WAF)
<code>0c054d4e4dd5455c9ff8f01efe5abb10 </code>(new WAF)</p></td><td><p>Log4j Body</p></td><td><p><code>BLOCK</code></p></td></tr><tr><td><p><code>100516 </code>(legacy WAF)
<code>5f6744fa026a4638bda5b3d7d5e015dd </code>(new WAF)</p></td><td><p>Log4j URL</p></td><td><p><code>BLOCK</code></p></td></tr></table><p>The mitigation has been split across three rules inspecting HTTP headers, body and URL respectively.</p><p>We are continuing to monitor the situation and will update any WAF managed rules accordingly.</p><p>More details on the vulnerability can be found on the official <a href="https://logging.apache.org/log4j/2.x/security.html">Log4j security page</a>.</p>
    <div>
      <h3>Who is affected</h3>
      <a href="#who-is-affected">
        
      </a>
    </div>
    <p>Log4j is a powerful Java based logging library maintained by the Apache Software Foundation.</p><p>In all Log4j versions &gt;= 2.0-beta9 and ← 2.14.1 JNDI features used in configuration, log messages, and parameters can be exploited by an attacker to perform remote code execution. Specifically, an attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.</p> ]]></content:encoded>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[Zero Day Threats]]></category>
            <category><![CDATA[WAF Rules]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Log4J]]></category>
            <category><![CDATA[Log4Shell]]></category>
            <guid isPermaLink="false">UBMongwawwkY03LMVbocf</guid>
            <dc:creator>Gabriel Gabor</dc:creator>
            <dc:creator>Andre Bluehs</dc:creator>
        </item>
        <item>
            <title><![CDATA[Using HPKE to Encrypt Request Payloads]]></title>
            <link>https://blog.cloudflare.com/using-hpke-to-encrypt-request-payloads/</link>
            <pubDate>Fri, 19 Feb 2021 12:00:00 GMT</pubDate>
            <description><![CDATA[ Allowing users to securely log parts of the request that match firewall rules while making it impossible for anyone else to decrypt. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Managed Rules team was recently given the task of allowing Enterprise users to <a href="/encrypt-waf-payloads-hpke/">debug Firewall Rules</a> by viewing the part of a request that matched the rule. This makes it easier to determine what specific attacks a rule is stopping or why a request was a false positive, and what possible refinements of a rule could improve it.</p><p>The fundamental problem, though, was how to securely store this debugging data as it may contain sensitive data such as personally identifiable information from submissions, cookies, and other parts of the request. We needed to store this data in such a way that <b>only</b> the user who is allowed to access it can do so. Even Cloudflare shouldn't be able to see the data, following our philosophy that any personally identifiable information that passes through our network is a <a href="/welcome-to-privacy-and-compliance-week/">toxic asset</a>.</p><p>This means we needed to encrypt the data in such a way that we can allow the user to decrypt it, but not Cloudflare. This means <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/">public key encryption</a>.</p><p>Now we needed to decide on which encryption algorithm to use. We came up with some questions to help us evaluate which one to use:</p><ul><li><p>What requirements do we have for the algorithm?</p></li><li><p>What language do we implement it in?</p></li><li><p>How do we make this as secure as possible for users?</p></li></ul><p>Here's how we made those decisions.</p>
    <div>
      <h3>Algorithm Requirements</h3>
      <a href="#algorithm-requirements">
        
      </a>
    </div>
    <p>While we knew we needed to use <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/">public key encryption</a>, we also needed to keep an eye on performance. This led us to select <a href="https://tools.ietf.org/html/draft-irtf-cfrg-hpke-06">Hybrid Public Key Encryption</a> (HPKE) early on as it has a best-of-both-worlds approach to using symmetric as well as public-key cryptography to increase performance. While these best-of-both-worlds schemes aren’t new [<a href="https://nacl.cr.yp.to/box.html">1</a>][<a href="https://github.com/google/tink">2</a>][<a href="https://age-encryption.org/">3</a>], HPKE aims to provide a single, future-proof, robust, interoperable combination of a general key encapsulation mechanism and a symmetric encryption algorithm.</p><p>HPKE is an emerging standard developed by the Crypto Forum Research Group (CFRG), the research body that supports the development of Internet standards at the <a href="http://ietf.org">IETF. The CFRG</a> produces specifications called RFCs (such as <a href="https://tools.ietf.org/html/rfc7748">RFC 7748</a> for elliptic curves) that are then used in higher level protocols including two we talked about previously: <a href="/oblivious-dns/">ODoH</a> and <a href="/encrypted-client-hello/">ECH</a>. Cloudflare has long been a supporter of Internet standards, so HPKE was a natural choice to use for this feature. Additionally, HPKE was co-authored by one of our colleagues at Cloudflare.</p>
    <div>
      <h3>How HPKE Works</h3>
      <a href="#how-hpke-works">
        
      </a>
    </div>
    <p>HPKE combines an asymmetric algorithm such as <a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">elliptic curve Diffie-Hellman</a> and a symmetric cipher such as AES. One of the upsides of HPKE is that the algorithms aren't dictated to the implementer, but making a combination that’s <a href="https://en.wikipedia.org/wiki/Provable_security#In_cryptography">provably secure</a> and meets the developer’s intuitive notions of security is important. All too often developers reach for a scheme without carefully understanding what it does, resulting in security vulnerabilities.</p><p>HPKE solves these problems by providing a high level of security in a generic manner and providing necessary hooks to tie messages to the context in which they are generated. This is the application of decades of research into the correct security notions and schemes.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/d6wSZdRKA3sg9R7181Rc3/6f61f19999611103d51ee2f394caa00d/image2-13.png" />
            
            </figure><p>HPKE is built in stages. First it turns a Diffie-Hellman key agreement into a Key Encapsulation Mechanism. A key encapsulation mechanism has two algorithms: Encap and Decap. The Encap algorithm creates a symmetric secret and wraps it in a public key, so that only the holder of the private key can unwrap it. An attacker with the encapsulation cannot recover the random key. Decap takes the encapsulation and the private key associated to the public key, and computes the same random key. This translation gives HPKE the flexibility to work almost unchanged with any kind of public key encryption or key agreement algorithm.</p><p>HPKE mixes this key with an optional info argument, as well as information relating to the cryptographic parameters used by each side. This ensures that attackers cannot modify messages’ meaning by taking them out of context. A postcard marked “So happy to see you again soon” is ominous from the dentist and endearing from one’s grandmother.</p><p>The specification for HPKE is open and available on the <a href="https://tools.ietf.org/html/draft-irtf-cfrg-hpke-06">IETF website</a>. It is on its way to becoming an RFC after passing multiple rounds of review and analysis by cryptography experts at the CFRG. HPKE is already gaining adoption in IETF protocols like ODoH, ECH, and the new <a href="https://messaginglayersecurity.rocks/">Messaging Layer Security (MLS)</a> protocol. HPKE is also designed with the <a href="/securing-the-post-quantum-world/">post-quantum future</a> since it is built to work with any KEM, including <a href="https://csrc.nist.gov/News/2020/pqc-third-round-candidate-announcement">all the NIST finalists for post-quantum</a> public-key encryption.</p>
    <div>
      <h3>Implementation Language</h3>
      <a href="#implementation-language">
        
      </a>
    </div>
    <p>Once we had an encryption scheme selected, we needed to settle on an implementation. HPKE is still fairly new, so the libraries aren't quite mature yet. There is a <a href="https://github.com/cisco/go-hpke">reference implementation</a>, and we’re in the process of developing an implementation in Go as part of <a href="https://github.com/cloudflare/circl">CIRCL</a>. However, in the absence of a clear "go to" that is widely known to be the best, we decided to go with <a href="https://github.com/rozbb/rust-hpke">an implementation</a> leveraging the same language already powering much of the Firewall code running at the Cloudflare edge - <a href="/building-fast-interpreters-in-rust/">Rust</a>.</p><p>Aside from this, the language benefits from features like native primitives, and crucially the ability to easily compile to <a href="https://developer.mozilla.org/en-US/docs/WebAssembly">WebAssembly (WASM)</a>.</p><p>As we mentioned in a <a href="/encrypt-waf-payloads-hpke/">previous blog post</a>, customers are able to generate a key pair and decrypt payloads either from the dashboard UI or from a CLI. Instead of writing and maintaining two different codebases for these, we opted to reuse the same implementation across the edge component that encrypts the payloads and the UI and CLI that decrypt them. To achieve this we compile our library to target WASM so it can be used in the dashboard UI code that runs in the browser. While this approach may yield a slightly larger JavaScript bundle size and relatively small computational overhead, we found it preferable to spending a significant amount of time securely re-implementing HPKE using JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API">WebCrypto</a> primitives.</p><p>The HPKE implementation we decided on comes with the caveat of not yet being formally audited, so we performed our own internal security review. We analyzed the cryptography primitives being used and the corresponding libraries. Between the composition of said primitives and secure programming practices like correctly zeroing memory and safe usage of random number generators, we found no security issues.</p>
    <div>
      <h3>Making It Secure For Users</h3>
      <a href="#making-it-secure-for-users">
        
      </a>
    </div>
    <p>To encrypt on behalf of users, we need them to provide us with a public key. To make this as easy as possible, we built a CLI tool along with the ability to do it right in the browser. Either option allows the user to generate a public/private key pair without needing to talk to Cloudflare servers at all.</p><p>In our API, we specifically do not accept the private key of the key pair — we don't want it! We don't need and don't want to be able to decrypt the data we're storing.</p><p>For the dashboard, once the user provides the private key for decryption, the key is held in a temporary JavaScript variable and used for the in-browser decryption. This allows the user to not constantly have to provide the key while browsing the Firewall event logs. The private key is also not persisted in any way in the browser, so any action that refreshes the page such as refreshing or navigating away will require the user to provide the key again. We believe this is an acceptable usability compromise for better security.</p>
    <div>
      <h3>How Payload Extraction Works</h3>
      <a href="#how-payload-extraction-works">
        
      </a>
    </div>
    <p>After deciding how to encrypt the data, we just had to figure out the rest of the feature: what data to encrypt, how to store and transmit it, and how to allow users to decrypt it.</p><p>When an HTTP request reaches the L7 Firewall, it is evaluated against a set of rulesets. Each of these rulesets contain several rules written in the <a href="https://github.com/cloudflare/wirefilter">wirefilter</a> syntax.</p><p>An example of one such rule would be:</p>
            <pre><code>http.request.version eq "HTTP/1.1"
and
(
    http.request.uri.path matches "\n+."
    or
    http.request.uri.query matches "\x00+."
)</code></pre>
            <p>This expression evaluates to a boolean “true” for HTTP/1.1 requests that either contain one or more newlines followed by a character in the request path or one or more NULL bytes followed by a character in the query string.</p><p>Say we had the following request that would match the rule above:</p>
            <pre><code>GET /cms/%0Aadmin?action=%00post HTTP/1.1
Host: example.com</code></pre>
            <p>If matched data logging is enabled, the rules that match would be executed again in a special context that tags all fields that are accessed during execution. We do this second execution because this tagging adds a noticeable computational overhead, and since the vast majority of requests don't trigger a rule at all we would be unnecessarily adding overhead to each request. Requests that do match any rules will only match a few rules as well, so we don't need to re-execute a large portion of the ruleset.</p><p>You may notice that although <code>http.request.uri.query matches "\x00+."</code> evaluates to <code>true</code> for this request, it won’t be executed, because the expression short-circuits with the first <code>or</code> condition that also matches. This results in only <code>http.request.version</code> and <code>http.request.uri.path</code> being tagged as accessed:</p>
            <pre><code>http.request.version -&gt; HTTP/1.1
http.request.uri.path -&gt; /cms/%0Aadmin</code></pre>
            <p>Having gathered the fields that were accessed, the Firewall engine does some post-processing; removing fields that are a subset of others (e.g., the query string and the full URI), or truncating fields that are beyond a certain character length.</p><p>Finally, these get serialized as JSON, encrypted with the customer's public key, serialized again as a set of bytes, and prefixed with a version number should we need to change/update it in the future. To simplify consumption of these blobs, our APIs display a base64 encoded version of the bytes:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3GszxT7kezPhIz3olZ7NRG/5e5468f1d414682c3279c9f427c92dfa/image3-8.png" />
            
            </figure><p>Now that we have encrypted the data at the edge and persisted it in <a href="/tag/clickhouse/">ClickHouse</a>, we need to allow users to decrypt it. As part of the setup of turning this feature on, users generated a key-pair: the public key which was used to encrypt the payloads and a private key which is used to decrypt them. Decryption is done completely offline via either the command line using <a href="https://github.com/cloudflare/matched-data-cli">cloudflare/matched-data-cli</a>:</p>
            <pre><code>$ MATCHED_DATA=AkjQDktMX4FudxeQhwa0UPNezhkgLAUbkglNQ8XVCHYqPgAAAAAAAACox6cEwqWQpFVE2gCFyOFsSdm2hCoE0/oWKXZJGa5UPd5mWSRxNctuXNtU32hcYNR/azLjsGO668Jwk+qCdFvmKjEqEMJgI+fvhwLQmm4=
$ matched-data-cli decrypt -d $MATCHED_DATA -k $PRIVATE_KEY
{"http.request.version": "HTTP/1.1", "http.request.uri.path": "/cms/%0Aadmin"}</code></pre>
            <p>Or the dashboard UI:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4S6H5u9SqEUrWDRRnYnCS/18a59db043aab89967c898bf87185151/image1-7.png" />
            
            </figure><p>Since our CLI tool is open-source and HPKE is interoperable, it can also be used in other tooling as part of a user's logging pipeline, for example in security information and event management (SIEM) software.</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>This was a team effort with help from our Research and Security teams throughout the process. We relied on them for recommendations on how best to evaluate the algorithms as well as vetting the libraries we wanted to use.</p><p>We're very pleased with how HPKE has worked out for us from an ease-of-implementation and performance standpoint. It was also an easy choice for us to make due to its impending standardization and best-of-both-worlds approach to security.</p>
    <div>
      <h3>Watch it on Cloudflare TV</h3>
      <a href="#watch-it-on-cloudflare-tv">
        
      </a>
    </div>
    <div></div>
<p></p> ]]></content:encoded>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[WAF Rules]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Firewall]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">2D6DVPVrqbmzOVwOsplIix</guid>
            <dc:creator>Miguel de Moura</dc:creator>
            <dc:creator>Andre Bluehs</dc:creator>
        </item>
    </channel>
</rss>