Commit 4967e834 authored by sajolida's avatar sajolida
Browse files

Update design documentation

parent 954ab6da
[[!meta title="Download verification"]]
Software verification is a critical step in the use of secure
applications but it has traditionally been hard to provide, especially
from a user experience perspective.
Usual solutions are:
- HTTPS
HTTPS is not enough in the case of Tails because we rely on [[mirrors
hosted by third parties|contribute/design/mirrors]].
Note that all these mirrors already use HTTPS.
HTTPS also doesn't protect from interrupted downloads leading to
broken Tails installations.
- OpenPGP signatures
Unless the user knows how to verify the signing key through the
OpenPGP Web-of-Trust, this technique ultimately relies on a correct
download of the signing key.
Tails provides 3 mechanisms for users to verify the image downloaded
through a third party mirror, while relying on cryptographic information
fetched from our website through HTTPS.
1. JavaScript verification
The main verification mechanism relies on JavaScript code on the
download page. See below for more details.
1. BitTorrent download
The Torrent file downloaded through HTTPS from our website includes a
checksum of the image. BitTorrent clients automatically verify this
checksum when the download finishes.
1. OpenPGP signature
We advertise OpenPGP as an optional verification technique, possibly
done on top of the other 2 techniques and ideally through the OpenPGP
Web-of-Trust. We assume that this technique is only relevant for
people who are already knowledgeable about OpenPGP. As a consequence:
- We only provide simplified instructions on how to perform the
verification, insisting on aspects that might still be relevant for
this public: verification of the date, command line options,
warning when the signing key is not trusted, etc.
- We take more time to develop the verification of the signing key
through the OpenPGP Web of Trust because it is the only technique
that is really stronger than HTTPS.
[[!toc levels=2]]
Related documents
=================
- [[Design document of the installation assistant, including the download page|installation_assistant]]
Scope of the JavaScript verification
====================================
Goals
-----
- Provide a simple, automated, and cross-platform technique to verify
USB and ISO images of the current version of Tails.
- Allow verifying any current Tails image: downloaded over BitTorrent,
copied from a friend, downloaded from one of our mirrors.
Non goals
---------
- Verify deprecated Tails images.
- Verify Tails images downloaded from nightly.tails.boum.org.
Threat model
============
We are considering here an attacker who can:
- [A] Provide a malicious Tails image to the user for example by
operating a rogue Tails mirror.
- [H] Operate a website that is loaded in a different tab in the same
browser. This threat is taken care of by the internals of the
browser and the proper coding of the JavaScript.
We are not considering an attacker who can:
- [B] Do a man-in-the-middle attack by providing a rogue HTTPS certificate
for https://tails.boum.org/ signed by a certificate authority
trusted by the browser but under the control of the attacker.
Since the JavaScript verification is targeted at new users, a MitM or exploit on
our website could defeat any verification technique by providing
simplified instructions or by faking the verification.
Note that our website is already in the [HSTS preload list of major
browsers](https://hstspreload.org/?domain=tails.boum.org), which forces HTTPS connections to our website, even for
first time visitors.
- [C] Insert malicious content on https://tails.boum.org/ through an
exploit on our website as this could trick new users to skip the Tails
image verification all the way. To prevent this kind of attack we
should instead:
- Monitor externally the most relevant parts of our website.
- Work on integrating full upgrades in Tails Upgrader to limit the
number of times people have to rely on our website to upgrade. See
[[!tails_ticket 7499]].
- [D] Insert malicious information in our main Git repository as such
an attacker could do attack [C] as well.
- [E] Insert targeted malware in the user's computer or web browser as this could
defeat any possible verification mechanism that such JavaScript
can do.
For example, we cannot protect from a malicious extension installed
in the web browser.
- [G] Insert malicious content on https://tails.boum.org/ after taking
control of the web server, or entire system, behind it. Such an
attacker could do attack [C] as well but in such a way that could be
much harder to detect (for example by serving malicious content only to
some users).
- [J] Provide a malicious copy of our website on a similar looking URL
that could pretend that verification has succeeded without actually
verifying anything.
Functioning
===========
Image description file
----------------------
When verifying a Tails image, the JavaScript:
1. Downloads an image description file (IDF) from:
<https://tails.boum.org/install/v2/Tails/amd64/stable/latest.json>
The IDF is served with the HTTP headers <span
class="code">`Access-Control-Allow-Origin: *`</span> to allow
developers to test the extension locally from a `file:///` URL.
1. Verifies that the checksum of the image is present in the IDF.
*Forge* library
---------------
The JavaScript uses the
[*Forge*](https://github.com/digitalbazaar/forge/) library to calculate
the checksum.
We chose *Forge* because it was [the fastest in this benchmark of
JavaScript checksum
implementations](https://github.com/brillout/test-javascript-hash-implementations).
We cannot use the native [SubtleCrypto.digest()
API](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest)
because it [cannot use
streams](https://github.com/w3c/webcrypto/issues/73) and would require
loading the entire image in memory before computing its checksum.
We also rely on reading the image as a stream to display the progress
bar, which is really important since the whole verification takes close
to 1 minute.
Browser compatibility
---------------------
- Internet Explorer is not supported because our JavaScript uses the
[readAsBinaryString
API](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString).
- Browsers without JavaScript are instructed to either enable JavaScript
or calculate the checksum using
[[GtkHash|doc/encryption_and_privacy/checksums]].
...@@ -2,16 +2,18 @@ ...@@ -2,16 +2,18 @@
In 2015, we worked on a complete rewrite on our installation In 2015, we worked on a complete rewrite on our installation
instructions. This work was extended in 2017 with the design of a new instructions. This work was extended in 2017 with the design of a new
download page. The archive of our design process as well as pending download page.
issues can be found in the [[corresponding
blueprint|blueprint/bootstrapping/assistant]]. The [artifacts from our design
process](https://gitlab.tails.boum.org/tails/ux/-/tree/master/installation%20assistant)
are stored in Git.
Our previous instructions forced people to jump through many different Our previous instructions forced people to jump through many different
documentation pages and often to figure out by themselves what to do next. See documentation pages and often to figure out by themselves what to do next. See
this [[flowchart of the installation process as of this [flowchart of the installation process as of
2014|blueprint/bootstrapping/2014.fodg]]. 2014](https://gitlab.tails.boum.org/tails/ux/-/raw/master/installation%20assistant/2014.fodg?inline=false).
The objective was to make this a linear process, to be follow step-by-step, and The objective was to make the installation a linear process, to be followed step-by-step, and
that would take the user from our homepage up to starting on a Tails USB stick that would take the user from our homepage up to starting on a Tails USB stick
with a Persistent Storage. But this process has to be adapted to the base with a Persistent Storage. But this process has to be adapted to the base
operating system of the user or their technical expertise. operating system of the user or their technical expertise.
...@@ -52,16 +54,16 @@ The assistant is divided into four sections: ...@@ -52,16 +54,16 @@ The assistant is divided into four sections:
Related documents Related documents
================= =================
- [[Design document of *Tails Installer*|verification_extension]] - [[Design document of *Tails Installer*|installation]]
- [[Design document of *Tails Verification*|verification_extension]] - [[Design document of *Tails Verification*|image_verification]]
- [[Blueprint with archives of the past design processes and notes on future work|blueprint/bootstrapping/assistant]] - [Archive of our design artifacts](https://gitlab.tails.boum.org/tails/ux/-/tree/master/installation%20assistant)
Implementation tricks Implementation tricks
===================== =====================
The installation assistant is basically presenting very similar content in many The installation assistant is presenting very similar content in many
different scenarios with small variations (slightly different steps, slightly different scenarios with small variations: slightly different steps, slightly
different terminology, etc.). different terminology, etc.
To reuse as much content as possible and reduce the quantity of text and To reuse as much content as possible and reduce the quantity of text and
translations, our implementation relies heavily on two tricks. Both are translations, our implementation relies heavily on two tricks. Both are
...@@ -211,29 +213,14 @@ Depending on the installation scenario, the download page points to the ...@@ -211,29 +213,14 @@ Depending on the installation scenario, the download page points to the
download of the ISO image (on `dvd` and `vm`) or the USB image (on all download of the ISO image (on `dvd` and `vm`) or the USB image (on all
other scenarios). other scenarios).
We propose two download techniques displayed in equal weight and combined We propose 2 download techniques displayed in equal weight:
with two verification techniques that have a level of verification at least as
good as HTTPS: a. Direct download.
a. Direct download combined with a browser extension, called *Tails Verification*. See the [[dedicated design b. BitTorrent download.
document|verification_extension]] for a security analysis of this technique.
See our [[design document on download verification]] for a security
b. BitTorrent download. The Torrent file is downloaded through HTTPS analysis of the different verification techniques that we provide.
from our website and BitTorrent clients automatically verifies the download once
completed.
We advertise OpenPGP verification as an optional verification technique,
possibly done on top of the other two techniques and ideally through the
OpenPGP Web-of-Trust. We assume that this technique is only relevant for
people who are already knowledgeable about OpenPGP. As a consequence:
- We only provide simplified instructions on how to perform the
verification, insisting on aspects that might still be relevant for
this public: verification of the date, command line options, warning
when the signing key is not trusted, etc.
- We take more time to develop the verification of the signing key
through the OpenPGP Web of Trust because it is the only technique that is
really stronger than HTTPS.
<a id="steps"></a> <a id="steps"></a>
......
[[!meta title="Tails Verification (browser extension)"]]
Software verification is a critical step in the use of secure
applications but it has traditionally been hard to provide, especially
from a user perspective. Usual solutions are:
- Using HTTPS to download. But in the case of Tails, we are serving so
many downloads that we have to rely on [[mirrors hosted by third
parties|contribute/design/mirrors]]. HTTPS also doesn't protect from interrupted downloads leading to
broken Tails installations.
- Providing OpenPGP signatures. But this really works only for the few
people who know how to verify an OpenPGP signature and use the
OpenPGP Web-of-Trust correctly.
We are trying here to provide a usable solution to verify a download
done through HTTP, while relying on cryptographic information fetched
elsewhere through HTTPS (and possibly with stronger authentication
mechanisms such as public key pinning from browser vendors).
We use for that a browser extension, called
*Tails Verification* which is available for
* Firefox 52+ (and Tor Browser 7+)
* Chrome 57+
i.e. browsers that support WebAPIs, in particular
[FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader),
[Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), and
[async/await](https://caniuse.com/#feat=async-functions).
The code of *Tails Verification* is available in [[!tails_gitweb_repo
verification-extension]].
[[!toc levels=2]]
Related documents
=================
- [[Design document of the installation assistant, including the download page|installation_assistant]]
Scope
=====
Goals
-----
Provide a simple, automated, and cross-platform technique to verify installable
Tails images of the current version, in ISO and disk image format.
Non goals
---------
- Verify deprecated Tails images.
- Verify Tails images downloaded from nightly.tails.boum.org.
- Verify Tails images downloaded through BitTorrent. If we can rely on
our website to provide a correct cryptographic description of the
Tails image then we can rely on it as well to provide a correct
BitTorrent file. Then we rely on the BitTorrent client to verify the integrity of
the download ([[!tails_ticket 9043]]).
However, any current Tails image (downloaded over BitTorrent, copied from a
friend, downloaded from one of our mirrors) can be verified by the extension.
<a id="verification"></a>
Security considerations
=======================
<a id="threat_model"></a>
Threat model
------------
We are considering here an attacker who can:
- [A] Provide a malicious Tails image to the user for example by
operating a rogue Tails mirror.
- [H] Operate a website that is loaded in a different tab in the same
browser as the extension. See the section on [[security inside the
browser|verification_extension#inside_the_browser]].
We are not considering an attacker who can:
- [B] Do a man-in-the-middle attack by providing a rogue HTTPS certificate
for https://tails.boum.org/ signed by a certificate authority
trusted by the browser but under the control of the attacker.
Since the extension is targeted at new users, a MitM or exploit on
our website could defeat any verification technique by providing
simplified instructions or by faking Tails image verification.
Note that our website is already in the HSTS preload list of Firefox
and Chrome which forces HTTPS connections to our website, even for
first time visitors.
- [C] Insert malicious content on https://tails.boum.org/ through an
exploit on our website as this could trick new users to skip the Tails
image verification all the way. To prevent this kind of attack we
should instead:
- Monitor externally the most relevant parts of our website.
- Work on integrating full upgrades in Tails Upgrader to limit the
number of times people have to rely on our website to upgrade. See
[[!tails_ticket 7499]].
- [D] Insert malicious information in our main Git repository as such
an attacker could do attack [C] as well.
- [E] Insert targeted malware on the user's computer as this could
defeat any possible verification mechanism that such an extension
could do.
- [F] Provide a rogue extension to the user as this could defeat any
possible verification mechanism that such an extension could do.
- [G] Insert malicious content on https://tails.boum.org/ after taking
control of the web server, or entire system, behind it. Such an
attacker could do attack [C] as well but in such a way that could be
much harder to detect (for example by serving malicious content only to
some users).
To mitigate such an attack in some cases we could both:
- Encourage external documentation (screencasts on YouTube, printed
forms, etc.). But those would be vulnerable to other kind of
attacks.
- Not rely on the website to perform the Tails image verification and rely
on a native interface accessible from the add-ons menu.
But the cost/benefit of such a technique is not very appealing…
- [I] Provide a malicious extension in the same browser as this would
have similar effects to attack [F].
- [J] Provide a malicious copy of our website on a similar looking URL
that could pretend that verification has succeeded without actually
verifying anything.
<a id="inside_the_browser"></a>
Security inside the browser
---------------------------
The threat described as [H] is taken care of by the internals of the
browser (and the proper coding of the extension).
### Cross-origin communication
The extension uses cross-origin communication to send messages to the download
page.
- To ensure that messages from the extension are only sent to pages on
our website, the extension
sets `targetOrigin` to `https://tails.boum.org` (no trailing slash needed) in
[`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
See commit c87ce92.
- Before processing the message, the download page verifies that it is
coming from:
- The same tab (`event.source` is `window`)
- Our website (`event.origin` is `https://tails.boum.org`, no trailing slash needed)
See [[!tails_gitweb wiki/src/install/inc/js/download.js
desc="`receiveMessage()` in *download.js*"]].
- The code of the extension is loaded via content scripts and targets only tabs
with locations `https://tails.boum.org/install/*` and
`https://tails.boum.org/upgrade/*`. See `permissions` in *manifest.json*.
- On Chrome browsers, a background script reloads tabs with matching URL
schemes (`https://tails.boum.org/install/*` and
`https://tails.boum.org/upgrade/*`) only after the first installation of the
extension, in order to make the extension usable right away. This is
automatically happening in Firefox based browsers, therefore the background
script does not apply.
- The communication is unidirectional: the extension only sends messages
but it does not listen to messages.
### Content Security Policy
The extension uses a Content Security Policy with `default-src 'none'`
and `script-src 'self'`. The latter part has been added because
background scripts are needed by the extension, and require a slightly
less strict CSP. However, this CSP also applies to the content scripts
shipped in the extension.
<a id="update"></a>
Update mechanisms
-----------------
### Automatic update from browsers
- Chrome checks for updates "[every few
hours](https://developer.chrome.com/extensions/autoupdate)".
- Firefox checks for updates once per day.
- Tor Browser doesn't prevent those updates [except for Torbutton and
Tor Launcher](https://lists.torproject.org/pipermail/tbb-dev/2015-April/000258.html).
### Enforce version check on our download page
On top of this, the HTML code of our download page includes a tag to
force a minimum version of the extension. For example:
<pre>
&lt;div id="extension-version"&gt;2.0&lt;/div&gt;
</pre>
*Tails Verification* checks the value of this tag and asks for an
update if its version is lower than the requested version number.
This mechanism might be useful to force updated extensions with a finer
time granularity that the native automatic updates from the browsers.
<a id="technology"></a>
Functioning
===========
Extension technology
--------------------
The extension is written as a *Web Extension* and the same exact code
works on both Firefox and Chrome.
Future plans include abandoning the extension and integrating the code directly
into our website, with the aim of supporting more browsers. [[!tails_ticket
16128]].
<a id="data_source">
Data source
-----------
Building upon the format specified for [[upgrade description
files|contribute/design/incremental_upgrades#upgrade-description-files]],
the verification extension fetches an [[!tails_gitweb
wiki/src/install/v2/Tails/amd64/stable/latest.json desc="image description
file"]] from our server to retrieve all the information it needs about
available Tails images (URL, size, checksum, etc.).
The file format allows to publish several target files, and formats, such as
ISO and IMG.
It currently publishes only information about the current stable supported
Tails release. A more fine grained approach is planned [[!tails_ticket 16200]].
Currently, this image description file is not signed using OpenPGP.
### Example of an image description file
<pre>
{
"build_target": "amd64",
"channel": "stable",
"installations": [
{
"installation-paths": [
{
"target-files": [
{
"sha256": "2ffeacab6ad74671a9eb15b560f47bae7d22e1bcbd9735342ee6d7dfe3c5706e",
"size": 1225568256,
"url": "http://dl.amnesia.boum.org/tails/stable/tails-amd64-3.11/tails-amd64-3.11.iso"
}
],
"type": "iso"
},
{
"target-files": [
{
"sha256": "cafedeadbeaf67213970783432cafe0dead9beefbd9735342ee6d7dfe3c5706e",
"size": 1225765432,
"url": "http://dl.amnesia.boum.org/tails/stable/tails-amd64-3.11/tails-amd64-3.11.img"
}
],
"type": "img"
}
],
"version": "3.11"
}
],
"product-name": "Tails"
}
</pre>
Checksum verification
---------------------
When verifying a Tails image, the extension:
- Downloads the image description document (url, size, checksum) from:
<https://tails.boum.org/install/v2/Tails/amd64/stable/latest.json>
- Verifies the image downloaded (ISO or IMG) against the document (first its
size, then its checksum).
Security properties:
- This technique would defeat attack [A] (malicious Tails image).
More complex verification mechanisms could be gradually built in to
defeat attacks [B], [C], [D], [F], and [G].
Embedded *Forge* library
------------------------
Contrary to its predecessor
([DAVE](https://git.tails.boum.org/download-and-verify-extension)),
*Tails Verification* cannot rely on native API calls to calculate the
checksum. So it embeds the *Forge* library:
<https://github.com/digitalbazaar/forge/>
We chose *Forge* because it was reported as being the fastest in this
benchmark:
<https://github.com/brillout/test-javascript-hash-implementations>
<a id="html">
Manipulation of the download page
---------------------------------
The extension modifies what is displayed on the page using two different
mechanisms:
- Mostly through message communication (`postMessage`) sent to a
script on the page ([[!tails_gitweb wiki/src/install/inc/js/download.js]]).
- If an extension is already installed when the page is loaded, through
an HTML attribute (`documentElement.dataset.extension`) corresponding
to some CSS declarations, to indicate whether the extension is
up-to-date or outdated.
This decouples the code of the extension from the implementation of the
display on the HTML page (ids, classes, etc.).
When JavaScript is disabled, the page instructs the user to temporarily
allow JavaScript on the page (through NoScript, the most likely scenario):
[[!img install/inc/screenshots/allow_js.png link="no"]]