WebAuthn in real life

In September 2019, the Mail.ru Mail team supported WebAuthn technology. We became the first email service in the world that implemented the ability to log into your account using electronic keys instead of passwords. Now this opportunity is available to all our users, you can bind the electronic key to your account in the settings and after that freely use it to enter.



We already wrote news about this event here, on Habré. In this article I want to talk more about the reasons for implementing WebAuthn in our services and about the technical aspects of working with this technology.

What is WebAuthn and why is it needed


In the modern world, most Internet services use passwords to authenticate users. The advantage of passwords is their simplicity: to access the necessary resource you just need to know the password and enter it correctly.

However, the disadvantages of passwords often outweigh their advantages:

  • if the password is simple - you can pick it up;
  • if the same password is used in several services, then breaking one of them the attacker gets access to all the others;
  • passwords are vulnerable to phishing attacks;
  • strong and unique passwords are difficult to remember, so the user is forced to write down the password on the sticker and stick it on the monitor, from where it can be easily spied, stolen or lost.

To get rid of the shortcomings of passwords and make the authentication process more secure, various ways to replace passwords appear - this is the use of one-time codes that are sent to the user via SMS or through PUSH notifications, or the use of special TOTP-code generator applications with which the user can log in account without entering your password.

Companies such as Microsoft , Yahoo , Amazon think about using passwordless authentication methods and completely abandon the use of passwords in their services. Mail.ru mail is no exception, we have long supported login using one-time codes, which allows users not to remember complex and strong passwords and quickly gain access to their account.

Another alternative to passwords is authentication using electronic keys (security keys, another name - electronic authenticators). The principle of its operation is based on the use of asymmetric cryptography and is described in the FIDO2 protocol family, developed by the FIDO (Fast IDentity Online) alliance.

In March 2019, W3C released the first version of the standard., which describes a browser-based JS API that allows you to interact with electronic keys. The standard received the recommendation status and the name Web Authentication: API for access to credentials using a public key: level one (Web Authentication: An API for accessing Public Key Credentials Level 1) - for short, WebAuthn.

How WebAuthn Works


The following key actors in the authentication process using WebAuthn are identified:

  • Client (WebAuthn Client) - a browser that supports WebAuthn API;
  • Web application - an application running on the client using the WebAuthn API to interact with credentials;
  • credentials (Public Key Credential) - a pair of public and private cryptographic keys that are associated with a user account;
  • Authenticator - a device or program - creates user credentials and signs requests from the relying party with these credentials (another name is an electronic key);
  • the relying party (WebAuthn Relying Party) - the web server - stores the public key associated with the user account, verifies the validity of the signing of their requests with the private key stored in the authenticator.

The WebAuthn API allows you to perform only two operations. It allows you to create new credentials and sign requests from the server with already created credentials.

Creation of credentials ( MakeCredential )



Scheme of the stage with the creation of credentials, taken from w3.org .

At this stage, the electronic key is registered in the user account. Inside the authenticator, a new pair of public and private keys is generated, and the public key is sent and stored in the user account on the server.

const credential = await navigator.credentials.create({
    publicKey: publicKeyMakeCredentialOptions
});

Signing a request with credentials already created ( GetAssertion )



Scheme of the stage with verification of credentials, taken from w3.org .

At this step, it is checked whether the user has an authenticator whose public key is stored in the user account. A random token is signed with the private key inside the authenticator and sent to the server, where the server checks the signature is correct. Accordingly, if the signature is correct, then we conclude that the user really has this authenticator.

const assertion = await navigator.credentials.get({
    publicKey: publicKeyGetAssertionOptions
});

You can see a demonstration of the process of entering Mail.ru Mail using WebAuthn in this video .

You can learn more about the WebAuthn API itself in the WebAuthn specification and, for example, in this Medium article .

So, the work of WebAuthn is based on the use of electronic keys. What is it?

Electronic keys


Electronic keys (I will sometimes call them also “WebAuthn keys”, Security Security key) are devices or programs that implement FIDO2 interaction protocols.

In the WebAuthn specification and at the household level, all electronic keys are classified in one of two categories:

  • platform-independent keys (roaming authenticators);
  • Platform Authenticators

Platform-independent keys are external physical devices, such as Yubikey from Yubico or Titan Security Key from Google. Typically, such authenticators are connected to the user's computer or smartphone via USB, NFC or BLE. Communication with such devices takes place using the special CTAP protocol (Client to Authenticator Protocol).

To start working with physical electronic keys, the user needs to bind him once to his account. After that, the user gets the opportunity to use this electronic key to enter on any other device and in any browser.


