
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Sat, 04 Apr 2026 08:40:09 GMT</lastBuildDate>
        <item>
            <title><![CDATA[LavaRand in Production: The Nitty-Gritty Technical Details]]></title>
            <link>https://blog.cloudflare.com/lavarand-in-production-the-nitty-gritty-technical-details/</link>
            <pubDate>Mon, 06 Nov 2017 06:07:00 GMT</pubDate>
            <description><![CDATA[ As some of you may know, there's a wall of lava lamps in the lobby of our San Francisco office that we use for cryptography. In this post, we’re going to explore how that works in technical detail.  ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3GpGyNbUwxO7rvWhWGw0St/0fbdcd80d0a93d7bbee4966b7f2a2f66/lava-lamps.jpg" />
            
            </figure><p>Lava lamps in the Cloudflare lobby. Courtesy of <a href="https://twitter.com/mahtin/status/888251632550424577">@mahtin</a></p>
    <div>
      <h2>Introduction</h2>
      <a href="#introduction">
        
      </a>
    </div>
    <p>As some of you may know, <a href="https://www.fastcodesign.com/90137157/the-hardest-working-office-design-in-america-encrypts-your-data-with-lava-lamps">there's a wall of lava lamps</a> in the lobby of our San Francisco office that we use for cryptography. In this post, we’re going to explore how that works in technical detail. This post assumes a technical background. For a higher-level discussion that requires no technical background, see <a href="/randomness-101-lavarand-in-production">Randomness 101: LavaRand in Production</a>.</p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>As we’ve <a href="/why-randomness-matters/">discussed in the past</a>, cryptography relies on the ability to generate random numbers that are both unpredictable and kept secret from any adversary. In this post, we’re going to go into fairly deep technical detail, so there is some background that we’ll need to ensure that everybody is on the same page.</p>
    <div>
      <h3>True Randomness vs Pseudorandomness</h3>
      <a href="#true-randomness-vs-pseudorandomness">
        
      </a>
    </div>
    <p>In cryptography, the term <i>random</i> means <i>unpredictable</i>. That is, a process for generating random bits is secure if an attacker is unable to predict the next bit with greater than 50% accuracy (in other words, no better than random chance).</p><p>We can obtain randomness that is unpredictable using one of two approaches. The first produces <i>true randomness</i>, while the second produces <i>pseudorandomness</i>.</p><p>True randomness is any information learned through the measurement of a physical process. Its unpredictability relies either on the inherent unpredictability of the physical process being measured (e.g., the unpredictability of radioactive decay), or on the inaccuracy inherent in taking precise physical measurements (e.g., the inaccuracy of the least significant digits of some physical measurement such as the measurement of a CPU’s temperature or the timing of keystrokes on a keyboard). Random values obtained in this manner are unpredictable even to the person measuring them (the person performing the measurement can’t predict what the value will be before they have performed the measurement), and thus are just as unpredictable to an external attacker. All randomness used in cryptographic algorithms begins life as true randomness obtained through physical measurements.</p><p>However, obtaining true random values is usually expensive and slow, so using them directly in cryptographic algorithms is impractical. Instead, we use pseudorandomness. Pseudorandomness is generated through the use of a deterministic algorithm that takes as input some other random value called a <i>seed</i> and produces a larger amount of random output (these algorithms are called <i>cryptographically secure pseudorandom number generators</i>, or CSPRNGs). A CSPRNG has two key properties: First, if an attacker is unable to predict the value of the seed, then that attacker will be similarly unable to predict the output of the CSPRNG (and even if the attacker is shown the output up to a certain point - say the first 10 bits - the rest of the output - bits 11, 12, etc - will still be completely unpredictable). Second, since the algorithm is deterministic, running the algorithm twice with the same seed as input will produce identical output.</p><p>The CSPRNGs used in modern cryptography are both very fast and also capable of securely producing an effectively infinite amount of output<sup>1</sup> given a relatively small seed (on the order of a few hundred bits). Thus, in order to efficiently generate a lot of secure randomness, true randomness is obtained from some physical process (this is slow), and fed into a CSPRNG which in turn produces as much randomness as is required by the application (this is fast). In this way, randomness can be obtained which is both secure (since it comes from a truly random source that cannot be predicted by an attacker) and cheap (since a CSPRNG is used to turn the truly random seed into a much larger stream of pseudorandom output).</p>
    <div>
      <h3>Running Out of Randomness</h3>
      <a href="#running-out-of-randomness">
        
      </a>
    </div>
    <p>A common misconception is that a CSPRNG, if used for long enough, can “run out” of randomness. This is an understandable belief since, as we’ll discuss in the next section, operating systems often re-seed their CSPRNGs with new randomness to hedge against attackers discovering internal state, broken CSPRNGs, and other maladies.</p><p>But if an algorithm is a true CSPRNG in the <a href="https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Definitions">technical sense</a>, then the only way for it to run out of randomness is for somebody to consume far more values from it than could ever be consumed in practice (think consuming values from a CSPRNG as fast as possible for thousands of years or more).<sup>2</sup></p><p>However, none of the fast CSPRNGs that we use in practice are proven to be true CSPRNGs. They’re just <i>strongly believed</i> to be true CSPRNGs, or something close to it. They’ve withstood the test of academic analysis, years of being used in production, attacks by resourced adversaries, and so on. But that doesn’t mean that they are without flaws. For example, SHA-1, long considered to be a cryptographically-secure collision-resistant hash function (a building block that can be used to construct a CSPRNG) was eventually discovered to be insecure. Today, it can be broken for $110,000’s worth of cloud computing resources.<sup>3</sup></p><p>Thus, even though we aren’t concerned with running out of randomness in a true CSPRNG, we also aren’t sure that what we’re using in practice are true CSPRNGs. As a result, to hedge against the possibility that an attacker has figured out how to break our CSPRNGs, designers of cryptographic systems often choose to re-seed CSPRNGs with fresh, newly-acquired true randomness just in case.</p>
    <div>
      <h3>Randomness in the Operating System</h3>
      <a href="#randomness-in-the-operating-system">
        
      </a>
    </div>
    <p>In most computer systems, one of the responsibilities of the operating system is to provide cryptographically-secure pseudorandomness for use in various security applications. Since the operating system cannot know ahead of time which applications will require pseudorandomness (or how much they will require), most systems simply keep an _entropy pool_<sup>4</sup> - a collection of randomness that is believed to be secure - that is used to seed a CSPRNG (e.g., <code>/dev/urandom</code> on Linux) which serves requests for randomness. The system then takes on the responsibility of not only seeding this entropy pool when the system first boots, but also of periodically updating the pool (and re-seeding the CSPRNG) with new randomness from whatever sources of true randomness are available to the system in order to hedge against broken CSPRNGs or attackers having compromised the entropy pool through other non-cryptographic attacks.</p><p>For brevity, and since Cloudflare’s production system’s run Linux, we will refer to the system’s pseudorandomness provider simply as <code>/dev/urandom</code>, although note that everything in this discussion is true of other operating systems as well.</p><p>Given this setup of an entropy pool and CSPRNG, there are a few situations that could compromise the security of <code>/dev/urandom</code>:</p><ul><li><p>The sources of true randomness used to seed theentropy pool could be too predictable, allowing an attacker to guess the values obtained from these sources, and thus to predict the output of <code>/dev/urandom</code>.</p></li><li><p>An attacker could have access to the sources of true randomness, thus being able to observe their values and thus predict the output of <code>/dev/urandom</code>.</p></li><li><p>An attacker could have the ability to modify the sources of true randomness, thus being able to influence the values obtained from these sources and thus predict the output of <code>/dev/urandom</code>.</p></li></ul>
    <div>
      <h3>Randomness Mixing</h3>
      <a href="#randomness-mixing">
        
      </a>
    </div>
    <p>A common approach to addressing these security issues is to mix multiple sources of randomness together in the system’s entropy pool, the idea being that so long as some of the sources remain uncompromised, the system remains secure. For example, if sources <i>X</i>, <i>Y</i>, and <i>Z</i>, when queried for random outputs, provide values <i>x</i>, <i>y</i>, and <i>z</i>, we might seed our entropy pool with <i>H(x, y, z)</i>, where <i>H</i> is a cryptographically-secure collision-resistant hash function. Even if we assume that two of these sources - say, <i>X</i> and <i>Y</i> - are malicious, so long as the attackers in control of them are not able to observe <i>Z</i>’s output,<sup>5</sup> then no matter what values of <i>x</i> and <i>y</i> they produce, <i>H(x, y, z)</i> will still be unpredictable to them.</p>
    <div>
      <h2>LavaRand</h2>
      <a href="#lavarand">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1thY8qByl6CmiTCI9tIgOG/5de49269d8aeae96359870cad09d3a16/lava-lamps-camera.jpg" />
            
            </figure><p>The view from the camera</p><p>While the probability is obviously very low that somebody will manage to predict or modify the output of the entropy sources on our production machines, it would be irresponsible of us to pretend that it is impossible. Similarly, while cryptographic attacks against state-of-the-art CSPRNGs are rare, they do occasionally happen. It’s important that we hedge against these possibilities by adding <a href="https://en.wikipedia.org/wiki/Defense_in_depth_(computing)">extra layers of defense</a>.</p><p>That’s where LavaRand comes in.</p><p>In short, LavaRand is a system that provides an additional entropy source to our production machines. In the lobby of our San Francisco office, we have a wall of lava lamps (pictured above). A video feed of this wall is used to generate entropy that is made available to our production fleet.</p><p>We're not the first ones to do this. Our LavaRand system was inspired by a similar system first <a href="https://en.wikipedia.org/wiki/Lavarand">proposed and built</a> by Silicon Graphics and <a href="https://www.google.com/patents/US5732138">patented</a> in 1996 (the patent has since expired).</p><p>The flow of the “lava” in a lava lamp is very unpredictable,6 and so the entropy in those lamps is incredibly high. Even if we conservatively assume that the camera has a resolution of 100x100 pixels (of course it’s actually much higher) and that an attacker can guess the value of any pixel of that image to within one bit of precision (e.g., they know that a particular pixel has a red value of either 123 or 124, but they aren’t sure which it is), then the total amount of entropy produced by the image is 100x100x3 = 30,000 bits (the x3 is because each pixel comprises three values - a red, a green, and a blue channel). This is orders of magnitude more entropy than we need.</p>
    <div>
      <h3>Design</h3>
      <a href="#design">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/HQnazwt1tj0ywVtjZ0HTX/4cbe7db55b4792b1b86dcea4a57b5474/Screen-Shot-2017-10-31-at-3.57.19-PM.png" />
            
            </figure><p>The flow of entropy in LavaRand</p><p>The overall design of the LavaRand system is pictured above. The flow of entropy can be broken down into the following steps:</p><p>The wall of lava lamps in the office lobby provides a source of true entropy.</p><p>In the lobby, a camera is pointed at the wall. It obtains entropy from both the visual input from the lava lamps and also from random noise in the individual photoreceptors.</p><p>In the office, there’s a server which connects to the camera. The server has its own entropy system, and the output of that entropy system is mixed with the entropy from the camera to produce a new entropy feed.</p><p>In one of our production data centers, there’s a service which connects to the server in the office and consumes its entropy feed. That service combines this entropy feed with output from its own local entropy system to produce yet another entropy feed. This feed is made available for any production service to consume.</p>
    <div>
      <h3>Security of the LavaRand Service</h3>
      <a href="#security-of-the-lavarand-service">
        
      </a>
    </div>
    <p>We might conceive of a number of attacks that could be leveraged against this system:</p><ul><li><p>An attacker could train a camera on the wall of lava lamps, attempting to reproduce the image captured by our camera.</p></li><li><p>An attacker could reduce the entropy from the wall of lava lamps by turning off the power to the lamps, shining a bright light at the camera, placing a lens cap on the camera, or any number of other physical attacks.</p></li><li><p>An attacker able to compromise the camera could exfiltrate or modify the feed of frames from the camera, replicating or controlling the entropy source used by the server in the office.</p></li><li><p>An attacker with code running on the office server could observe or modify the output of the entropy feed generated by that server.</p></li><li><p>An attacker with code running in the production service could observe or modify the output of the entropy feed generated by that service.</p></li></ul><p>Only one of these attacks would be fatal if successfully carried out: running code on the production service which produces the final entropy feed. In every other case, the malicious entropy feed controlled by the attacker is mixed with a non-malicious feed that the attacker can neither observe nor modify.<sup>7</sup> As we discussed in a previous section, as long as the attacker is unable to predict the output of these non-malicious feeds, they will be unable to predict the output of the entropy feed generated by mixing their malicious feed with the non-malicious feed.</p>
    <div>
      <h3>Using LavaRand</h3>
      <a href="#using-lavarand">
        
      </a>
    </div>
    <p>Having a secure entropy source is only half of the story - the other half is actually using it!</p><p>The goal of LavaRand is to ensure that our production machines have access to secure randomness <i>even if their local entropy sources are compromised</i>. Just after boot, each of our production machines contacts LavaRand over TLS to obtain a fixed-size chunk of fresh entropy called a “beacon.” It mixes this beacon into the entropy system (on Linux, by writing the beacon to <code>/dev/random</code>). After this point, in order to predict or control the output of <code>/dev/urandom</code>, an attacker would need to compromise both the machine’s local entropy sources <i>and</i> the LavaRand beacon.</p>
    <div>
      <h3>Bootstrapping TLS</h3>
      <a href="#bootstrapping-tls">
        
      </a>
    </div>
    <p>Unfortunately, the reality isn’t quite that simple. We’ve gotten ourselves into something of a chicken-and-egg problem here: we’re trying to hedge against bad entropy from our local entropy sources, so we have to assume those might be compromised. But TLS, like many cryptographic protocols, requires secure entropy in order to operate. And we require TLS to request a LavaRand beacon. So in order to ensure secure entropy, we have to have secure entropy…</p><p>We solve this problem by introducing a second special-purpose CSPRNG, and seeding it in a very particular way. Every machine in Cloudflare’s production fleet has its own permanent store of secrets that it uses just after boot to prove its identity to the rest of the fleet in order to bootstrap the rest of the boot process. We piggyback on that system by storing an extra random seed - unique for each machine - that we use for that first TLS connection to LavaRand.</p><p>There’s a simple but very useful result from cryptography theory that says that an HMAC - a hash-based message authentication code - when combined with a random, unpredictable seed, behaves (from the perspective of an attacker) like a random oracle. That’s a lot of crypto jargon, but it basically means that if you have a secret, randomly-generated seed, <i>s</i>, then an attacker will be completely unable to guess the output of <i>HMAC(s, x)</i> <i>regardless of the value of x</i> - even if <i>x</i> is completely predictable! Thus, you can use <i>HMAC(s, x)</i> as the seed to a CSPRNG, and the output of the CSPRNG will be unpredictable. Note, though, that if you need to do this multiple times, you will have to pick different values for <i>x</i>! Remember that while CSPRNGs are secure if used with unpredictable seeds, they’re also deterministic. Thus, if the same value is used for <i>x</i> more than once, then the CSPRNG will end up producing the same stream of “random” values more than once, which in cryptography is often very insecure!</p><p>This means that we can combine those unique, secret seeds that we store on each machine with an HMAC and produce a secure random value. We use the current time with nanosecond precision as the input to ensure that the same value is never used twice on the same machine. We use the resulting value to seed a CSPRNG, and we use that CSPRNG for the TLS connection to LavaRand. That way, even if the system’s entropy sources are compromised, we’ll still be able to make a secure connection to LavaRand, obtain a new, secure beacon, and bootstrap the system’s entropy back to a secure state!</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>Hopefully we’ll never need LavaRand. Hopefully, the primary entropy sources used by our production machines will remain secure, and LavaRand will serve little purpose beyond adding some flair to our office. But if it turns out that we’re wrong, and that our randomness sources in production are actually flawed, then hopefully LavaRand will be our hedge, making it just a little bit harder to hack Cloudflare.</p><hr /><p><sup>1</sup> Some CSPRNGs exist with constraints on how much output can be consumed securely, but those are not the sort that we are concerned with in this post.</p><p><sup>2</sup> Section 3.1, <a href="https://www.usenix.org/system/files/conference/hotos15/hotos15-paper-corrigan-gibbs.pdf">Recommendations for Randomness in the Operating System</a></p><p><sup>3</sup> <a href="https://shattered.io/static/shattered.pdf">The first collision for full SHA-1</a></p><p><sup>4</sup> “Entropy” and “randomness” are synonyms in cryptography - the former is the more technical term.</p><p><sup>5</sup> If the attacker controls <i>X</i> and <i>Y</i> and can also observe the output of <i>Z</i>, then the attacker can still partially influence the output of <i>H(x, y, z)</i>. See <a href="http://blog.cr.yp.to/20140205-entropy.html">here</a> for a discussion of possible attacks.</p><p><sup>6</sup> Noll, L.C. and Mende, R.G. and Sisodiya, S., <a href="https://www.google.com/patents/US5732138"><i>Method for seeding a pseudo-random number generator with a cryptographic hash of a digitization of a chaotic system</i></a></p><p><sup>7</sup> A surprising example of the effectiveness of entropy is the mixing of the image captured by the camera with the random noise in the camera’s photoreceptors. If we assume that every pixel captured is either recorded as the “true” value or is instead recorded as one value higher than the true value (50% probability for each), then even if the input image can be reproduced by an attacker with perfect accuracy, the camera <i>still</i> provides one bit of entropy for each pixel channel. As discussed before, even for a 100x100 pixel camera, that’s 30,000 bits!</p> ]]></content:encoded>
            <category><![CDATA[LavaRand]]></category>
            <category><![CDATA[Entropy]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">6i8GxcLswvLnL74LrqK2Ef</guid>
            <dc:creator>Joshua Liebow-Feeser</dc:creator>
        </item>
        <item>
            <title><![CDATA[Randomness 101: LavaRand in Production]]></title>
            <link>https://blog.cloudflare.com/randomness-101-lavarand-in-production/</link>
            <pubDate>Mon, 06 Nov 2017 05:54:46 GMT</pubDate>
            <description><![CDATA[ As some of you may know, there's a wall of lava lamps in the lobby of our San Francisco office that we use for cryptography. In this post, we’re going to explore how that works.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Lava lamps in the Cloudflare lobby Courtesy of <a href="https://twitter.com/mahtin/status/888251632550424577">@mahtin</a></p>
    <div>
      <h3>Introduction</h3>
      <a href="#introduction">
        
      </a>
    </div>
    <p>As some of you may know, <a href="https://www.fastcodesign.com/90137157/the-hardest-working-office-design-in-america-encrypts-your-data-with-lava-lamps">there's a wall of lava lamps</a> in the lobby of our San Francisco office that we use for cryptography. In this post, we’re going to explore how that works. This post assumes no technical background. For a more in-depth look at the technical details, see <a href="/lavarand-in-production-the-nitty-gritty-technical-details">LavaRand in Production: The Nitty-Gritty Technical Details</a>.</p>
    <div>
      <h3>Background</h3>
      <a href="#background">
        
      </a>
    </div>
    
    <div>
      <h4>Randomness in Cryptography</h4>
      <a href="#randomness-in-cryptography">
        
      </a>
    </div>
    <p>As we’ve <a href="/why-randomness-matters/">discussed in the past</a>, cryptography relies on the ability to generate random numbers that are both unpredictable and kept secret from any adversary.</p><p>But “random” is a pretty tricky term; it’s used in many different fields to mean slightly different things. And like all of those fields, its use in cryptography is very precise. In some fields, a process is random simply if it has the right statistical properties. For example, the digits of pi are said to be random because all sequences of numbers appear with equal frequency (“15” appears as frequently as “38”, “426” appears as frequently as “297”, etc). But for cryptography, this isn’t enough - random numbers must be <i>unpredictable</i>.</p><p>To understand what <i>unpredictable</i> means, it helps to consider that all cryptography is based on an asymmetry of information. If you’re trying to securely perform some cryptographic operation, then what you’re concerned about is that somebody - an <i>adversary</i> - will try to break your security. The only thing that distinguishes you from the adversary is that you know some things that the adversary does not, and the job of cryptography is to ensure that this asymmetry of information is enough to keep you secure.</p><p>Let’s consider a simple example. Imagine that you and a friend are trying to go to a movie, but you don’t want your nemesis to figure out which movie you’re going to go to (lest she show up and thwart your movie watching!). This week, it’s your turn to choose the movie. Once you’ve made your choice, you’re going to need to send a message to your friend telling him which movie you’ve chosen, but you’re going to need to ensure that even if your nemesis intercepts the message, she won’t be able to figure out what it says.</p><p>You devise the following scheme: since there are only two movies available to watch at the moment, you label one A and the other B. Then, while in the presence of your friend, you flip a coin. You agree on the following table outlining which message that you will send depending on your choice of what movie to watch and whether the coin comes up heads (H) or tails (T). Later, once you’ve made up your mind about which movie to see, you’ll use this table to send an encrypted message to your friend telling him which movie you’ve chosen.</p><table><tr><td><p><b>Movie</b></p></td><td><p><b>Coin</b></p></td><td><p><b>Message</b></p></td></tr><tr><td><p>A</p></td><td><p>H</p></td><td><p>“The rain in Spain stays mainly on the plain.”</p></td></tr><tr><td><p>A</p></td><td><p>T</p></td><td><p>“In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen.”</p></td></tr><tr><td><p>B</p></td><td><p>H</p></td><td><p>“In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen.”</p></td></tr><tr><td><p>B</p></td><td><p>T</p></td><td><p>“The rain in Spain stays mainly on the plain.”</p></td></tr></table><p>If you were to decide on movie B, and the coin came up heads, you would send the message, “In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen.” Since your friend knows that the coin came up heads - he was there when it happened - he knows that you must have decided on movie B. But consider it from your nemesis’ perspective. She doesn’t know the result of the coin toss - all she knows is that there’s a 50% chance that the coin came up heads, and a 50% chance that it came up tails. Thus, seeing the message “In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen” doesn’t help her at all! There’s a 50% chance that the coin came up heads (implying movie B), and a 50% chance that it came up tails (implying movie A). She doesn’t know anything more than she knew before!</p><p>Let’s return now to the concept of <i>unpredictability</i>. Imagine that the result of the coin toss was completely predictable - say your nemesis planted a trick coin that always comes up heads on the first toss, tails on the second, heads on the third, and so on. Since she would know that there was a 100% chance of the first coin toss coming up heads, then regardless of which message you sent, she would know which movie you were going to see. While the trick coin still exhibits some basic properties of “randomness” as the term is used in the field of statistics - it comes up heads as often as it comes up tails - it’s <i>predictable</i>, which makes it useless for cryptography. The takeaway: when we say <i>random</i> in the context of cryptography, we mean <i>unpredictable</i>.</p>
    <div>
      <h3>Randomness in Computing</h3>
      <a href="#randomness-in-computing">
        
      </a>
    </div>
    <p>Unfortunately for cryptographers, if there’s one thing computers are good at, it’s being predictable. They can execute the same code a million times, and so long as they are given the same inputs each time, they’ll always come up with the same outputs. This is very good for reliability, but it’s tricky when it comes to cryptography - after all, we <i>need</i> unpredictability!</p><p>The solution to this problem is <i>cryptographically-secure pseudorandom number generators</i> (CSPRNGs). CSPRNGs are algorithms which, provided an input which is itself unpredictable, produce a much larger stream of output which is also unpredictable. This stream can be extended indefinitely, producing as much output as required at any time in the future. In other words, if you were to flip a coin a number of times (a process which is known to be unpredictable) and then use the output of those coin flips as the input to a CSPRNG, an adversary who wasn’t able to predict the output of those coin flips would also be unable to predict the output of the CSPRNG - no matter how much output was consumed from the CSPRNG.</p><p>But even though CSPRNGs are a very powerful tool, they’re only one half of the equation - they still need an unpredictable input to operate. But as we said, computers aren’t unpredictable, so aren’t we back at square one? Well, not quite. It turns out that computers do usually have sources of unpredictability that they can use, but they’re pretty slow. What we can do is combine that slow process of gathering unpredictable input with a CSPRNG, which can take that input and produce a much larger amount of input more quickly, and we can satisfy all of our randomness needs!</p><p>But where can a computer get such unpredictable input, even slowly? The answer is <i>the real world</i>. While computers provide a nice simplification of the world for programmers to live in, real, physical computers still exist in the real, physical world. And that world is unpredictable. Computers have all sorts of ways of taking input from the real world - temperature sensors, keyboards, network interfaces, etc. All of these provide the ability to take measurements of the real world, and all of those measurements have some degree of inherent inaccuracy. As we’ll explain in a moment, that inaccuracy is the same thing as unpredictability, and this can be used! Common sources of unpredictable randomness include measuring the temperature of the CPU with high - and thus inaccurate - precision, measuring the timing of keystrokes on the keyboard with high precision, etc. To see how this can be used to produce unpredictable randomness, consider the question, “what’s the temperature of the room I’m sitting in right now?” You can probably estimate to within a couple of degrees - say, somewhere between 70 and 75 degrees Fahrenheit. But you probably have no idea what the temperature is to 2 decimal places of accuracy - is it 73.42 degrees or 73.47 degrees? By measuring the temperature with high precision and then using only the low-order digits of the measured value, you can get highly unpredictable randomness just by observing the world around you. And so can computers.</p><p>So, to recap:</p><ul><li><p>Randomness used in cryptography needs to be unpredictable.</p></li><li><p>Computers can slowly get a small amount of unpredictable randomness by measuring their environment.</p></li><li><p>Computers can greatly extend this randomness by using a CSPRNG which can quickly turn it into a large amount of unpredictable randomness.</p></li></ul>
    <div>
      <h3>Hedging Your Bets</h3>
      <a href="#hedging-your-bets">
        
      </a>
    </div>
    <p>If there’s one thing cryptographers are wary about, it’s certainty. Cryptographic systems are routinely shown to be less secure than they were originally thought to be, and we’re constantly updating our understanding of what algorithms are safe to use in what scenarios.</p><p>So it shouldn’t be any surprise that cryptographers like to hedge their bets by using more security than they believe necessary in case it turns out that one of their assumptions was wrong. It’s sort of like the cryptographer’s version of the engineering practice of designing buildings to withstand far more weight or wind or heat than they think will arise in practice.</p><p>When it comes to randomness, this hedging often takes the form of <i>mixing</i>. Unpredictable random values have the neat property that if they’re mixed in the right way with more unpredictable random values, then the result is at least as unpredictable as either of the inputs. That means that if you mix a random value which is highly unpredictability with a random value which is somewhat predictable, the result will be a highly unpredictable value.</p><p>This mixing property is useful because it allows you to mix unpredictable random values from many sources, and if you later discover that one of those sources was less unpredictable than you’d originally thought, it’s still OK - the other sources come to the rescue.</p>
    <div>
      <h3>LavaRand</h3>
      <a href="#lavarand">
        
      </a>
    </div>
    <p>At Cloudflare, we have thousands of computers in data centers all around the world, and each one of these computers needs cryptographic randomness. Historically, they got that randomness using the default mechanism made available by the operating system that we run on them, Linux.</p><p>But being good cryptographers, we’re always trying to hedge our bets. We wanted a system to ensure that even if the default mechanism for acquiring randomness was flawed, we’d still be secure. That’s how we came up with LavaRand.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Vz4N3zljIz1BLk9Zj8EFH/df36b17492525695fceb79198df56823/lava-lamps-camera.jpg" />
            
            </figure><p>The view from the camera</p><p>LavaRand is a system that uses lava lamps as a secondary source of randomness for our production servers. A wall of lava lamps in the lobby of our San Francisco office provides an unpredictable input to a camera aimed at the wall. A video feed from the camera is fed into a CSPRNG, and that CSPRNG provides a stream of random values that can be used as an extra source of randomness by our production servers. Since the flow of the “lava” in a lava lamp is very unpredictable,<sup>1</sup> “measuring” the lamps by taking footage of them is a good way to obtain unpredictable randomness. Computers store images as very large numbers, so we can use them as the input to a CSPRNG just like any other number.</p><p>We're not the first ones to do this. Our LavaRand system was inspired by a similar system first <a href="https://en.wikipedia.org/wiki/Lavarand">proposed and built</a> by Silicon Graphics and <a href="https://www.google.com/patents/US5732138">patented</a> in 1996 (the patent has since expired).</p><p>Hopefully we’ll never need it. Hopefully, the primary sources of randomness used by our production servers will remain secure, and LavaRand will serve little purpose beyond adding some flair to our office. But if it turns out that we’re wrong, and that our randomness sources in production are actually flawed, then LavaRand will be our hedge, making it just a little bit harder to hack Cloudflare.</p><ol><li><p>Noll, L.C. and Mende, R.G. and Sisodiya, S., <a href="https://www.google.com/patents/US5732138"><i>Method for seeding a pseudo-random number generator with a cryptographic hash of a digitization of a chaotic system</i></a></p></li></ol><p></p> ]]></content:encoded>
            <category><![CDATA[LavaRand]]></category>
            <category><![CDATA[Entropy]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">cMgBPjWlpt6XfFcsYQhhc</guid>
            <dc:creator>Joshua Liebow-Feeser</dc:creator>
        </item>
        <item>
            <title><![CDATA[Understanding Our Cache and the Web Cache Deception Attack]]></title>
            <link>https://blog.cloudflare.com/understanding-our-cache-and-the-web-cache-deception-attack/</link>
            <pubDate>Fri, 14 Apr 2017 15:00:00 GMT</pubDate>
            <description><![CDATA[ About a month ago, security researcher Omer Gil published the details of an attack that he calls the Web Cache Deception attack. It works against sites that sit behind a reverse proxy (like Cloudflare) and are misconfigured in a particular way. ]]></description>
            <content:encoded><![CDATA[ <p>About a month ago, security researcher <a href="https://twitter.com/omer_gil">Omer Gil</a> published <a href="https://omergil.blogspot.co.il/2017/02/web-cache-deception-attack.html">the details</a> of an attack that he calls the Web Cache Deception attack. It works against sites that sit behind a reverse proxy (like Cloudflare) and are misconfigured in a particular way. Unfortunately, the definition of "misconfigured" for the purposes of this attack changes depending on how the cache works. In this post, we're going to explain the attack and then describe the algorithm that our cache uses to decide whether or not to cache a given piece of content so that customers can be sure that they are secure against this attack.</p>
    <div>
      <h3>The Attack</h3>
      <a href="#the-attack">
        
      </a>
    </div>
    <p>First, we'll explain the basics of the Web Cache Deception attack. For those who want a more in-depth explanation, Omer's <a href="https://omergil.blogspot.co.il/2017/02/web-cache-deception-attack.html">original post</a> is a great resource.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Wy262IiC2ykqjHqHRbOwk/ac8fc41024662ee444219734662f9f9b/one-way.jpg" />
            
            </figure><p>CC <a href="https://creativecommons.org/licenses/by-sa/2.0/">BY-SA 2.0</a> - <a href="https://www.flickr.com/photos/shelleygibb/2700437267/in/photolist-57CrVe-i4jqNw-gmjSdW-b4eUjD-gmk8in-cFq3pN-2uVYE-2juSjD-d7gDoh-7ac96c-ytw77e-6k2Mw-9NnUjX-6oC4tp-9wFsmg-dsd8bt-bDTPG3-co2zqU-jFdVgc-5DHRZA-66H4P6-7jaCZF-848i8G-9aUjGk-bWVLYW-aCJNHD-buaVVA-nGA4V-soHrms-9quZAv-6MsSqe-nBG2bz-dsd7HT-d7gyTS-9kCfi-4F5xjK-cYYz9N-fFUYF-fQuqJw-dQZTkX-cNMqMJ-qrNmAB-aCJPui-dQXj68-87UrJH-phtpFE-997rCh-oA1ezU-nwpSdp-kswDL6/">image</a> by <a href="https://www.flickr.com/photos/shelleygibb/">shelleygibb</a></p><p>Imagine that you run the social media website <code>example.com</code>, and that each of your users has a newsfeed at <code>example.com/newsfeed</code>. When a user navigates to their newsfeed, the HTTP request generated by their browser might look something like this:</p>
            <pre><code>GET /newsfeed HTTP/1.1
Host: example.com
...</code></pre>
            <p>If you use Cloudflare, you don't want us to cache this request because if we did, some of your users might start seeing other users' newsfeeds instead of their own, which would be very bad. Luckily, as we'll explain below, this request won't be cached because the path in the request (the <code>/newsfeed</code> part) doesn't have a "cacheable file extension" (a file extension such as <code>.jpg</code> or <code>.css</code> that instructs Cloudflare that it's OK to cache the request).</p><p>The trouble begins if your website is configured to be flexible about what kinds of paths it can handle. In particular, the issue arises when requests to a path that doesn't exist (say, <code>/x/y/z</code>) are treated as equivalent to requests to a parent path that <i>does</i> exist (say, <code>/x</code>). For example, what happens if you get a request for the nonexistent path <code>/newsfeed/foo</code>? Depending on how your website is configured, it might just treat such a request as equivalent to a request to <code>/newsfeed</code>. For example, if you're running the <a href="https://docs.djangoproject.com/en/1.10/topics/http/urls/">Django web framework</a>, the following configuration would do just that because the regular expression <code>^newsfeed/</code> matches both <code>newsfeed/</code> and <code>newsfeed/foo</code> (Django routes omit the leading <code>/</code>):</p>
            <pre><code>from django.conf.urls import url

patterns = [url(r'^newsfeed/', ...)]</code></pre>
            <p>And here's where the problem lies. If your website does this, then a request to <code>/newsfeed/foo.jpg</code> will be treated as the same as a request to <code>/newsfeed</code>. But Cloudflare, seeing the <code>.jpg</code> file extension, will think that it's OK to cache this request.</p><p>Now, you might be thinking, "So what? My website never has any links to <code>/newsfeed/foo.jpg</code> or anything like that." That's true, but that doesn't stop <i>other</i> people from trying to convince your users to visit paths like that. For example, an attacker could send this message to somebody:</p><blockquote><p>Hey, check out this cool link! <a href="https://example.com/newsfeed/foo.jpg">https://example.com/newsfeed/foo.jpg</a></p></blockquote><p>If the recipient of the message clicks on the link, they will be taken to their newsfeed. But when the request passes through Cloudflare, since the path ends in `.jpg`, we will cache it. Then the attacker can visit the same URL themselves and their request will be served from our cache, exposing your user's sensitive content.</p>
    <div>
      <h3>Defending Against the Web Cache Deception Attack</h3>
      <a href="#defending-against-the-web-cache-deception-attack">
        
      </a>
    </div>
    <p>The best way to defend against this attack is to ensure that your website isn't so permissive, and never treats requests to nonexistent paths (say, <code>/x/y/z</code>) as equivalent to requests to valid parent paths (say, <code>/x</code>). In the example above, that would mean that requests to <code>/newsfeed/foo</code> or <code>/newsfeed/foo.jpg</code> wouldn't be treated as equivalent to requests to <code>/newsfeed</code>, but would instead result in some kind of error or a redirect to a legitimate page. If we wanted to modify the Django example from above, we could add a <code>$</code> to the end of the regular expression to ensure only exact matches (in this case, a request to <code>/newsfeed/foo</code> will <a href="https://docs.djangoproject.com/en/1.10/topics/http/urls/#error-handling">result in a 404</a>):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/EctCR6DDUYFIWG9EatWeC/be0902c6bc2d5e558554c3e31c63ec43/Screen-Shot-2018-01-19-at-10.23.10-AM.png" />
            
            </figure><p>We provide many settings that allow you to customize the way our cache will treat requests to your website. For example, if you have a Page Rule enabled for <code>/newsfeed</code> with the Cache Everything setting enabled (it's off by default), then we'll cache requests to <code>/newsfeed</code>, which could be bad. Thus, the best way to <a href="https://www.cloudflare.com/learning/security/glossary/website-security-checklist/">ensure that your website is secure</a> is to understand the rules that our cache uses to determine whether or not a request should be cached.</p>
    <div>
      <h3>How Our Cache Works</h3>
      <a href="#how-our-cache-works">
        
      </a>
    </div>
    <p>When a request comes in to our network, we perform two phases of processing in order to determine whether or not to cache the origin's response to that request:</p><ul><li><p>In the <i>eligibility phase</i>, which is performed when a request first reaches our edge, we inspect the request to determine whether it should be eligible for caching. If we determine that it is not eligible, then we will not cache it. If we determine that it is eligible, then we proceed to a second disqualification phase.</p></li><li><p>In the <i>disqualification phase</i>, which is performed after we've received a response from the origin web server, we inspect the response to determine whether any characteristics disqualify the response from being cached. If nothing disqualifies it, then the response will be cached.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2TLTgYd4yL4nBAkczqkQHn/c90ac4770733d951a17a54c815516693/page-rule-modal.png" />
            
            </figure><p>_Configuring caching via a Page Rule_</p><p>Note that site-wide settings or Page Rules can affect this logic. Below, when we say "a setting applies" or "the setting is," we mean that either a global setting exists which applies to all requests or a Page Rule with the setting exists that applies to the given request (e.g., a Page Rule for <code>/foo/*</code> applies to requests to <code>/foo/bar</code>, <code>/foo/baz</code>, <code>/foo/bar/baz</code>, etc). Page Rules override global rules if both apply to a given request.</p>
    <div>
      <h3>Eligibility Phase</h3>
      <a href="#eligibility-phase">
        
      </a>
    </div>
    <p>In the <i>eligibility phase</i>, we use characteristics of the request from the client to determine whether or not the request is eligible to be cached. If the request is not eligible, then it will not be cached. If the request is eligible, then we will perform more processing later in the disqualification phase.</p><p>The rules for eligibility are as follows:</p><ul><li><p>If the setting is Standard, Ignore Query String, or No Query String, then:</p><ul><li><p>a request is eligible to be cached if the requested path ends in one of the file extensions listed in Figure 1 below</p></li><li><p>a request <i>may</i> be eligible to be cached (depending on performance-related decisions made by our edge) if the requested path ends in one of the file extensions listed in Figure 2 below</p></li><li><p>a request is eligible to be cached if the request path is <code>/robots.txt</code></p></li></ul></li><li><p>If the setting is Cache Everything, then all requests are eligible to be cached.</p></li></ul><p>In addition to the above rules, if either of the following two conditions hold, then any decision made so far about eligibility will be overridden, and the request will not be eligible to be cached:</p><ul><li><p>If the Cache on Cookie setting is enabled and the configured cookie is <i>not</i> present in a <code>Cookie</code> header, then the request is not eligible to be cached.</p></li><li><p>If the Bypass Cache on Cookie setting is enabled and the configured cookie <i>is</i> present in a <code>Cookie</code> header, then the request is not eligible to be cached.</p></li></ul>
    <div>
      <h3>Disqualification Phase</h3>
      <a href="#disqualification-phase">
        
      </a>
    </div>
    <p>In the <i>disqualification phase</i>, which only occurs if a request has been marked as eligible, characteristics of the response from the origin web server can disqualify a request. If a request is disqualified, then the response will not be cached. If a request is not disqualified, then the response will be cached.</p><p>The rules for disqualification are as follows:</p><ul><li><p>If the setting is Standard, Ignore Query String, or No Query String, or if the setting is Cache Everything <i>and</i> no Edge Cache TTL is present, then:</p><ul><li><p>A <code>Cache-Control</code> header in the response from the origin with any of the following values will disqualify a request, causing it not to be cached:</p><ul><li><p><code>no-cache</code></p></li><li><p><code>max-age=0</code></p></li><li><p><code>private</code></p></li><li><p><code>no-store</code></p></li></ul></li><li><p>An <code>Expires</code> header in the response from the origin indicating any time in the past will disqualify a request, causing it not to be cached.</p></li></ul></li><li><p>If the setting is Cache Everything and an Edge Cache TTL <i>is</i> present, then a request will never be disqualified under any circumstances, and will always be cached.</p></li></ul><p>There is one further set of rules relating to the <code>Set-Cookie</code> header. The following rules only apply if a <code>Set-Cookie</code> header is present:</p><ul><li><p>If the setting is Standard, Ignore Query String, or No Query String, or if the setting is Cache Everything and an Edge Cache TTL is present, then the request will not be disqualified, but the <code>Set-Cookie</code> header will be stripped from the version of the response stored in our cache.</p></li><li><p>If the setting is Cache Everything and no Edge Cache TTL is present, then the request will be disqualified, and it will not be cached. The <code>Set-Cookie</code> header will be stripped from the response that is sent to the client making the request.</p></li></ul>
            <pre><code>class
css
jar
js
jpg
jpeg
gif
ico
png
bmp
pict
csv
doc
docx
xls
xlsx
ps
pdf
pls
ppt
pptx
tif
tiff
ttf
otf
webp
woff
woff2
svg
svgz
eot
eps
ejs
swf
torrent
midi
mid</code></pre>
            <p>_Figure 1: Always Cacheable File Extensions_</p>
            <pre><code>mp3
mp4
mp4v
mpg
mpeg
mov
mkv
flv
webm
wmv
avi
ogg
m4a
wav
aac
ogv
zip
sit
tar
7z
rar
rpm
deb
dmg
iso
img
msi
msp
msm
bin
exe
dll
ra
mka
ts
m4v
asf
mk3d
rm
swf</code></pre>
            <p>_Figure 2: Sometimes Cacheable File Extensions_</p><p>So there you have it. So long as you make sure to follow the advice above, and make sure that your site plays nicely with our cache, you should be secure against the Web Cache Deception attack.</p> ]]></content:encoded>
            <category><![CDATA[Page Rules]]></category>
            <category><![CDATA[Attacks]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Reliability]]></category>
            <category><![CDATA[Best Practices]]></category>
            <category><![CDATA[Cache]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <guid isPermaLink="false">6XM5d3s0P5kafUnEofmpM2</guid>
            <dc:creator>Joshua Liebow-Feeser</dc:creator>
        </item>
    </channel>
</rss>