[[!meta title="Automatic ISO verification extension for Firefox"]]

As part of our effort to simplify the workflow of a new user getting
started with Tails, we are working on a custom browser extension to
automate some verification of the ISO image after it has been
downloaded.

This has to be considered as part of a bigger plan to:

  - Further automate ISO verification. See the blueprint on [[ISO
    verification|verification]].
  - Guide the user through the whole process. See the blueprint on the
    [[web assistant|assistant]].

The extension will be used as well by people doing full upgrades until
we automate the download and verification steps of a full upgrade in
Tails Upgrader. See the blueprint on [[upgrades|upgrade]].

[[!toc levels=2]]

Vision
======

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.
  - Providing OpenPGP signatures. But this really works only for the few
    of us 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).

Goals
=====

  - Fix the ISO verification method using Windows which has been broken
    for years.
  - Simplify the installation process by automating *some* verification
    of the ISO image inside the browser as part of the download process.
  - Ensure that ISO images are downloaded entirely before trying to
    verify them.
  - In case of an interrupted download, help the user resume it. This
    requires us to have our mirrors stop sending HTTP ETag headers. See
    [[!tails_ticket 9022]].
  - Allow users to install the extension without restarting the browser.
  - Have the extension available in Firefox first, then Chrome. Firefox
    makes sense as a first target because it is the base for Tor Browser
    and is installed by default in Debian and Ubuntu. But Chrome is much
    more popular. Usage share of web browsers are currently on
    [[!wikipedia desc="Wikipedia" Usage_share_of_web_browsers]]:
    - Chrome: 48.1%
    - Internet Explorer: 17.5%
    - Firefox: 16.7%
    - Safari: 4.8%
    - Opera: 1.5%
    - Other: 11.4%

Non goals
=========

  - Verify deprecated ISO images.
  - Verify ISO images downloaded from nightly.tails.boum.org.
  - Verify ISO images downloaded through BitTorrent. If we can rely on
    our website to provide a correct cryptographic description of the
    ISO image then we can rely on it as well to provide a correct
    BitTorrent file. Then BitTorrent clients verify the integrity of
    their downloads and we're good ([[!tails_ticket 9043]]).

<a id="wireframe"></a>

User scenario and wireframe
===========================

  - [[Simplified wireframe|wireframe.pdf]]
  - For the full wireframe, refer to the latest wireframe uploaded on [[!tails_ticket 8564]].

Open questions
--------------

  - Maybe we will display educational material, such as our warnings,
    while the ISO image is downloaded.

<a id="integration">

Integration in the web assistant
================================

The extension will interact with a single web page that it will modify
to display the relevant content. This page will be the first step of one
of the scenarios of the [[web assistant|assistant]].

As we need a way of knowing where people are in the assistant, the
extension will potentially interact with several web pages on our
website, depending on the scenario, for example:

  - `/install/windows/usb/1-download/` for the Windows USB scenario in the default language.
  - `/install/debian/dvd/1-download/index.de.html` for the Debian DVD scenario in German.

Initial browser detection
-------------------------

On this page, the initial screen as seen by the user will have to depend
on the browser to propose only the relevant options. We also have to
provide a fallback for people who disable JavaScript. So we'll have
three potential versions of this initial script:

  A. If we cannot detect the browser (no JavaScript).
  B. If we detect a supported browser (Firefox and Tor Browser to start
     with, Chrome after the extension gets ported to Chrome, etc.).
  C. If we detect an unsupported browser.

We need some JavaScript code to display option B or C, and otherwise
display option A if there is no JavaScript.

Localization
------------

The web page manipulated by the extension will be translated using our
usual infrastructure (ikiwiki and PO files). The extension must not
embed any user-visible string in its code.

<a id="verification"></a>

ISO verification mechanism
==========================

We are considering here an attacker who can:

  - (A) Provide a malicious ISO 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|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 ISO verification.

    To mitigate such an attack we should work on deploying HPKP (HTTP
    Public Key Pinning) which provides TOFU on our SSL certificate
    ([[!tails_ticket 9026]]). But our certificate could also probably be
    integrated in the Firefox preload list shipped with the browser
    ([[!tails_ticket 9027]]).

  - (C) Insert malicious content on https://tails.boum.org/ through an
    exploit on our website as this could trick new users to skip the ISO
    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. 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 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 ISO verification and rely
      on a native interface accessible from the add-ons menu.

  - [I] Provide a malicious extension in the same browser as this would
    have similar effects to attack [F].