Examples of various platform- independent keys, taken from theverge.com .

If the mechanism of operation of the first type of keys is more or less clear, then I want to dwell in more detail on the second category.

In the second case, public and private cryptographic keys are generated and stored not inside an external physical device, but with some software module inside a computer or smartphone. This software module can be implemented at the specific application level, or at the operating system level. For example, in a secure chip inside a computer, to which your OS will only give access if you are logged in and have proved that you are really you.

In most modern implementations in different browsers, the OS requires the user to confirm themselves either with a fingerprint or by entering the password for the user account. It is important to clarify that although the user needs to put his finger on the fingerprint scanner to use such keys, the fingerprint itself is not stored anywhere and is not transmitted anywhere. This is just the way in which the operating system or browser validates the user.


Use of platform-specific authenticators.

Only encoded public key information or a signed random token is returned to the web service from the WebAuthn API, which is then stored and checked on the server side.

Therefore, in the case of the built-in authenticator, it will be possible to use it only on the browser and device where it was attached to the account. In other words, platform-dependent keys will have to be registered separately on each device / browser in which you intend to log in to your account.

In the future, more ways are expected to appear that will enable the user to activate the use of platform-specific authenticators, for example, by using a face scan, or by entering a PIN code from the device.

When creating credentials or calculating the signature, you can specify the preferred type of authenticator in a special parameter that takes two values ​​- cross-platformand platform. In this case, the user will be asked to use only one of the types of electronic keys.

const credential = await navigator.credentials.create({
    publicKey: {
        authenticatorSelection: {
            authenticatorAttachment: 'cross-platform',
        },
        ...,
    },
});

WebAuthn Benefits


What are the benefits of WebAuthn technology for users and developers?

  • The user does not need to remember and enter any passwords, and the server does not store user passwords, respectively, all the shortcomings that the passwords had are gone. Stealing a physical authenticator from a user is much more difficult than intercepting a password transmitted electronically over an insecure connection, and a leak of public keys on the site will not open the private key hidden in the device.
  • origin , . origin . , (thesslstore.com, yubico.com) .
  • WebAuthn - . - web- , .
  • WebAuthn itself, as an API, provides developers with an abstraction over the implementation of authenticators and allows you to write code once, which then will work with all types and types of electronic keys. Thus WebAuthn is a scalable solution for user authentication.

Even more about why WebAuthn is safer than a password - WebAuthn for developers: 5 steps to better authentication , Getting started with security keys .

WebAuthn Support


Whether or not dongle authentication works on your device depends on several different factors. Starting from whether your browser supports the WebAuthn API, and ending with what connectors are on your computer and what communication methods your authenticator supports. WebAuthn’s performance also depends heavily on which device and OS you use.

At the time of writing, according to caniuse.com, the WebAuthn API is supported by 80.5% of users. According to statistics on users of Mail.ru, this figure has the same order - 79.8%. However, in order to use WebAuthn in all these browsers, you will definitely need an external electronic key.

Not all browsers that support the WebAuthn API can work with platform-dependent keys (for convenience, I will refer to these keys as “Fingerprints” later on). In addition, to work with such keys, it is not enough to install a browser that can work with them. It is also necessary that your device and OS have an appropriate module / sensor and be able to interact with it. Of all Mail.ru users, only 9.0% have the ability to add platform-specific keys.

I’ll tell you briefly about the support of WebAuthn by different OS and browsers.

Windows


WebAuthn support on Windows is very good. The Windows Hello authentication subsystem can work with electronic keys. Therefore, all the latest browser versions for this OS - Microsoft Edge, Google Chrome, Opera and Mozilla Firefox - support working with both foreign keys and fingerprints. Internet Explorer API WebAuthn does not support.


Linux


External authenticators are usually supported by any modern Linux distributions, as well as browsers such as Google Chrome, Chromium, and Mozilla Firefox. However, on some systems additional settings may be required to work with foreign keys .

Android


WebAuthn support on Android is also good. Google Chrome, Opera and Mozilla Firefox - support working with both foreign keys and fingerprints. But Microsoft Edge for Android does not support the WebAuthn API at all. There is also a bug in Firefox - specifying the preferred type of authenticator using the option does not work for it authenticatorAttachment.


iOS


Among all browsers for the iOS operating system, WebAuthn only supports mobile Safari version 13.3. Moreover, he can only work with external electronic keys. Other browsers for iOS do not yet support WebAuthn at all.

macOS


Microsoft Edge, Google Chrome, Opera and Mozilla Firefox support working with foreign keys on macOS. Google Chrome also supports fingerprinting, allowing you to use WebAuthn with Touch ID.


