
<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 16:32:54 GMT</lastBuildDate>
        <item>
            <title><![CDATA[UtahFS: Encrypted File Storage]]></title>
            <link>https://blog.cloudflare.com/utahfs/</link>
            <pubDate>Tue, 09 Jun 2020 11:00:00 GMT</pubDate>
            <description><![CDATA[ Several months ago, I realized that I had a lot of sensitive files on my computer (my diary, if you must know) that I was afraid of losing, but I didn’t feel comfortable putting them in something like Google Drive or Dropbox. Introducing UtahFS. ]]></description>
            <content:encoded><![CDATA[ <p>Encryption is one of the most powerful technologies that everyone uses on a daily basis without realizing it. Transport-layer encryption, which protects data as it’s sent across the Internet to its intended destination, is now ubiquitous because it’s a fundamental tool for creating a trustworthy Internet. Disk encryption, which protects data while it’s sitting idly on your phone or laptop’s hard drive, is also becoming ubiquitous because it prevents anybody who steals your device from also being able to see what’s on your desktop or read your email.</p><p>The next improvement on this technology that’s starting to gain popularity is end-to-end encryption, which refers to a system where only the end-users are able to access their data -- not any intermediate service providers. Some of the most popular examples of this type of encryption are chat apps like <a href="https://faq.whatsapp.com/en/android/28030015/">WhatsApp</a> and <a href="https://signal.org/">Signal</a>. End-to-end encryption significantly reduces the likelihood of a user’s data being <a href="https://en.wikipedia.org/wiki/Yahoo!_data_breaches">maliciously stolen</a> from, or <a href="https://arstechnica.com/gadgets/2020/02/google-photos-bug-let-strangers-download-your-private-videos/">otherwise mishandled</a> by a service provider. This is because even if the service provider loses the data, nobody will have the keys to decrypt it!</p><p>Several months ago, I realized that I had a lot of sensitive files on my computer (my diary, if you must know) that I was afraid of losing, but I didn’t feel comfortable putting them in something like Google Drive or Dropbox. While Google and Dropbox are absolutely trustworthy companies, they don’t offer encryption and this is a case where I would really wanted complete control of my data.</p><p>From looking around, it was hard for me to find something that met all of my requirements:</p><ol><li><p>Would both encrypt and authenticate the directory structure, meaning that file names are hidden and it’s not possible for others to move or rename files.</p></li><li><p>Viewing/changing part of a large file doesn’t require downloading and decrypting the entire file.</p></li><li><p>Is open-source and has a documented protocol.</p></li></ol><p>So I set out to build such a system! The end result is called UtahFS, and the <a href="https://github.com/cloudflare/utahfs">code for it is available here</a>. Keep in mind that this system is not used in production at Cloudflare: it’s a proof-of-concept that I built while working on our <a href="/cloudflares-approach-to-research/">Research Team</a>. The rest of this blog post describes why I built it as I did, but there’s documentation in the repository on actually using it if you <a href="https://github.com/cloudflare/utahfs/tree/master/docs">want to skip to that</a>.</p>
    <div>
      <h3>Storage Layer</h3>
      <a href="#storage-layer">
        
      </a>
    </div>
    <p>The first and most important part of a storage system is… the storage. For this, I used Object Storage, because it’s one of the cheapest and most reliable ways to store data on somebody else’s hard drives. <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">Object storage</a> is nothing more than a key-value database hosted by a cloud provider, often tuned for storing values around a few kilobytes in size. There are a ton of different providers with different pricing schemes like <a href="https://aws.amazon.com/free/storage/">Amazon S3</a>, <a href="https://www.backblaze.com/b2/cloud-storage.html">Backblaze B2</a>, and <a href="https://wasabi.com/">Wasabi</a>. All of them are capable of storing terabytes of data, and many also offer geographic redundancy.</p>
    <div>
      <h3>Data Layer</h3>
      <a href="#data-layer">
        
      </a>
    </div>
    <p>One of the requirements that was important to me was that it shouldn’t be necessary to download and decrypt an entire file before being able to read a part of it. One place where this matters is audio and video files, because it enables playback to start quickly. Another case is ZIP files: a lot of file browsers have the ability to explore compressed archives, like ZIP files, without decompressing them. To enable this functionality, the browser needs to be able to read a specific part of the archive file, decompress just that part, and then move somewhere else.</p><p>Internally, UtahFS never stores objects that are larger than a configured size (32 kilobytes, by default). If a file has more than that amount of data, the file is broken into multiple objects which are connected by a <a href="https://en.wikipedia.org/wiki/Skip_list">skip list</a>. A skip list is a slightly more complicated version of a <a href="https://en.wikipedia.org/wiki/Linked_list">linked list</a> that allows a reader to move to a random position quickly by storing additional pointers in each block that point further than just one hop ahead.</p><p>When blocks in a skip list are no longer needed, because a file was deleted or truncated, they’re added to a special “trash” linked list. Elements of the trash list can then be recycled when blocks are needed somewhere else, to create a new file or write more data to the end of an existing file, for example. This maximizes reuse and means new blocks only need to be created when the trash list is empty. Some readers might recognize this as the Linked Allocation strategy described in The Art of Computer Programming: Volume 1, section 2.2.3!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6Bnd1jOzfzii7HcP4IWI51/6cb2736762a219e51eaf3769387f2396/IMG_0428-5.jpg" />
            
            </figure><p>The reason for using Linked Allocation is fundamentally that it’s the most efficient for most operations. But also, it’s the approach for allocating memory that’s going to be most compatible with the cryptography we talk about in the next three sections.</p>
    <div>
      <h3>Encryption Layer</h3>
      <a href="#encryption-layer">
        
      </a>
    </div>
    <p>Now that we’ve talked about how files are broken into blocks and connected by a skip list, we can talk about how the data is actually protected. There are two aspects to this:</p><p>The first is <b>confidentiality</b>, which hides the contents of each block from the storage provider. This is achieved simply by encrypting each block with AES-GCM, with a key derived from the user’s password.</p><p>While simple, this scheme doesn’t provide <i>forward secrecy</i> or <i>post-compromise security</i>. Forward Secrecy means that if the user’s device was compromised, an attacker wouldn’t be able to read deleted files. Post-Compromise Security means that once the user’s device is no longer compromised, an attacker wouldn’t be able to read new files. Unfortunately, providing either of these guarantees means storing cryptographic keys on the user’s device that would need to be synchronized between devices and, if lost, would render the archive unreadable.</p><p>This scheme also doesn’t protect against <i>offline password cracking</i>, because an attacker can take any of the encrypted blocks and keep guessing passwords until they find one that works. This is somewhat mitigated by using <a href="https://en.wikipedia.org/wiki/Argon2">Argon2</a>, which makes guessing passwords more expensive, and by recommending that users choose strong passwords.</p><p>I'm definitely open to improving the encryption scheme in the future, but considered the security properties listed above too difficult and fragile for the initial release.</p>
    <div>
      <h3>Integrity Layer</h3>
      <a href="#integrity-layer">
        
      </a>
    </div>
    <p>The second aspect of data protection is <b>integrity</b>, which ensures the storage provider hasn’t changed or deleted anything. This is achieved by building a Merkle Tree over the user’s data. Merkle Trees are described in-depth in our <a href="/introducing-certificate-transparency-and-nimbus/">blog post about Certificate Transparency</a>. The root hash of the Merkle Tree is associated with a version number that’s incremented with each change, and both the root hash and the version number are authenticated with a key derived from the user’s password. This data is stored in two places: under a special key in the object storage database, and in a file on the user’s device.</p><p>Whenever the user wants to read a block of data from the storage provider, they first request the root stored remotely and check that it’s either the same as what they have on disk, or has a greater version number than what’s on disk. Checking the version number prevents the storage provider from reverting the archive to a previous (valid) state undetected. Any data which is read can then be verified against the most recent root hash, which prevents any other types of modifications or deletions.</p><p>Using a Merkle Tree here has the same benefit as it does for Certificate Transparency: it allows us to verify individual pieces of data without needing to download and verify <i>everything</i> at once. Another common tool used for data integrity is called a Message Authentication Code (or MAC), and while it’s a lot simpler and more efficient, it doesn’t have a way to do only partial verification.</p><p>The one thing our use of Merkle Trees doesn’t protect against is <i>forking</i>, where the storage provider shows different versions of the archive to different users. However, detecting forks would require some kind of gossip between users, which is beyond the scope of the initial implementation for now.</p>
    <div>
      <h3>Hiding Access Patterns</h3>
      <a href="#hiding-access-patterns">
        
      </a>
    </div>
    <p><a href="https://en.wikipedia.org/wiki/Oblivious_RAM">Oblivious RAM</a>, or ORAM, is a cryptographic technique for reading and writing to random-access memory in a way that hides which operation was performed (a read, or a write) and to which part of memory the operation was performed, from the memory itself! In our case, the ‘memory’ is our <a href="https://www.cloudflare.com/developer-platform/products/r2/">object storage provider</a>, which means we’re hiding from them which pieces of data we’re accessing and why. This is valuable for defending against <i>traffic analysis attacks</i>, where an adversary with detailed knowledge of a system like UtahFS can look at the requests it makes, and infer the contents of encrypted data. For example, they might see that you <i>upload</i> data at regular intervals and almost never <i>download</i>, and infer that you’re storing automated backups.</p><p>The simplest implementation of ORAM would consist of always reading the entire memory space and then rewriting the entire memory space with all new values, any time you want to read or write an individual value. An adversary looking at the pattern of memory accesses wouldn’t be able to tell which value you actually wanted, because you always touch everything. This would be incredibly inefficient, however.</p><p>The construction we actually use, which is called <a href="https://eprint.iacr.org/2013/280.pdf">Path ORAM</a>, abstracts this simple scheme a little bit to make it more efficient. First, it organizes the blocks of memory into a binary tree, and second, it keeps a client-side table that maps application-level pointers to random leafs in the binary tree. The trick is that a value is allowed to live in any block of memory that’s on the path between its assigned leaf and the root of the binary tree.</p><p>Now, when we want to lookup the value that a pointer goes to, we look in our table for its assigned leaf, and read all the nodes on the path between the root and that leaf. The value we’re looking for should be on this path, so we already have what we need! And in the absence of any other information, all the adversary saw is that we read a random path from the tree.</p><p>What looks like a random path is read from the tree, that ends up containing the data we're looking for.</p><p>However, we still need to hide whether we’re reading or writing, and to re-randomize some memory to ensure this lookup can’t be linked with others we make in the future. So to re-randomize, we assign the pointer we just read to a new leaf and move the value from whichever block it was stored in before to a block that’s a parent of both the new and old leaves. (In the worst case, we can use the root block since the root is a parent of everything.) Once the value is moved to a suitable block and done being consumed/modified by the application, we re-encrypt all the blocks we fetched and write them back to memory. This puts the value in the path between the root and its new leaf, while only changing the blocks of memory we’ve already fetched.</p><p>This construction is great because we’ve only had to touch the memory assigned to a single random path in a binary tree, which is a logarithmic amount of work relative to the total size of our memory. But even if we read the same value again and again, we’ll touch completely random paths from the tree each time! There’s still a performance penalty caused by the additional memory lookups though, which is why ORAM support is optional.</p>
    <div>
      <h3>Wrapping Up</h3>
      <a href="#wrapping-up">
        
      </a>
    </div>
    <p>Working on this project has been really rewarding for me because while a lot of the individual layers of the system seem simple, they’re the result of a lot of refinement and build up into something complex quickly. It was difficult though, in that I had to implement a lot of functionality myself instead of reuse other people’s code. This is because building end-to-end encrypted systems requires carefully integrating security into every feature, and the only good way to do that is from the start. I hope UtahFS is useful for others interested in secure storage.</p> ]]></content:encoded>
            <category><![CDATA[Encryption]]></category>
            <category><![CDATA[Developers]]></category>
            <guid isPermaLink="false">5un9hPBwEvXsmyek9NjHff</guid>
            <dc:creator>Brendan McMillion</dc:creator>
        </item>
        <item>
            <title><![CDATA[Continuing to Improve our IPFS Gateway]]></title>
            <link>https://blog.cloudflare.com/continuing-to-improve-our-ipfs-gateway/</link>
            <pubDate>Wed, 19 Jun 2019 13:00:00 GMT</pubDate>
            <description><![CDATA[ When we launched our InterPlanetary File System (IPFS) gateway last year we were blown away by the positive reception.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>When we launched our InterPlanetary File System (IPFS) gateway <a href="/distributed-web-gateway/">last year</a> we were blown away by the positive reception. Countless people gave us valuable suggestions for improvement and made open-source contributions to make serving content through our gateway easy (many captured in our <a href="https://developers.cloudflare.com/distributed-web/">developer docs</a>). Since then, our gateway has grown to regularly handle over a thousand requests per second, and has become the primary access point for several IPFS websites.</p><p>We’re committed to helping grow IPFS and have taken what we have learned since our initial release to improve our gateway. So far, we’ve done the following:</p>
    <div>
      <h3>Automatic Cache Purge</h3>
      <a href="#automatic-cache-purge">
        
      </a>
    </div>
    <p>One of the ways we tried to improve the performance of our gateway when we initially set it up was by setting really high cache TTLs. After all, content on IPFS is largely meant to be static. The complaint we heard though, was that site owners were frustrated at wait times upwards of several hours for changes to their website to propagate.</p><p>The way an IPFS gateway knows what content to serve when it receives a request for a given domain is by looking up the value of a TXT record associated with the domain – the DNSLink record. The value of this TXT record is the hash of the <b>entire</b> site, which changes if any one bit of the website changes. So we wrote a <a href="https://www.cloudflare.com/products/cloudflare-workers/">Worker</a> script that makes a DNS-over-HTTPS query to 1.1.1.1 and bypasses cache if it sees that the DNSLink record of a domain is different from when the content was originally cached.</p><p>Checking DNS gives the illusion of a much lower cache TTL and usually adds less than 5ms to a request, whereas revalidating the cache with a request to the origin could take anywhere from 30ms to 300ms. And as an additional usability bonus, the 1.1.1.1 cache automatically purges when Cloudflare customers change their DNS records. Customers who don’t manage their DNS records with us can purge their cache using <a href="https://1.1.1.1/purge-cache/">this tool</a>.</p>
    <div>
      <h3>Beta Testing for Orange-to-Orange</h3>
      <a href="#beta-testing-for-orange-to-orange">
        
      </a>
    </div>
    <p>Our gateway was originally based on a feature called <a href="https://support.cloudflare.com/hc/en-us/articles/217371987-Managing-Custom-Hostnames-SSL-for-SaaS-">SSL for SaaS</a>. This tweaks the way our edge works to allow anyone, Cloudflare customers or not, to CNAME their own domain to a target domain on our network, and have us send traffic we see for their domain to the target domain’s origin. SSL for SaaS keeps valid certificates for these domains in the Cloudflare database (hence the name), and applies the target domain’s configuration to these requests (for example, enforcing Page Rules) before they reach the origin.</p><p>The great thing about SSL for SaaS is that it doesn’t require being on the Cloudflare network. New people can start serving their websites through our gateway with their existing DNS provider, instead of migrating everything over. All Cloudflare settings are inherited from the target domain. This is a huge convenience, but also means that the source domain can’t customize their settings even if they do migrate.</p><p>This can be improved by an experimental feature called Orange-to-Orange (O2O) from the Cloudflare Edge team. O2O allows one zone on Cloudflare to CNAME to another zone, and apply the settings of both zones in layers. For example, cloudflare-ipfs.com has <b>Always Use HTTPS</b> turned off for various reasons, which means that every site served through our gateway also does. O2O allows site owners to override this setting by enabling <b>Always Use HTTPS</b> just for their website, if they know it’s okay, as well as adding custom Page Rules and Worker scripts to embed all sorts of complicated logic.</p><p>If you are on an Enterprise plan and would like to try this out on your domain, please reach out to. your account team with this request and we'll enable it for you in the coming weeks.</p>
    <div>
      <h3>Subdomain-based Gateway</h3>
      <a href="#subdomain-based-gateway">
        
      </a>
    </div>
    <p>To host an application on IPFS it’s pretty much essential to have a custom domain for your app. We discussed all the reasons for this in our post, <a href="/e2e-integrity/">End-to-End Integrity with IPFS</a> – essentially saying that because browsers only sandbox websites at the domain-level, serving an app directly from a gateway’s URL is not secure because another (malicious) app could steal its data.</p><p>Having a custom domain gives apps a secure place to keep user data, but also makes it possible for whoever controls the DNS for the domain to change a website’s content without warning. To provide both a secure context to apps as well as eternal immutability, Cloudflare set up a subdomain-based gateway at cf-ipfs.com.</p><p>cf-ipfs.com doesn’t respond to requests to the root domain, only at subdomains, where it interprets the subdomain as the hash of the content to serve. This means a request to https://.cf-ipfs.com is the equivalent of going to <a href="https://cloudflare-ipfs.com/ipfs/">https://cloudflare-ipfs.com/ipfs/</a>. The only technicality is that because domain names are case-insensitive, the hash must be re-encoded from Base58 to Base32. Luckily, the standard IPFS client provides a utility for this!</p><p>As an example, we’ll take the classic Wikipedia mirror on IPFS:<a href="https://cloudflare-ipfs.com/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/">https://cloudflare-ipfs.com/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/</a></p><p>First, we convert the hash, <code>QmXoyp...6uco</code> to base32:</p>
            <pre><code>$ ipfs cid base32 QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco
bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq</code></pre>
            <p>which tells us we can go here instead:</p><p><a href="https://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq.cf-ipfs.com/wiki/">https://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq.cf-ipfs.com/wiki/</a></p><p>The main downside of the subdomain approach is that for clients without <a href="/encrypted-sni/">Encrypted SNI</a> support, the hash is leaked to the network as part of the TLS handshake. This can be bad for privacy and enable <a href="https://www.bleepingcomputer.com/news/security/south-korea-is-censoring-the-internet-by-snooping-on-sni-traffic/">network-level censorship</a>.</p>
    <div>
      <h3>Enabling Session Affinity</h3>
      <a href="#enabling-session-affinity">
        
      </a>
    </div>
    <p>Loading a website usually requires fetching more than one asset from a backend server, and more often than not, “more than one” is more like “more than a dozen.” When that website is being loaded over IPFS, it dramatically improves performance when the IPFS node can make one connection and re-use it for all assets.</p><p>Behind the curtain, we run several IPFS nodes to reduce the likelihood of an outage and improve throughput. Unfortunately, with the way it was originally setup, each request for a different asset on a website would likely go to a different IPFS node and all those connections would have to be made again.</p><p>We fixed this by replacing the original backend load balancer with our own <a href="https://www.cloudflare.com/load-balancing/">Load Balancing</a> product that supports Session Affinity and automatically directs requests from the same user to the same IPFS node, minimizing redundant network requests.</p>
    <div>
      <h3>Connecting with Pinata</h3>
      <a href="#connecting-with-pinata">
        
      </a>
    </div>
    <p>And finally, we’ve configured our IPFS nodes to maintain a persistent connection to the nodes run by <a href="https://pinata.cloud/">Pinata</a>, a company that helps people pin content to the IPFS network. Having a persistent connection significantly improves the performance and reliability of requests to our gateway, for content on their network. Pinata has written their own blog post, which you can find <a href="https://medium.com/pinata/how-to-easily-host-a-website-on-ipfs-9d842b5d6a01">here</a>, that describes how to upload a website to IPFS and keep it online with a combination of Cloudflare and Pinata.</p><p>As always, we look forward to seeing what the community builds on top of our work, and hearing about how else Cloudflare can improve the Internet.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7jxOs3MCZyCfTxalFujmdZ/90734a85f553cb3903e3b6338758811f/image2-5.png" />
            
            </figure> ]]></content:encoded>
            <category><![CDATA[Crypto Week]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[IPFS]]></category>
            <category><![CDATA[1.1.1.1]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">2v3Nrp3CmcVKRsqyifM9un</guid>
            <dc:creator>Brendan McMillion</dc:creator>
        </item>
        <item>
            <title><![CDATA[Tracing Soon-to-Expire Federal .gov Certificates with CT Monitors]]></title>
            <link>https://blog.cloudflare.com/tracing-soon-to-expire-federal-gov-certificates-with-ct-logs/</link>
            <pubDate>Wed, 23 Jan 2019 09:13:59 GMT</pubDate>
            <description><![CDATA[ As of December 22, 2018, parts of the US Government have “shut down” because of a lapse in appropriation.  ]]></description>
            <content:encoded><![CDATA[ <p>As of December 22, 2018, parts of the US Government have “shut down” because of a lapse in appropriation. The shutdown has caused the furlough of employees across the government and has affected federal contracts. An unexpected side-effect of this shutdown has been the expiration of TLS certificates on some .gov websites. This side-effect has emphasized a common issue on the Internet: the usage of expired certificates and their erosion of trust.</p><p>For an entity to provide a secure website, it needs a valid <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> attached to the website server. These TLS certificates have both start dates and expiry dates. Normally certificates are renewed prior to their expiration. However, if there’s no one to execute this process, then websites serve expired certificates--a poor security practice.</p><p>This means that people looking for government information or resources may encounter alarming error messages when visiting important .gov websites:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/JWkU4QPny2yCHCF0ddOvo/36f3a3cc60f50843456a51f1256f079c/cert_expired.png" />
            
            </figure><p>The content of the website hasn’t changed; it’s just the cryptographic exchange that’s invalid (an expired certificate can’t be validated). These expired certificates present a trust problem. Certificate errors often dissuade people from accessing a website, and imply that the site is not to be trusted. Browsers purposefully make it difficult to continue to an insecure website by hiding the “proceed” option under an “Advanced Settings/Actions” button. In the example above, people seeking aid in the wake of a natural disaster may not be able to access government websites with crucial information.</p><p>Converse to the situation above, some Internet users may get desensitized to certificate error messages. Seeing expired certificates on otherwise trusted websites will teach users to dismiss certificate errors and bypass them even when a certificate (and website) is genuinely unsafe. Moreover, keys should be rotated on a regular basis to minimize the amount of traffic made vulnerable by a key breach. To use expired certificates is to extend the use of a public-private key pair beyond its expected lifetime, and opens up more traffic to potential snooping.</p>
    <div>
      <h3>Tracking Expired .gov Certificates Using Certificate Transparency Monitors</h3>
      <a href="#tracking-expired-gov-certificates-using-certificate-transparency-monitors">
        
      </a>
    </div>
    <p><a href="https://techcrunch.com/2019/01/17/federal-https-domains-expire-government-shutdown/">TechCrunch recently published a list</a> of soon-to-expire certificates for .gov domains. To create this list, they iterated over a dataset of all federal .gov domains furnished by 18F, the federal government’s digital services unit. For each .gov domain on the list, they pulled its certificate and checked its expiration date. They then filtered out the state and local government .gov domains.</p><p>Relying on 18F for this list, however, introduces a single point of failure. What if 18F’s list was not up-to-date? What if 18F was shut down? What if 18F’s list is not conclusive? (Their list actually does not include .gov subdomains). One organization alone cannot be the provider of all truth about federal .gov sites. Third-party collections of .gov certificates would bolster the thoroughness and availability of expired certificate information.</p><p>Cloudflare's Certificate Transparency (CT) monitor, <a href="http://merkle.town">Merkle Town</a>, is one such third-party. Around the same time as TechCrunch did its research, Cloudflare used Merkle Town to find .gov certificates under imminent expiration. CT monitors are one part of the Certificate Transparency ecosystem. Certificate Transparency <b>Logs</b> are used to store all issued certificates on the Internet and hold Certificate Authorities accountable for the certificates they issue. This means that CT logs hold all issued .gov certificates, so one can consult them for an exhaustive list. Certificate Transparency <b>Monitors</b>, on the other hand, help keep the CT logs accountable as well as make their raw bulk data useful to the general public. In addition to Merkle Town, <a href="https://crt.sh/">crt.sh</a> and <a href="https://sslmate.com/certspotter/">Cert Spotter</a> are other examples of monitors.</p>
    <div>
      <h3>The Nitty-Gritty</h3>
      <a href="#the-nitty-gritty">
        
      </a>
    </div>
    <p>All the certificates that our monitor extracts from crawling CT logs are stored in an <a href="https://en.wikipedia.org/wiki/Apache_HBase">HBase</a> table. HBase is a database similar to Google’s Bigtable, and is designed for storing large amounts of data and running <a href="https://en.wikipedia.org/wiki/MapReduce">MapReduce</a> jobs. Using the MapReduce model, we wrote a small amount of code to look at each row of the database, parse the stored certificate and check if (1) it’s valid for a domain ending in “.gov” and (2) will expire in the next two months.</p><p>If (1) and (2) are true, the hostname, the name of the issuing certificate authority, and the expiration date were output.</p><p>Once the code was deployed, it took 90 minutes to scan over 1 billion unique certificates stored in all CT logs. This means that it was processing roughly 200,000 certificates per second!</p><p>The MapReduce job gave us an initial and comprehensive list. But just because a certificate was issued by a CA doesn’t mean that it’s being served. We did a second pass over the first list, this time actually contacting each domain and trying to complete a TLS handshake and observing if the old certificate was still being served. If so, the hostname was kept in the final list. If the handshake succeeded but a new certificate was being served, we discarded the hostname. If the handshake failed, the hostname was excluded and the error message was noted.</p><p>In our final dataset, we filter out .gov domains that correspond to state and local governments, as well as those federal government domains that appear to have been funded by earlier appropriations.</p><p><a href="https://docs.google.com/spreadsheets/d/1noWXyWA3PKHZ79F8HlE3AdX7HCscMrY8UKObYjUiZTI/edit?usp=sharing">Our results can be found here</a>.</p>
    <div>
      <h3>Unexpected Mis-Configurations</h3>
      <a href="#unexpected-mis-configurations">
        
      </a>
    </div>
    <p>As expected, a significant number of hostnames were excluded by the second pass because they had updated their certificates already. Another smaller number of hostnames were also excluded because those websites were unreachable or no longer operational. However, we also found many more hostnames than we expected with mis-configured TLS, even though they’re websites that seem to be for public consumption.</p><p>An example of this is <a href="https://cableplant.boulder.noaa.gov">https://cableplant.boulder.noaa.gov</a> which currently fails to load with this error:</p><blockquote><p>An error occurred during a connection to cableplant.boulder.noaa.gov. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG</p></blockquote><p>A subtler issue we found was with <a href="https://www.indianaffairs.gov/">https://www.indianaffairs.gov/</a> and <a href="https://www.volunteer.gov/">https://www.volunteer.gov/</a>. Our script was unable to validate the certificate chain for these websites, even though these websites seem to load fine in a browser. The reason is that these websites omit parts of their certificate chain which are necessary to verify that the certificate comes from a publicly trusted authority.</p><p>To improve page load times, browsers will often cache partial certificate chains on-disk. So even if a website does not send all of the necessary certificates, the browser may find what it needed in its cache, which has been well-populated by previous browsing activity. This is still just <b>cache</b>, though. It cannot be relied upon. In my case, after clearing my browser history, both of the websites above become inaccessible, same as for the script.</p>
    <div>
      <h3>How Can Domains Stop Presenting Expired Certificates?</h3>
      <a href="#how-can-domains-stop-presenting-expired-certificates">
        
      </a>
    </div>
    <p>The presence of .gov expired certificates means that either (1) .gov certificates are manually renewed, or (2) .gov certificates cost money to renew, and the shutdown prevented spending on this important web security measure.</p><p><a href="https://www.cloudflare.com/application-services/solutions/certificate-lifecycle-management/">Automatic certificate issuance</a> has become a standard for many domains, and services like Cloudflare offer automatic certificate renewal when you use <a href="https://www.cloudflare.com/ssl/">Universal SSL</a> or get a Cloudflare-issued certificate. CAs like Let’s Encrypt also offer automatic certificate renewal, which works as long as you run the certbot daemon on your webserver. Furthermore, automatic certificate renewal is free with both of these approaches.</p><p>Automating certificate renewals makes expired certificates and mis-configured TLS a problem of the past. We hope that this interesting blip with a few .gov certificates has encouraged domain owners to automate their certificate handling. If you haven’t automated your domain’s certificate renewal, try Universal SSL or Cloudflare certificates today!</p><p><i>Many thanks to Alissa Starzak for her help in filtering .gov domains for this blog post.</i></p> ]]></content:encoded>
            <category><![CDATA[Politics]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Certificate Transparency]]></category>
            <guid isPermaLink="false">2VrdkIKoAUkcr4YHi0n8DW</guid>
            <dc:creator>Gabbi Fisher</dc:creator>
            <dc:creator>Brendan McMillion</dc:creator>
        </item>
        <item>
            <title><![CDATA[End-to-End Integrity with IPFS]]></title>
            <link>https://blog.cloudflare.com/e2e-integrity/</link>
            <pubDate>Mon, 17 Sep 2018 13:02:00 GMT</pubDate>
            <description><![CDATA[ Use Cloudflare’s IPFS gateway to set up a website which is end-to-end secure, while maintaining the performance and reliability benefits of being served from Cloudflare’s edge network. ]]></description>
            <content:encoded><![CDATA[ <p>This post describes how to use Cloudflare's IPFS gateway to set up a website which is end-to-end secure, while maintaining the performance and reliability benefits of being served from Cloudflare’s edge network. If you'd rather read an introduction to the concepts behind IPFS first, you can find that in <a href="/distributed-web-gateway/">our announcement</a>. Alternatively, you could skip straight to the <a href="https://developers.cloudflare.com/distributed-web/">developer docs</a> to learn how to set up your own website.</p><p>By 'end-to-end security', I mean that neither the site owner nor users have to trust Cloudflare to serve the correct documents, like they do now. This is similar to how using HTTPS means you don't have to trust your ISP to not modify or inspect traffic.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6TAh0shMDYcLioHSrr05YS/9df521abdbf0ddc64596066f864466a4/ipfs-blog-post-image-1-copy_3.5x--1-.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/75MIGMU5KJSYIZudpdJcNM/666111e79475ef39ca6701ad7e0cc27e/ipfs-blog-post-image-2-copy_3.5x--1-.png" />
            
            </figure>
    <div>
      <h3>CNAME Setup with Universal SSL</h3>
      <a href="#cname-setup-with-universal-ssl">
        
      </a>
    </div>
    <p>The first step is to choose a <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name/">domain name</a> for your website. Websites should be given their own domain name, rather than served directly from the gateway by root hash, so that they are considered a distinct origin by the browser. This is primarily to prevent cache poisoning, but there are several functional advantages as well. It gives websites their own instance of localStorage and their own cookie jar which are sandboxed from inspection and manipulation by malicious third-party documents. It also lets them run Service Workers without conflict, and request special permissions of the user like access to the webcam or GPS. But most importantly, having a domain name makes a website easier to identify and remember.</p><p>Now that you've <a href="https://www.cloudflare.com/products/registrar/">chosen a domain</a>, rather than using it as-is, you’ll need to add "ipfs-sec" as the left-most subdomain. So for example, you'd use "ipfs-sec.example.com" instead of just "example.com". The ipfs-sec subdomain is special because it signals to the user and to their browser that your website is capable of being served with end-to-end integrity.</p><p>In addition to that, ipfs-sec domains require <a href="/dnssec-an-introduction/">DNSSEC</a> to be properly setup to prevent spoofing. Unlike with standard HTTPS, where DNS spoofing can't usually result in a on-path attacker attack, this is exactly what DNS spoofing does to IPFS because the root hash of the website is stored in DNS. Many <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name-registrar/">registrars</a> make enabling DNSSEC as easy as the push of a button, though some don't support it at all.</p><p>With the ipfs-sec domain, you can now follow the <a href="https://developers.cloudflare.com/distributed-web/ipfs-gateway/connecting-website/">developer documentation</a> on how to serve a generic static website from IPFS. Note that you'll need to use a CNAME setup and retain control of your <a href="https://www.cloudflare.com/learning/dns/what-is-dns/">DNS</a>, rather than the easier method of just signing up for Cloudflare. This helps maintain a proper separation between the party managing the DNSSEC signing keys and the party serving content to end-users. Keep in mind that CNAME setups tend to be problematic and get into cases that are difficult to debug, which is why we reserve them for technically sophisticated customers.</p><p>You should now be able to access your website over HTTP and HTTPS, backed by our gateway.</p>
    <div>
      <h3>Verifying what the Gateway Serves</h3>
      <a href="#verifying-what-the-gateway-serves">
        
      </a>
    </div>
    <p>HTTPS helps makes sure that nobody between the user and Cloudflare's edge network has tampered with the connection, but it does nothing to make sure that Cloudflare actually serves the content the user asked for. To solve this, we built two connected projects: a modified gateway service and a browser extension.</p><p>First, we <a href="https://github.com/cloudflare/go-ipfs">forked the go-ipfs repository</a> and gave it the ability to offer cryptographic proofs that it was serving content honestly, which it will do whenever it sees requests with the HTTP header <code>X-Ipfs-Secure-Gateway: 1</code>. The simplest case for this is when users request a single file from the gateway by its hash -- all the gateway has to do is serve the content and any metadata that might be necessary to re-compute the given hash.</p><p>A more complicated case is when users request a file from a directory. Luckily, directories in IPFS are just files containing a mapping from file name to the hash of the file, and very large directories can be transparently split up into several smaller files, structured into a search tree called a <a href="https://idea.popcount.org/2012-07-25-introduction-to-hamt/">Hash Array Mapped Trie (HAMT)</a>. To convince the client that the gateway is serving the contents of the correct file, the gateway first serves the file corresponding to the directory, or every node in the search path if the directory is a HAMT. The client can hash this file (or search tree node), check that it equals the hash of the directory they asked for, and look up the hash of the file they want from within the directory's contents. The gateway then serves the contents of the requested file, which the client can now verify because it knows the expected hash.</p><p>Finally, the most complicated case by far is when the client wants to access content by domain name. It's complicated because the protocol for authenticating DNS, called DNSSEC, has very few client-side implementations. DNSSEC is also not widely deployed, even though some registrars make it even easier than setting up HTTPS. In the end, we ended up writing our own simple DNSSEC-validating resolver that's capable of outputting a cryptographically-convincing proof that it did some lookup correctly.</p><p>It works the same way as certificate validation in HTTPS: we start at the bottom, with a signature from some authority claiming to be example.com over the DNS records they want us to serve. We then lookup a delegation (DS record) from an authority claiming to be .com, that says "example.com is the authority with these public keys" which is in turn signed by the .com authority's private key. And finally, we lookup a delegation from the root authority, ICANN (whose public keys we already have), attesting to the public keys used by the .com authority. All of these lookups bundled together form an authenticated chain starting at ICANN and ending at the exact records we want to serve. These constitute the proof.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4qVP41QjM9flXihnLEj4CH/441ee5dd840fbac451e12854248da9cd/IPFS-tech-post-_3.5x.png" />
            
            </figure><p><i>Chain of trust in DNSSEC.</i></p><br /><p>The second project we built out was a browser extension that requests these proofs from IPFS gateways and ipfs-sec domains, and is capable of verifying them. The extension uses the <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest">webRequest API</a> to sit between the browser's network stack and its rendering engine, preventing any unexpected data from being show to the user or unexpected code from being executed. The code for the browser extension is <a href="https://github.com/cloudflare/ipfs-ext">available on Github</a>, and can be installed through <a href="https://addons.mozilla.org/en-US/firefox/addon/cloudflare-ipfs-validator/">Firefox's add-on store</a>. We’re excited to add support for Chrome as well, but that can’t move forward until <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=487422">this ticket</a> in their bug tracker is addressed.</p><p>On the other hand, if a user doesn't have the extension installed, the gateway won't see the <code>X-Ipfs-Secure-Gateway</code> header and will serve the page like a normal website, without any proofs. This provides a graceful upgrade path to using IPFS, either through our extension that uses a third-party gateway or perhaps another browser extension that runs a proper IPFS node in-browser.</p>
    <div>
      <h3>Example Application</h3>
      <a href="#example-application">
        
      </a>
    </div>
    <p>My favorite website on IPFS so far has been the <a href="https://cloudflare-ipfs.com/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/">mirror of English Wikipedia</a> put up by <a href="https://ipfs.io/blog/24-uncensorable-wikipedia/">the IPFS team at Protocol Labs</a>. It's fast, fun to play with, and above all has practical utility. One problem that stands out though, is that the mirror has no search feature so you either have to know the URL of the page you want to see or try to find it through Google. The <a href="https://ipfs.io/ipfs/QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX/wiki/Anasayfa.html">Turkish-language mirror</a> has in-app search but it requires a call to a dynamic API on the same host, and doesn't work through Cloudflare's gateway because we only serve static content.</p><p>I wanted to provide an example of the kinds of secure, performant applications that are possible with IPFS, and this made building a search engine seem like a prime candidate. Rather than steal Protocol Labs' idea of 'Wikipedia on IPFS', we decided to take the <a href="http://www.kiwix.org/">Kiwix</a> archives of all the different StackExchange websites and build a distributed search engine on top of that. You can play with the finished product here: <a href="https://ipfs-sec.stackexchange.cloudflare-ipfs.com">ipfs-sec.stackexchange.cloudflare-ipfs.com</a>.</p><p>The way it's built is actually really simple, at least as far as search engines go: We build an inverted index and publish it with the rest of each StackExchange, along with a JavaScript client that can read the index and quickly identify documents that are relevant to a user's query. Building the index takes two passes over the data:</p><ol><li><p>The first pass decides what words/tokens we want to allow users to search by. Tokens shouldn't be too popular (like the top 100 words in English), because then the list of all documents containing that token is going to be huge and it's not going to improve the search results anyways. They also shouldn't be too rare (like a timestamp with sub-second-precision), because then the index will be full of meaningless tokens that occur in only one document each. You can get a good estimate of the most frequent K tokens, using only constant-space, with the really simple space-saving algorithm from <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.114.9563&amp;rep=rep1&amp;type=pdf">this paper</a>.</p></li><li><p>Now that the first pass has given us the tokens we want to track, the second pass through the data actually builds the inverted index. That is, it builds a map from every token to the list of documents that contain that token, called a postings list. When a client wants to find only documents that contain some set of words/tokens, they download the list for each individual token and intersect them. It sounds less efficient than it is -- in reality, the postings lists are unnoticeably small (&lt;30kb) even in the worst case. And the browser can 'pipeline' the requests for the postings lists (meaning, send them all off at once) which makes getting a response to several requests about as fast as getting a response to one.</p></li></ol><p>We also store some simple statistics in each postings list to help rank the results. Essentially, documents that contain a query token more often are ranked higher than those that don't. And among the tokens in a query, those tokens that occur in fewer documents have a stronger effect on ranking than tokens that occur in many documents. That's why when I search for <a href="https://ipfs-sec.stackexchange.cloudflare-ipfs.com/crypto/search.html?q=AES+SIV">"AES SIV"</a> the first result that comes back is:</p><ul><li><p><a href="https://ipfs-sec.stackexchange.cloudflare-ipfs.com/crypto/A/question/54413.html">"Why is SIV a thing if MAC-and-encrypt is not the most secure way to go?"</a></p></li></ul><p>while the following is the fourth result, even though it has a higher score and greater number of total hits than first result:</p><ul><li><p><a href="https://ipfs-sec.stackexchange.cloudflare-ipfs.com/crypto/A/question/31835.html">"Why is AES-SIV not used, but AESKW, AKW1?"</a></p></li></ul><p>(AES is a very popular and frequently discussed encryption algorithm, while SIV is a lesser-known way of using AES.)</p><p>But this is what really makes it special: because the search index is stored in IPFS, the user can convince themselves that no results have been modified, re-arranged, or omitted without having to download the entire corpus. There's one small trick to making this statement hold true: All requests made by the search client must succeed, and if they don't, it outputs an error and no search results.</p><p>To understand why this is necessary, think about the search client when it first gets the user's query. It has to tokenize the query and decide which postings lists to download, where not all words in the user's query may be indexed. A naive solution is to try to download the postings list for every word unconditionally, and interpret a non-200 HTTP status code as "this postings list must not exist". In this case, a network adversary could block the search client from being able to access postings lists that lead to undesirable results, causing the client to output misleading search results either through omission or re-arranging.</p><p>What we do instead is store the dictionary of every indexed token in a file in the root of the index. The client can download the dictionary once, cache it, and use it for every search afterwards. This way, the search client can consult the dictionary to find out which requests should succeed and only send those.</p>
    <div>
      <h3>From Here</h3>
      <a href="#from-here">
        
      </a>
    </div>
    <p>We were incredibly excited when we realized the new avenues and types of applications that combining IPFS with Cloudflare open up. Of course, our IPFS gateway and the browser extension we built will need time to mature into a secure and reliable platform. But the ability to securely deliver web pages through third-party hosting providers and CDNs is incredibly powerful, and its something cryptographers and internet security professionals have been working towards for a long time. As much fun as we had building it, we're even more excited to see what you build with it.</p><p><a href="/subscribe/"><i>Subscribe to the blog</i></a><i> for daily updates on our announcements.</i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Zg5pDJxaCCTQXzqquORuu/1a2f514eff601ee0f88f245945a3ea54/CRYPTO-WEEK-banner-plus-logo_2x.png" />
            
            </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Crypto Week]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[IPFS]]></category>
            <category><![CDATA[Universal SSL]]></category>
            <category><![CDATA[SSL]]></category>
            <category><![CDATA[DNSSEC]]></category>
            <category><![CDATA[Cryptography]]></category>
            <guid isPermaLink="false">2ZSYs23n0hZhgRFnzpS5O1</guid>
            <dc:creator>Brendan McMillion</dc:creator>
        </item>
    </channel>
</rss>