Move paragraphs to single lines in u2f-proxy.md

This commit is contained in:
pierwill 2019-08-18 13:22:06 -05:00
parent f07019101a
commit b08ab99e5c

View File

@ -6,115 +6,37 @@ permalink: /doc/u2f-proxy/
# The Qubes U2F Proxy # The Qubes U2F Proxy
The [Qubes U2F Proxy] is a secure proxy intended The [Qubes U2F Proxy] is a secure proxy intended to make use of U2F two-factor authentication devices with web browsers without exposing the browser to the full USB stack, not unlike the [USB keyboard and mouse proxies][USB] implemented in Qubes.
to make use of U2F two-factor authentication devices with web browsers without
exposing the browser to the full USB stack, not unlike the [USB keyboard and
mouse proxies][USB] implemented in Qubes.
## What is U2F? ## What is U2F?
[U2F], which stands for "Universal 2nd Factor", is a framework for [U2F], which stands for "Universal 2nd Factor", is a framework for authentication using hardware devices (U2F tokens) as "second factors", i.e. *what you have* as opposed to *what you know*, like a passphrase. This additional control provides [good protection][krebs] in cases in which the passphrase is stolen (e.g. by phishing or keylogging). While passphrase compromise may not be obvious to the user, a physical device that cannot be duplicated must be stolen to be used outside of the owner's control. Nonetheless, it is important to note at the outset that U2F cannot guarantee security when the host system is compromised (e.g. a malware-infected operating system under an adversary's control).
authentication using hardware devices (U2F tokens) as "second factors", i.e.
*what you have* as opposed to *what you know*, like a passphrase. This
additional control provides [good protection][krebs] in cases in which the
passphrase is stolen (e.g. by phishing or keylogging). While passphrase
compromise may not be obvious to the user, a physical device that cannot be
duplicated must be stolen to be used outside of the owner's control.
Nonetheless, it is important to note at the outset that U2F cannot guarantee
security when the host system is compromised (e.g. a malware-infected operating
system under an adversary's control).
The U2F specification defines protocols for multiple layers from USB to the The U2F specification defines protocols for multiple layers from USB to the browser API, and the whole stack is intended to be used with web applications (most commonly websites) in browsers. In most cases, tokens are USB dongles. The protocol is very simple, allowing the devices to store very little state inside (so the tokens may be reasonably cheap) while simultaneously authenticating a virtually unlimited number of services (so each person needs only one token, not one token per application). The user interface is usually limited to a single LED and a button that is pressed to confirm each transaction, so the devices themselves are also easy to use.
browser API, and the whole stack is intended to be used with web applications
(most commonly websites) in browsers. In most cases, tokens are USB dongles.
The protocol is very simple, allowing the devices to store very little state
inside (so the tokens may be reasonably cheap) while simultaneously
authenticating a virtually unlimited number of services (so each person needs
only one token, not one token per application). The user interface is usually
limited to a single LED and a button that is pressed to confirm each
transaction, so the devices themselves are also easy to use.
Currently, the most common form of two-step authentication consists of a numeric Currently, the most common form of two-step authentication consists of a numeric code that the user manually types into a web application. These codes are typically generated by an app on the user's smartphone or sent via SMS. By now, it is well-known that this form of two-step authentication is vulnerable to phishing and man-in-the-middle attacks due to the fact that the application requesting the two-step authentication code is typically not itself authenticated by the user. (In other words, users can accidentally give their codes to attackers because they do not always know who is really requesting the code.) In the U2F model, by contrast, the browser ensures that the token receives valid information about the web application requesting authentication, so the token knows which application it is authenticating (for details, see [here][u2f-details]). Nonetheless, [some attacks are still possible][wired] even with U2F (more on this below).
code that the user manually types into a web application. These codes are
typically generated by an app on the user's smartphone or sent via SMS. By now,
it is well-known that this form of two-step authentication is vulnerable to
phishing and man-in-the-middle attacks due to the fact that the application
requesting the two-step authentication code is typically not itself
authenticated by the user. (In other words, users can accidentally give their
codes to attackers because they do not always know who is really requesting the
code.) In the U2F model, by contrast, the browser ensures that the token
receives valid information about the web application requesting authentication,
so the token knows which application it is authenticating (for details, see
[here][u2f-details]). Nonetheless, [some attacks are still possible][wired] even
with U2F (more on this below).
## The Qubes approach to U2F ## The Qubes approach to U2F
In a conventional setup, web browsers and the USB stack (to which the U2F token In a conventional setup, web browsers and the USB stack (to which the U2F token is connected) are all running in the same monolithic OS. Since the U2F model assumes that the browser is trustworthy, any browser in the OS is able to access any key stored on the U2F token. The user has no way to know which keys have been accessed by which browsers for which services. If any of the browsers are compromised, it should be assumed that all of the token's keys have been compromised. (This problem can be mitigated, however, if the U2F device has a special display to show the user what's being authenticated.) Moreover, since the USB stack is in the same monolithic OS, the system is vulnerable to attacks like [BadUSB].
is connected) are all running in the same monolithic OS. Since the U2F model
assumes that the browser is trustworthy, any browser in the OS is able to access
any key stored on the U2F token. The user has no way to know which keys have
been accessed by which browsers for which services. If any of the browsers are
compromised, it should be assumed that all of the token's keys have been
compromised. (This problem can be mitigated, however, if the U2F device has a
special display to show the user what's being authenticated.) Moreover, since
the USB stack is in the same monolithic OS, the system is vulnerable to attacks
like [BadUSB].
In Qubes OS, by contrast, it is possible to securely compartmentalise the In Qubes OS, by contrast, it is possible to securely compartmentalise the browser in one qube and the USB stack in another so that they are always kept separate from each other. The Qubes U2F Proxy then allows the token connected to the USB stack in one qube to communicate with the browser in a separate qube. We operate under the assumption that the USB stack is untrusted from the point of view of the browser and also that the browser is not to be trusted blindly by the token. Therefore, the token is never in the same qube as the browser. Our proxy forwards only the data necessary to actually perform the authentication, leaving all unnecessary data out, so it won't become a vector of attack. This is depicted in the diagram below (click for full size).
browser in one qube and the USB stack in another so that they are always kept
separate from each other. The Qubes U2F Proxy then allows the token connected to
the USB stack in one qube to communicate with the browser in a separate qube. We
operate under the assumption that the USB stack is untrusted from the point of
view of the browser and also that the browser is not to be trusted blindly by
the token. Therefore, the token is never in the same qube as the browser. Our
proxy forwards only the data necessary to actually perform the authentication,
leaving all unnecessary data out, so it won't become a vector of attack. This is
depicted in the diagram below (click for full size).
[![Qubes U2F Proxy diagram](/attachment/wiki/posts/u2f.svg)](/attachment/wiki/posts/u2f.svg) [![Qubes U2F Proxy diagram](/attachment/wiki/posts/u2f.svg)](/attachment/wiki/posts/u2f.svg)
The Qubes U2F Proxy has two parts: the frontend and the backend. The frontend The Qubes U2F Proxy has two parts: the frontend and the backend. The frontend runs in the same qube as the browser and presents a fake USB-like HID device using `uhid`. The backend runs in `sys-usb` and behaves like a browser. This is done using the `u2flib_host` reference library. All of our code was written in Python. The standard [qrexec] policy is responsible for directing calls to the appropriate domains.
runs in the same qube as the browser and presents a fake USB-like HID device
using `uhid`. The backend runs in `sys-usb` and behaves like a browser. This is
done using the `u2flib_host` reference library. All of our code was written in
Python. The standard [qrexec] policy is responsible for directing calls to the
appropriate domains.
The `vault` qube with a dashed line in the bottom portion of the diagram depicts The `vault` qube with a dashed line in the bottom portion of the diagram depicts future work in which we plan to implement the Qubes U2F Proxy with a software token in an isolated qube rather than a physical hardware token. This is similar to the manner in which [Split GPG] allows us to emulate the smart card model without physical smart cards.
future work in which we plan to implement the Qubes U2F Proxy with a software
token in an isolated qube rather than a physical hardware token. This is similar
to the manner in which [Split GPG] allows us to emulate the smart card model
without physical smart cards.
One very important assumption of U2F is that the browser verifies every request One very important assumption of U2F is that the browser verifies every request sent to the U2F token --- in particular, that the web application sending an authentication request matches the application that would be authenticated by answering that request (in order to prevent, e.g., a phishing site from sending an authentication request for your bank's site). With the WebUSB feature in Chrome, however, a malicious website can [bypass][wired] this safeguard by connecting directly to the token instead of using the browser's U2F API.
sent to the U2F token --- in particular, that the web application sending an
authentication request matches the application that would be authenticated by
answering that request (in order to prevent, e.g., a phishing site from sending
an authentication request for your bank's site). With the WebUSB feature in
Chrome, however, a malicious website can [bypass][wired] this safeguard by
connecting directly to the token instead of using the browser's U2F API.
The Qubes U2F Proxy also prevents this class of attacks by implementing an The Qubes U2F Proxy also prevents this class of attacks by implementing an additional verification layer. This verification layer allows you to enforce, for example, that the web browser in your `twitter` qube can only access the U2F key associated with `https://twitter.com`. This means that if anything in your `twitter` qube were compromised --- the browser or even the OS itself --- it would still not be able to access the U2F keys on your token for any other websites or services, like your email and bank accounts. This is another significant security advantage over monolithic systems. (For details and instructions, see the [Advanced usage] section below.)
additional verification layer. This verification layer allows you to enforce,
for example, that the web browser in your `twitter` qube can only access the U2F
key associated with `https://twitter.com`. This means that if anything in your
`twitter` qube were compromised --- the browser or even the OS itself --- it
would still not be able to access the U2F keys on your token for any other
websites or services, like your email and bank accounts. This is another
significant security advantage over monolithic systems. (For details and
instructions, see the [Advanced usage] section below.)
For even more protection, you can combine this with the [Qubes firewall] to For even more protection, you can combine this with the [Qubes firewall] to ensure, for example, that the browser in your `banking` qube accesses only one website (your bank's website). By configuring the Qubes firewall to prevent your `banking` qube from accessing any other websites, you reduce the risk of another website compromising the browser in an attempt to bypass U2F authentication.
ensure, for example, that the browser in your `banking` qube accesses only one
website (your bank's website). By configuring the Qubes firewall to prevent your
`banking` qube from accessing any other websites, you reduce the risk of another
website compromising the browser in an attempt to bypass U2F authentication.
## Installation ## Installation
These instructions assume that there is a `sys-usb` qube that holds the USB These instructions assume that there is a `sys-usb` qube that holds the USB stack, which is the default configuration in most Qubes OS installations.
stack, which is the default configuration in most Qubes OS installations.
In dom0: In dom0:
@ -135,59 +57,27 @@ In Debian TemplateVMs:
$ sudo apt install qubes-u2f $ sudo apt install qubes-u2f
``` ```
Repeat `qvm-service --enable` (or do this in VM settings -> Services in the Qube Repeat `qvm-service --enable` (or do this in VM settings -> Services in the Qube Manager) for all qubes that should have the proxy enabled. As usual with software updates, shut down the templates after installation, then restart `sys-usb` and all qubes that use the proxy. After that, you may use your U2F token (but see [Browser support] below).
Manager) for all qubes that should have the proxy enabled. As usual with
software updates, shut down the templates after installation, then restart
`sys-usb` and all qubes that use the proxy. After that, you may use your U2F
token (but see [Browser support] below).
## Advanced usage: per-qube key access ## Advanced usage: per-qube key access
If you are using Qubes 4.0, you can further compartmentalise your U2F keys by If you are using Qubes 4.0, you can further compartmentalise your U2F keys by restricting each qube's access to specific keys. For example, you could make it so that your `twitter` qube (and, therefore, all web browsers in your `twitter` qube) can access only the key on your U2F token for `https://twitter.com`, regardless of whether any of the web browsers in your `twitter` qube or the `twitter` qube itself are compromised. If your `twitter` qube makes an authentication request for your bank website, it will be denied at the Qubes policy level.
restricting each qube's access to specific keys. For example, you could make it
so that your `twitter` qube (and, therefore, all web browsers in your `twitter`
qube) can access only the key on your U2F token for `https://twitter.com`,
regardless of whether any of the web browsers in your `twitter` qube or the
`twitter` qube itself are compromised. If your `twitter` qube makes an
authentication request for your bank website, it will be denied at the Qubes
policy level.
To enable this, create a file in dom0 named To enable this, create a file in dom0 named `/etc/qubes-rpc/policy/policy.RegisterArgument+u2f.Authenticate` with the following content:
`/etc/qubes-rpc/policy/policy.RegisterArgument+u2f.Authenticate` with the
following content:
``` ```
sys-usb @anyvm allow,target=dom0 sys-usb @anyvm allow,target=dom0
``` ```
Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it is a blank file. Do not delete the file itself. (If you do, the default file will be recreated the next time you update, so it will no longer be empty.) Finally, follow your web application's instructions to enroll your token and use it as usual. (This enrollment process depends on the web application and is in no way specific to Qubes U2F.)
is a blank file. Do not delete the file itself. (If you do, the default file
will be recreated the next time you update, so it will no longer be empty.)
Finally, follow your web application's instructions to enroll your token and use
it as usual. (This enrollment process depends on the web application and is in
no way specific to Qubes U2F.)
The default model is to allow a qube to access all and only the keys that were The default model is to allow a qube to access all and only the keys that were enrolled by that qube. For example, if your `banking` qube enrolls your banking key, and your `twitter` qube enrolls your Twitter key, then your `banking` qube will have access to your banking key but not your Twitter key, and your `twitter` qube will have access to your Twitter key but not your banking key.
enrolled by that qube. For example, if your `banking` qube enrolls your banking
key, and your `twitter` qube enrolls your Twitter key, then your `banking` qube
will have access to your banking key but not your Twitter key, and your
`twitter` qube will have access to your Twitter key but not your banking key.
## TemplateVM and browser support ## TemplateVM and browser support
The large number of possible combinations of The large number of possible combinations of TemplateVM (Fedora 27, 28; Debian 8, 9) and browser (multiple Google Chrome versions, multiple Chromium versions, multiple Firefox versions) made it impractical for us to test every combination that users are likely to attempt with the Qubes U2F Proxy. In some cases, you may be the first person to try a particular combination. Consequently (and as with any new feature), users will inevitably encounter bugs. We ask for your patience and understanding in this regard. As always, please [report any bugs you encounter].
TemplateVM (Fedora 27, 28; Debian 8, 9) and browser (multiple Google Chrome
versions, multiple Chromium versions, multiple Firefox versions) made it
impractical for us to test every combination that users are likely to attempt
with the Qubes U2F Proxy. In some cases, you may be the first person to try a
particular combination. Consequently (and as with any new feature), users will
inevitably encounter bugs. We ask for your patience and understanding in this
regard. As always, please [report any bugs you encounter].
Please note that, in Firefox before Quantum (e.g. Firefox 52 in Debian 9), you Please note that, in Firefox before Quantum (e.g. Firefox 52 in Debian 9), you have to install the [U2F Support Add-on][ff-u2f-addon]. In Firefox post-Quantum you may have to enable the `security.webauth.u2f` flag in `about:config`. Chrome and Chromium do not require any special browser extensions.
have to install the [U2F Support Add-on][ff-u2f-addon]. In Firefox post-Quantum
you may have to enable the `security.webauth.u2f` flag in `about:config`. Chrome
and Chromium do not require any special browser extensions.
[Qubes U2F Proxy]: https://github.com/QubesOS/qubes-app-u2f [Qubes U2F Proxy]: https://github.com/QubesOS/qubes-app-u2f