If in Edge, Opera and Chrome the interface for interacting with WebAuthn is the same, then Firefox has distinguished itself here. Instead of a pretty popup in Firefox, when using WebAuthn, a small notification appears in the corner of the screen. If you accidentally click on a page, it simply collapses, leaving the user at a loss what is happening now.



However, Safari has not yet supported WebAuthn. WebAuthn support was announced in Safari 13, which will be available on macOS 10.15 Catalina. However, at the time of writing, my checks showed that the WebAuthn API in Safari, although present, is extremely unstable and does not work with all authenticators. Like its mobile version, Safari does not work with built-in electronic keys. In addition, it does not yet support any of the foreign electronic keys.

So, we realized that in addition to support issues, WebAuthn has even greater differences in the UI. These differences lead to the fact that you have to explain in more detail to the user what is required of him in order to use the entrance through electronic keys. In addition, with each new browser release, these pop-ups may change, and the process of using WebAuthn today can be very different from what it was yesterday.

It is clear why this is happening. WebAuthn technology is still quite young, and browser developers are still experimenting with different types of implementation. One can only hope that over time the support for WebAuthn in browsers will stabilize and we will be able to use it without restrictions.

Authenticator Registration


If we give the user the opportunity to register different electronic keys in his account, then he should have the opportunity to view their list and remove obsolete or unnecessary ones from it. This may be useful, for example, in the event of a compromise of one of the keys.

The WebAuthn API is designed so that when creating and using credentials, the client is not available any information about the type, type and name of the authenticators used. Accordingly, we do not have any data by which we could distinguish one key from another. All keys in the list will be presented equally without distinguishing features. Question: what to do?


You can get some information about the authenticator used if you request the so-called credentials when creating credentials. certification. Certification is a way for an authenticator to prove its authenticity to a server. In some cases, information about the key manufacturer can be obtained from certification. But in the general case, the data used is still not enough to clearly distinguish one electronic key associated with an account from another.

const credential = await navigator.credentials.create({
    publicKey: {
        attestation: 'direct',
         ...,
    },
});

Therefore, after connecting the key to the account in Mail, we give the user the opportunity to assign some name to the newly created record. And already further the user can distinguish one key from another by this name.

The fact that the information that is available to the client and server does not contain any data about the type of authenticator leads to another unpleasant feature of WebAuthn.

Imagine a user who added only one fingerprint to his account, for example, in his smartphone. When we want to log in using the WebAuthn API, we pass in a function callnavigator.credentials.getlist of all keys associated with an account. But the browser cannot determine from this list which of the authenticators are present on the device and which are not. Therefore, he is forced to always offer the user to use WebAuthn.

Therefore, even when trying to log into an account on a computer that does not support authentication through fingerprints, the user will still be offered to use WebAuthn.

To implement the correct behavior in such situations, you need to refine the WebAuthn standard itself. For example, to encode information about whether a cross-platform key or fingerprint was used to create it and not to offer the WebAuthn user in cases when it is known in advance that he will not be able to use it.

There are ways to get around this behavior in some situations. For example, allow the user to register fingerprints and physical keys only individually. And when using keys, filter fingerprints on devices that obviously do not support them. But this method does not solve the problem completely. And there is no reliable way to solve this problem.

Our users have not yet received complaints about this behavior, so we are currently investigating this feature and deciding what to do in the future.

WebAuthn work on different subdomains


As I said earlier, WebAuthn provides out of the box protection against phishing. When registering electronic keys, information is stored originon which this key was registered. WebAuthn does not allow the use of this electronic key on resources, with another origin.

Large web services such as Mail.ru often use several different domains for their work. For example, we have a domain e.mail.rufor Mail and cloud.mail.rufor the Cloud. And on each of them we have a common form of authorization. In this case, the standard WebAuthn settings are not enough. So that we can use originkeys registered on the other on one origin, it is necessary that these two domains have a common suffix (a common subdomain of more than the first level).

For example at domainse.mail.ruand the cloud.mail.rucommon suffix is mail.ru.

In this case, when registering and using electronic keys, we can specify an rpIdequal parameter in the request options mail.ru, and then we can use the same key on the subkey itself https://mail.ruand on any of its subdomains.

const credential = await navigator.credentials.create({
    publicKey: {
        rp: {
            name: 'Mail.ru Group',
            id: 'mail.ru',
        },
        ...,
    },
});

WebAuthn work in iframe