<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). Web pages from a
different origin cannot interfere in any way with the result of the
verification performed by the extension. Only tabs from the same origin,
or if the content of the other tab opts-in for some form of cross-domain
communication, or it's been opened with `window.open()` by a script in
this tab or vice-versa (in the latter cases it has a handle to the
window of the other tab, either as the return value of `window.open()` or
as the `window.opener` property, but it cannot actually touch the content
unless it's same domain).

Of course, any tab can open an alert box saying "Verification
Successful", but it cannot overlay a different tab and, most important,
cannot detect any hint that the verification is happening. Note that the
proposed wireframe for the extension does not open alert boxes but
instead modifies the content of the page.

Bugs in the browser itself that could temper with the verification
mechanism would need to be of the "remote code execution vulnerability"
and would represent a threat in many more use cases than when verifying
an ISO image.

Checksum verification
---------------------

The code of the extension includes:

  - The root certificate of the authority expected to sign the
    certificate of https://tails.boum.org/ (until we get [[!tails_ticket 9027]]).

When verifying an ISO image, the extension:

  - Connects to https://tails.boum.org/ and verifies its certificate
    against its expected authority.
  - If the certificate is trusted, then it downloads an ISO description
    document (size, checksum).
  - Verifies the ISO image against the document (first its size, then
    its checksum).

Security properties:

  - This technique would defeat attack A (malicious ISO).

Other considerations:

  - We would have to upgrade the extension if the certificate authority
    of https://tails.boum.org/ changes but we should know this in
    advance.
  - More complex verification mechanisms should be gradually [[built into
    Tails Installer|blueprint/bootstrapping/installer]] where we can
    defeat attacks B, C, D, F, and G.

<a id="html">

HTML code
=========

The extension will manipulate the HTML code of the download page. Here
are some important parts of this code.

### Extension version

The HTML code will include a tag to force a version of the extension.
For example:

<pre>
&lt;div id="extension-version"&gt;1.0&lt;/div&gt;
</pre>

We will provide only one version of the download page at a time. So the
extension must check the value of this tag and ask for an upgrade if its
version is lower than the request version number.

<a id="data_source">

Data source
===========

Building up on the format specified for [[upgrade description
files|contribute/design/incremental_upgrades#upgrade-description-files]],
the verification extension fetches an ISO description file from our
server to retrieve all the information it needs about the ISO image
(URL, size, checksum, etc.). As a beginning, this ISO description file
is not signed using OpenPGP.

### URL

For each release of Tails:

  - https://tails.boum.org/install/v1/Tails/i386/stable/0.23.yml

With a copy or a symlink to the latest version on:

  - https://tails.boum.org/install/v1/Tails/i386/stable/latest.yml

### ISO description file

    ---
    build-target: i386
    channel: stable
    product-name: Tails
    version: '0.23'
    target-files:
    - sha256: 359d104737f1a448375d2030f938dea3d529468b8218485998ab893c1f7509eb
      size: 939571200
      url: http://dl.amnesia.boum.org/tails/stable/tails-i386-0.23/tails-i386-0.23.iso

Updates mechanism
=================

We should also keep in mind how would the extension upgrade (change in
the code, change in the certificates it relies upon). If we need to
upgrade the extension:

  - In Firefox, it has to go through a manual review process that can
    take several days.
  - In Chrome, it can be uploaded directly to the store by us.

Firefox checks for updates of the extension once per day on a secure
channel (the update pings are also used to generate add-ons usage
stats). Tor Browser doesn't prevent those updates [except for Torbutton
and Tor Launcher](https://lists.torproject.org/pipermail/tbb-dev/2015-April/000258.html).

<a id="technology"></a>

Extension technology
====================

We [decided](https://mailman.boum.org/pipermail/tails-dev/2015-August/009450.html)
to write our extension as a Add-on SDK to have is compatible with
Electrolysis, extend its lifespan and make its code easier to port to
Chrome in the future.

Add-on SDK was the only valid option amongst the different technologies
available to write Firefox extensions:

  A. XUL/XPCOM. This technology requires restarting the browser after
     installing the extension and will be deprecated at some point as
     Firefox wants to move out of XUL/XPCOM in general.

  A. Bootstrapped add-ons. Are restartless but still uses XPCOM so will
     get deprecated as well.

  A. Add-on SDK. Are restartless as well and use a pure-JS sandboxed
     abstraction. They will be automatically ready for Electrolysis, the
     new multi-thread paradigm of Firefox. By being pure JS and not
     depending on XUL/XPCOM their code will be easier to port to Chrome.

  A. WebExtensions. Is a future technology that will use a pure JS API
     partially shared between Firefox and Google Chrome. They will be
     restartless and ready for Electrolysis as well. But this API is not
     stable yet and lacks some mechanisms that our extension would need.

To understand the roadmap for Firefox regarding extension technologies,
read <https://blog.mozilla.org/addons/2015/08/21/the-future-of-developing-firefox-add-ons/>.

<a id="satori"></a>

Satori
======

[Satori](https://chrome.google.com/webstore/detail/satori/oncomejlklhkbffpdhpmhldlfambmjlf)
has been suggested as an alternative to verify our downloads.

Pros:

- Already exists in beta.
- Knows how to calculate checksums.
- Probably more isolated from the browser than our current design.
- Not specific to Tails: reusable by the user for other software.

Cons:

- Checksum hardcoded (needs to be updated on each release).
- Current UI calculates the checksum but doesn't compare it.
- Not specific to Tails: more complex if you only want Tails.
- Doesn't work from Tor Browser.
