Building A More Trusted Web: Meet Cloudflare SXG (Automatic Signed eXchanGes)

If you don’t know about Cloudflare, then you should, as they provide a range of services which make the Web a more secure and trusted…

Photo by Sebastian Herrmann on Unsplash

Building A More Trusted Web: Meet Cloudflare SXG (Automatic Signed eXchanGes)

If you don’t know about Cloudflare, then you should, as they provide a range of services which make the Web a more secure and trusted place. One of the great things about the company is that they have a great passion for cryptography and continually shares its knowledge with others. Also, Cloudflare has a passion for creating a more trusted Web, and SXG (Automated Signed eXchanges) is one of its newest services for increasing trust in Web content. As code inject still ranks highly in the OWASP Top 10, it is important that we try and address issues related to the modification of content in order to address cybersecurity issues.

So, how can we check that the content we receive from a Web page is the content that was created by the originator and that it has not been modified by a proxy (Eve)? Well, we need to add a digital signature to the content provided, and which verifies both the content and the originator. Normally this is done by the originator signing with their private key, and then the receiver checking the signature against their public key. This public key will be signed by a trusted entity.

An untrusted Internet

The Internet is built mostly on protocols that care little about trust and privacy. When these protocols were being defined, there was a general lack of focus on security. The fix has to generally add in a layer of security — such as with TLS. But this only provides basic checks within the network stack, and where proxies can be used to hide much of the details of an origin. The “blockchain” way is to move to the other end of the spectrum, and where every transaction is trusted with a digital signature.

A break-point for security is the hand-over from one domain to another. In some use cases we need to know that the hand-over is coming from a trusted source, but the normal HTTP responses have little support for properly defining the origin. Now, Cloudflare has developed a new service which overcomes this: Signed Exchanges (SXGs), and which can be used to authenticate the origin of resources and where it does not matter how the resource is delivered.

A cache and signer

Basically, SXG works by using a cache to provide content which has been cryptographically signed by the origin and can be used to verify referer sites while users move from one site to another. For example, an education site (BobnAlice) may only accept referrals from a site within the Trent domain, and where BobnAlice needs to make sure that it was Trent’s site which initiated the navigation and that the content remains unchanged. Within the protocol any information about the user is hidden from Trent’s site, until the hand-over has been verified. There are some major adopters of SXG, including Google who are using it to cache the trusted signing of content from Google Search. For this, they cache SXGs, and do a prefetch on the sites that a user is likely to visit. Typically, this is the first link on a search. This makes the delivery of the content faster, and the verification is already precomputed.

Overall, SXG adds a digital signature to the HTTP exchange. With this, a user who requests a site will send an HTTP request and receive back an HTTP response. The receiving site can then verify the original source of content rather than its provider. And, so, CarolProxy may deliver the content, but where the content will be signed by AlicenBob (as the original source of the content). Trent can then verify that it is the content from AlicenBob, and has not been modified by CarolProxy.

SXG uses a binary encoded file with the HTTP exchange (the requested URL, content negotiation and an HTTP response) and a signature. An example of this [1] is:

format version: 1b3
request:
method: GET
uri: https://example.org/
headers:

response:
status: 200
headers:
Cache-Control: max-age=604800
Digest: mi-sha256-03=kcwVP6aOwYmA/j9JbUU0GbuiZdnjaBVB/1ag6miNUMY=
Expires: Mon, 24 Aug 2020 16:08:24 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: mi-sha256-03
Date: Mon, 17 Aug 2020 16:08:24 GMT
Vary: Accept-Encoding
signature:
label;cert-sha256=*ViFgi0WfQ+NotPJf8PBo2T5dEuZ13NdZefPybXq/HhE=*;
cert-url="https://test.web.app/ViFgi0WfQ-NotPJf8PBo2T5dEuZ13NdZefPybXq_HhE";
date=1597680503;expires=1598285303;integrity="digest/mi-sha256-03";sig=*MEUCIQD5VqojZ1ujXXQaBt1CPKgJxuJTvFlIGLgkyNkC6d7LdAIgQUQ8lC4eaoxBjcVNKLrbS9kRMoCHKG67MweqNXy6wJg=*;
validity-url="https://example.org/webpkg/validity"
header integrity: sha256-Gl9bFHnNvHppKsv+bFEZwlYbbJ4vyf4MnaMMvTitTGQ=


The exchange has a valid signature.
payload [1256 bytes]:
<!doctype html>
<html>
<head>
<title>SXG example</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div>
<h1>Hello</h1>
</div>
</body>
</html>

Within this we see the request and the response, and where

Content-Encoding: mi-sha256

signature:
sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;
integrity="digest/mi-sha256";
validity-url="https://example.com/resource.validity.1511128380";
cert-url="https://example.com/oldcerts";
cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;
date=1511128380; 
expires=1511733180;

With “mi-sha256” we have Merkle Integrity Content Encoding [here][here], and which strongly defines the integrity of the messages. We can see that the response also contains the signature for the content and the location of the digital certificate with the public key to verify this signature. In our case, this will be signed by the BobnAlice domain, and if Trent trusts their public key, the content will be verified as being unchanged and from BobnAlice’s domain. An important field is the expires parameter, and which will define the amount of time that the content will be trusted. This can be up to seven days.

Supported by Chome

Currently, SXG is supported by Chome, and where it is possible to debug the transaction [here]:

Figure [here]

and where we can view the headers [here]:

Figure [here]

Conclusion

The security of the Web is often weak, and the levels of trust can often be breached. SXG provides a way to secure content, rather than just network connections. If someone from the 1980s were to look at the protocols that we use on the Internet, they would see very little change in the core methods. At that time, there was little thought about digital signatures, but the Internet we had then is not the one we have now, and things must change.

References

[1] https://web.dev/signed-exchanges/#speeding-up-page-loads-with-signed-exchanges