For security reasons, calls to WebAuthn methods are forbidden from inside cross-origin iframes. Our projects use a single authorization form, it is located at https://account.mail.ru/login , and when we want to show the authorization form on any other project, for example, in Mail or in the Cloud, iframe is actually added to the page inside which this url opens. This solution allows us to simultaneously update the form itself on all projects that use it, and simplifies the collection of statistics, and also improves the user’s UX, allowing him to stay on the same service where he was originally.



In our case, the restriction on calls to WebAuthn methods from within the iframe made us look for ways to get around it, because we wanted to allow us to log in via WebAuthn anywhere we show the authorization form.

What have we done. To open the authorization form on all services, we use a small library, which essentially only creates an iframe on the page with the correct url and after loading its contents shows the iframe on the page. This library supports communication with iframes through postMessageand uses it, for example, to resize iframes when resizing its contents.

We came up with and implemented the following mechanism:

  1. in the authorization application when using WebAuthn, we determine whether we are now open inside the iframe or not;
  2. if we are open inside the iframe, then instead of calling the browser API WebAuthn, we serialize the call parameters and send them through the postMessageparent window;
  3. in the parent window we deserialize these parameters and call the WebAuthn methods;
  4. when we receive an answer, we serialize it in the same way and send it through the postMessageinside of an iframe, where we accept this answer and perform further processing.

Thus, we circumvented this ban and realized the possibility of using the same key during authorization in all services of the company.

WebAuthn Test Automation


In our team for all new projects and features, we always write integration UI autotests using selenium-like solutions and the WebDriver protocol. Therefore, during the development of WebAuthn, the question arose of how to write autotests UI on it.

The difficulty in writing such autotests is that the WebDriver protocol does not yet have methods for automating interaction with WebAuthn. And in the standard itself there is still no support for testing automation WebAuthn API (but there is an issue on this topic). The first ideas on how this automation can be organized are described in a draft Web Authentication: An API for accessing Public Key Credentials Level 2 and have not yet been published, not to mention being supported elsewhere. Therefore, I had to come up with alternative solutions.

Because we cannot work with the native implementation of WebAuthn functions in autotests (there are no methods for controlling the browser), then we had to do the following.

Somewhere in the autotest, before trying to use WebAuthn, we patch the browser’s global host objects and replace the native functions with our implementations. Here we save the arguments with which the native functions were called into a variable and return the promise.

//    WebAuthn   
navigator.credentials.create = (options) => {
    window.credentialsCreateArgs = options;

    return new Promise((resolve, reject) => {
        window.credentialsCreateSuccess = resolve;
        window.credentialsCreateFail = reject;
    });
};

Next, we need to somehow get the result of the function to return it to emulate the work of WebAuthn in the tests. We can always return some kind of constant hardcoded answer.

// -    
const credentialsCreateResponse = { /* constant object */ };

window.credentialsCreateSuccess(credentialsCreateResponse);

In this case, we will have to teach our server to accept this answer and not validate it, but consider it automatically correct.

What are the disadvantages of such tests? In this case, we will not be able to:

  • check whether the client correctly forms and rolls parameters into WebAuthn functions;
  • check the correctness of backend changes when rolling backend releases.

Thus, such tests will not be reliable enough, and this does not suit us.

We decided to go the more difficult way and eventually wrote our own implementation of FIDO2 protocols and algorithms on Node.js, with which we managed to lock these functions as close as possible to the native implementations.

That is, we wrote a function that, based on the request parameters, calculates the response for the locked WebAuthn functions so that the server considers it to be completely correct.

// -    
const credentialsCreateResponse =
    calcCredentialsCreateResponse(window.credentialsCreateArgs);
 
window.credentialsCreateSuccess(credentialsCreateResponse);

As a result, the autotest operation scheme is as follows:

  1. get the arguments that the WebAuthn methods were called with;
  2. we run these arguments through a function that implements the same algorithms as inside real authenticators;
  3. we get the result, and return it from our replaced functions;
  4. all the rest of the code in our service processes these responses in the usual mode and as a result, all the behavior of the service does not differ from its behavior for real users.

The sources of such an autotest and the implementation of the most disguised authenticator lie in the github repository , you can start and investigate their work later. When writing the authenticator, we were guided only by the w3.org specification and the Node.js documentation.

The Present and Future of WebAuthn


So what we have at the moment.

We launched a fully working electronic key entry at the end of September 2019. Now we do not advertise this type of entry, and it is not used very actively - less than a hundred unique users per day. But we are confident that over time their number will only grow, and sooner or later, electronic key logging will become one of the main types of logging into your account.

What keeps us from actively promoting such an entry is that WebAuthn itself is still not sufficiently reliable and stable in browsers, and there are many nuances regarding its support and operation.

Why is WebAuthn now a feature not for a wide audience?

