Many download sites, especially for software download, give hashes or digests for the file they distribute so that users can check the validity of the files once they've downloaded it. The process for verifying the hash however isn't straightforward. Furthermore, there are other use cases where link hashes might be useful to improve caching or modify the user experience of security.
A lot of software download pages already give you MD5 or SHA-1 digests values to check the validity of the downloaded file. Checking the file ensure that the downloaded file is same as the author of the page wanted to give you. Corrupted or tampered files can be detected that way.
The problem is that there is no way to automate that verification process. To automate this process, a browser would need to extract the hash associated with the link on the original page.
Some links to software download pages featuring hashes:
Hashes on links are used in Metalink, which is implemented by a number of software download products.
Other examples can be found on the hash examples page on the Microformat wiki.
There are a few use cases for link hashes.
The most obvious is easier discoverability of tampered files which could come from a mirror server being hacked. However, the security improvement is limited to the security properties of how the links themselves are conveyed.
Additionally, the failure case needs to be considered; if we use hashes for security and the hashes don't match, how should this affect the page load?
For downloads a browser could display the following message when in case of hash mismatch:
- File "image.iso" is different from the file linked on page "My Software CD Images". It is possible that this file has been tampered with and it'd be advisable to not open it. Do you wish to delete the file?
[Delete File] [Keep in Quarantine]
Displaying a new type of error to users for linked content (e.g., CSS, JS, SVG) probably won't improve security; it'll just be another warning to click through. However, hashes COULD be used to improve the current security experience.
For example, a Web page served over a https:// URL could include hashes for links to assets with http:// URLs; if the hashes match, mixed content warnings might not need to be given.
Another use case is for caching. If a browser has a cached copy of jquery, for example, and a link has a hash that matches the cached copy, it could avoid a request, even if the URL is completely different. The collision resistance and other security properties would obviously need to be carefully specified here, but if the hash doesn't match, it isn't necessary to present the error to the user; you just fetch the URL as per normal.
Hashes would also enable new forms of caching; e.g., a browser could implement a peer-to-peer protocol to ask its peers for URLs that it wants, verifying what it gets from them using the hashes. Again, there are serious privacy and security issues to work through here.
A hash attribute could contain a md5 checksum of the target file. If the hash of the downloaded file does not match the one from the link, the file is deleted or quarantined and the user is alerted of a potential security risk.
<a href="..." hash="b3187253c1667fac7d20bb762ad53967">
As well, algorithm agility would be nice. Brad Hill suggested a syntax like:
<link href="https://www.example.com/foo.css" digest="sha256:ab8e92231...">
When the link is clicked, the browser keeps the hash in memory to compare it with the it hashes from the downloaded file. Once the file is downloaded, the the computed hash is compared against the expected hash.
For links to JS, CSS, etc., where HTML has been fetched over SSL/TLS, a matching hash means that the mixed content warning can be omitted. This might require substantial modification of the fetch to allow content to be downloaded before the policy decision is made.
(The processing model for all of the proposals is largely the same)
The hash microformat provides a way to associate hash values with links:
<span class="download"> <a rel="bookmark" href="...">Download OpenOffice.org <span class="checksum md5">e0d123e5f316bef78bfdf5a008837577</span> </a> </span>
The microformat is better described on the hash-examples page.
When a link is clicked, the browser check if it corresponds to the microformat (details to be added). If it is the hash value is extracted and, once the file is downloaded, the computed hash for the file is compared against the expected hash. Browsers should keep the initial hash value across redirections, if any. This only applies to files downloaded to the disk.
- "Could the syntax be extended so that fragment identifiers could cohabit with fingerprints?"
Append a digest for the file in the fragment identifier of the URL. The browser can then check the validity of the file when it downloads it.
The Link Fingerprints article by Gervase Markham gives more details.
HTTP defines the Content-MD5 HTTP header. However, MD5 has known security flaws, and is not recommended for use.
The Digest HTTP header avoids this by allowing the hash algorithm to be specified.
Both of these approaches are on the response itself, rather than in links -- so they're only able to indicate the integrity of the response they occur within, and are naturally vulnerable to modification in transit and on the server.
Another approach would be using Link headers to indicate hashes for the links in content; this could be useful if you want to add hashes with a server plug-in or a reverse proxy, for example.