The most basic factor here is that it requires the user to have a special device - an electronic key. Now the need for it is not so acutely felt by users. Many users are not aware of their existence. But over time, when more and more services begin to support this way of logging in, the number of users with such keys will also begin to grow.

A significant leap forward in the popularity of WebAuthn can occur when Google engineers complete the development and testing of the possibility of using smartphones on Android and iOS as external physical electronic keys for WebAuthn and open this opportunity for all Internet services. In this case, each owner of a modern smartphone will essentially get the opportunity to use it as a WebAuthn key and the number of WebAuthn users will increase dramatically. Now this feature is available only to users of the Google email service.



How else can you use WebAuthn?


Mail.ru uses WebAuthn now as an alternative to passwords for entering the account. But essentially WebAuthn can be used like any of the authorization factors. It can be used as instead of the first factor in one-factor authentication. So instead of the second - as an additional password protection with two-factor. In addition, confirmation via an electronic key can be used, for example, when restoring access to an account if the user has lost or forgotten his password.

WebAuthn can be used as an additional security measure when editing critical settings of your account. Imagine how convenient it is - you go to the profile settings in your favorite service, and you do not need to remember and enter a password to change them! Just put your finger on the fingerprint scanner, and you will be passed on.

You can find even more different scenarios for using WebAuthn in this Medium article .

Popular questions and answers


Where can I buy an electronic key?


So far, there are not many places in Russia where you can purchase electronic keys compatible with FIDO2 protocols. Most suppliers only sell them in bulk, in batches of 10 or more. You can buy electronic keys piece by piece in the following stores:


Also, such keys can be ordered in friendly online stores, for example, on Amazon . In this article, there are comparative characteristics of electronic switches 10 models with links to stores where they can be purchased.

What if I lose my electronic key?


Using electronic keys, you should treat them with the same attention as with the keys to the apartment or car. If we lose the keys to the apartment, we usually change the lock and get new keys. The same is with electronic keys: if they are lost, you should immediately remove them from all accounts where they were linked, and attach a new authenticator to all accounts.

In case of loss of the main electronic key, you should have several additional authentication methods. For example, using the application for generating codes, or using a spare key that can be stored in a specially protected place: in a safe or in a bank cell.

What should I do if someone else gets access to my electronic key?


If two-factor authentication is included in your account and the electronic key is just one of the factors, then in this case your account will be protected from hacking. Unless the attacker has access to the second factor.

If the electronic key is the only factor sufficient to enter the account, then even in this case the attacker must know the name of the account in which this electronic key is registered. This information is not stored inside the electronic key, and therefore an accidentally lost electronic key with a high degree of probability will be completely useless for a passerby who found it.

However, there are schemes in which electronic keys can be used as a replacement not only for a password, but also for a login. In such a scenario, the server only provides credentials when requestedorigin, and the credentials themselves are entirely stored in the authenticator. In this case, the lost electronic key can already be easily used to enter your account, and then you should be more careful about your authenticator. For protection in such scenarios, you can use electronic keys with additional security measures, for example, keys, for activation of which you need to enter a PIN code.

In any case, as soon as you notice the loss of your key, you should immediately untie it from all accounts in all services, where you can use it to enter. That is why all services should provide the ability to manage a list of bound authenticators. The faster you notice the loss, the less time the attackers will have in order to gain access to your data.

Now my biometric data will be stored on Mail.ru/Google/Microsoft servers?


When WebAuthn works with built-in authenticators (for example, using Touch ID on Mac OS), only the corresponding sensor and the operating system itself have access to your biometric data. The web service does not receive or process any biometric information; it works only with the public cryptographic key and with data signed with the private key.

And on the server itself, only information about the public key is stored. Therefore, WebAuthn does not use your biometric data in any way to work with built-in authenticators.

Conclusion


As we found out, WebAuthn has many important advantages over passwords:

  • when using WebAuthn it is not required to remember and enter passwords;
  • WebAuthn - , ;
  • WebAuthn ;
  • WebAuthn — .

However, passwords should not be discarded. A physical key can still be stolen or lost, just like a password. But passwords have an important advantage. As long as they are stored only in the head, they won’t be able to recognize them without the owner’s knowledge.

Summing up, I want to say that WebAuthn technology is a very promising technology that changes such a basic and important element of the functioning of all modern web-services as authentication. It is also a fairly young technology and users are not yet used to it. But it is in our power to make it more popular and convenient.

I hope our experience of implementing WebAuthn in Mail.ru Mail will help you to support it in your services, and together we will make the Internet more secure and modern!

Additional materials



All Articles