chushpan
Professional
- Messages
- 735
- Reaction score
- 471
- Points
- 63
In this article, we will follow the history of passwordless authentication ideas. We will understand what FIDO2 is, how the WebAuthn and CTAP protocols work, and discuss their internal security mechanisms and existing attacks. In the meantime, we will uncover a conspiracy of mass biometric data leakage, see what Passkeys have to do with it, and try to understand how close the passwordless future is.
The idea of ditching passwords is almost as old as passwords themselves. However, the first serious discussions of this topic began around 2004, when Bill Gates said at the RSA security conference: "There is no doubt that over time, people will rely less and less on passwords. ... [passwords] are simply not up to the task of protecting anything of real value." Then there was a chorus of voices from IBM, Google and other companies preaching the imminent demise of passwords. But twenty years have passed since Gates' speech, and nothing has changed - passwords are still alive.
Before we move on, let's refresh our understanding of a few basic concepts:
In the context of this article, we are interested in authentication. The de facto standard for it has become the login-password combination. But what's wrong with passwords?
And anyway, what can we say when Fernando Corbató, who first implemented the password mechanism in 1961, stated that it was not intended for the web and has now turned into a nightmare.
It all started in the 1980s, when Security Dynamics Technologies (now RSA Security) created the first hardware token generating one-time passwords (OTP). In 1998, AT&T received a patent for two-factor authentication, combining a password with an OTP code. In the 2000s, the SSO system became widespread. In 2011, Motorola released the first smartphone with a fingerprint scanner, and two years later Apple did the same, equipping the iPhone with the Touch ID sensor. Thus, the evolution of authentication has created only three factors: knowledge factors (something you know), possession factors (something you have), and property factors (something that characterizes you). So, fundamentally, we have the following alternatives:
I will dispel the biggest misconception about PA. Any use of biometrics is a local solution of the authenticator manufacturer, but even in this case, no one sends your fingerprints or their derivatives anywhere or signs anything with them, this also applies to FIDO2, which will be discussed below. Many people confuse the use of biometrics and PA, which gives rise to mass hysteria about biometric data leaks.
Since 2004, OATH, OIDF, OASIS, IDSA, OIX and others have been formed. The number of organizations and protocols grew, companies tried to create products, but did not come to any common solution. Therefore, in July 2012, PayPal, Lenovo and four other companies founded the FIDO (Fast IDentity Online) alliance, whose mission was to "reduce global dependence on passwords." Contrary to popular belief, Google and Microsoft were not among the founders, but joined only in 2013. Now the FIDO alliance includes several hundred companies.
At first, the newly formed alliance united two independent projects. First, there is the Universal Authentication Framework (UAF), developed by PayPal and Validity Sensors, a protocol that uses biometric data to authenticate a user without a password on the mobile device side. Second, there is the Universal Second Factor (U2F), created by Google and Yubico. This protocol involves using an external security token as a second authentication factor, in addition to a password. This resulted in two specifications: UAF 1.0 (December 8, 2014) and U2F 1.0 (October 9, 2014), which can be roughly called the FIDO 1.0 project.
The concept looked great, but it lacked unification, so in September 2015, the FIDO Alliance merged the two specifications and released the FIDO 2.0 proposal, which was submitted to the W3C. On this basis, the W3C released the WebAuthn protocol in May 2016, and the FIDO alliance, after several revisions, released the U2F 1.2 protocol (aka CTAP 1.0) in July 2017. This combination can already be called a full-fledged FIDO 2.0 project.
Info
W3C (World Wide Web Consortium) is an international web standards organization. There are other similar organizations, such as WHATWG (supports HTML) and ECMA (supports JavaScript). The standards issued by these organizations are not mandatory, but are generally accepted.
W3C and FIDO regularly release new iterations of their specifications. So, today the standard is WebAuthn (Level 2) from 2021 and CTAP 2.1 from 2022, but there is also a new version that is still at the proposal stage. Today, FIDO2 is the most common solution of the FIDO alliance, although U2F is also used by some web services as a 2FA method, and UAF is used in mobile applications as a method of confirming an action, for example, a transaction in a banking application. In summary, you need to remember that FIDO is an alliance, FIDO1 and FIDO2 are projects, not protocols; UAF, U2F, CTAP and WebAuthn of all versions are protocols that have specifications of the same name.
First, I will say a few words about what FIDO2 does not cover. The protocols do not cover how we get an authenticator (buy it, or it is given to us at work), how we activate the authenticator (set our fingerprint or code) and how our keys are stored (encrypted storage or a browser password manager).
FIDO2 also does not cover Passkeys, which are now starting to be offered on some large sites. The thing is that in the first FIDO2 specifications such a concept did not exist, and later the word Passkeys began to be used for convenience to refer to those same cryptographic keys. In practice, Passkeys is one of the implementations of a key based on cryptography that can be used in FIDO2 and has other useful functions, such as synchronization between devices. But it is worth remembering that neither WebAuthn nor CTAP regulate Passkeys. This is currently simply the most common solution. The main participants in the interaction are:
The WebAuthn protocol is responsible for the interaction between the JS client and the RP, it can be conventionally called the client API. In most cases, the JS client is the user's browser, but it can also be a native application for Android or iOS. For simplicity, we will consider the concepts of the JS client and browser, as well as the website and RP to be equivalent.
The CTAP protocol regulates the relationship between the authenticator and the user's device, it can be conventionally called the authenticator API. The authenticator can be built-in, such as Face ID, or external, such as the YubiKey hardware token, but we will not distinguish between them.
CTAP can transmit data via USB, NFC or BLE (Bluetooth Low Energy). The most attentive will probably notice that we still have a gap in the interaction between the user's device and the JS client. Unfortunately, each platform (OS) solves this issue in its own way, there are no clear standards here.
The FIDO2 architecture is conceptually shown in the figure below, with the components in different colors depending on the team or even the vendor.
First, the user must log in to the site, find the registration form, enter their login and click the registration button. Then the RP forms a PublicKeyCredentialCreationOptions request to the browser. This array contains:
If attestation is required, the generated public key will be signed by the attestation private key. The attestation private key is created on the authenticator by the manufacturer and is unique for each device model manufactured in a given time frame: for example, all YubiKey 5 manufactured from September to December 2022 will have the same key. Then the signed public key and attestation certificate are sent to the RP. The RP may or may not verify the attestation! To establish trust, the RP checks the certificate chain from the manufacturer's signature to the GlobalSign root certificate. At the same time, to determine the authenticator's capabilities, the responsible party needs to download and update the MDS3 database monthly, which contains data on each authenticator model.
After receiving the request, the browser calls the navigator.credentials.create() function, in which it checks that the rp.id value matches the domain name, and also hashes the request data. At this point, WebAuthn ends, and the OS calls authenticatorMakeCredential from the authenticator via the CTAP protocol. In general, most of the values in this array should already be familiar to you, we will only point out clientDataHash, which is the aforementioned SHA-256 hash of the request data, and options, which contain requirements for the user presence (UP) and user verification (UV) procedures, among others.
The WebAuthn and CTAP specifications do not strictly define these procedures, talking about some kind of "authorization gesture" that each manufacturer can understand in its own way. For FIDO2, the difference is that UV allows you to distinguish between different users of the same authenticator, while UP does not.
After receiving the request, the authenticator creates a key pair and performs other actions, a total of 19 steps in the algorithm. As a result, the authenticator returns an AuthenticatorAttestationResponse object to the operating system via CTAP. The OS passes it to the bored navigator.credentials.create() function, which forms a PublicKeyCredential and ends its cycle.
The AuthenticatorAttestationResponse returned by the authenticator is often simply called Attestation, so sometimes you can hear that the entire registration process is also called Attestation (attestation), but this is more of a colloquial name that should not be confused with the process of establishing the authenticator model described above. The formats of AuthenticatorAttestationResponse and PublicKeyCredential are almost identical, so we will consider only the latter:
Array components in detail:
At the final stage, the browser sends the PublicKeyCredential to the RP. The RP verifies the received data, for example, checks whether the received keys and algorithms meet the stated requirements, and performs certification. In total, the WebAuthn specification assumes an algorithm of 19 steps. If successful, the RP saves the credentialID and public key with metadata in its database. Then the user is most often redirected to the login page to log in.
Conditional UI works only for authentication and is supported by most browsers or built-in OS calls for native apps. Conditional UI only works with discoverable keys (see below) and may also conflict with password manager autofill capabilities. It does not require any plugins to be installed on the user side.
The RP generates a PublicKeyCredentialRequestOptions request to the browser that contains:
Discoverable keys are stored on the authenticator, and during login, the authenticator prompts the user to select which of the domain keys (rp.id) to use.
Non-discoverable keys are not stored on the authenticator, but are created as a derivative of the authenticator's master key and seed. During login, the RP sends the authenticator the key identifier and seed, and the authenticator recreates the key and signs the challenge. Since the key is only available in the authenticator's memory for a certain time, it is also called ephemeral, and the authenticator itself does not know that the key exists unless it is told about it.
Next, the browser calls the navigator.credentials.get() function, in which it checks that the rp.id value matches the interaction domain, and also hashes the request data. At this point, WebAuthn ends again, and the OS calls the authenticatorGetAssertion function of the authenticator via the CTAP protocol.
Having received the request, the authenticator finds its private key and performs other actions, including interaction with the user. The entire algorithm involves 13 steps. As a result, the authenticator via CTAP returns an AuthenticatorAssertionResponse object to the operating system, which it passes to navigator.credentials.get(). This function forms a PublicKeyCredential and ends its cycle.
The AuthenticatorAssertionResponse returned by the authenticator is often simply called Assertion, which is why you can sometimes hear that the entire authentication process is also called Assertion (confirmation) - by analogy with how registration is often called attestation.
For clarity, let's look at the difference in the data sent in the PublicKeyCredential array during registration and authentication.
At the final stage, the browser sends the PublicKeyCredential to the responsible party. It verifies the received data, for example, checks whether the challenge matches. The entire verification algorithm in the WebAuthn specification is 23 steps. If successful, the RP sends the user a session cookie.
First, if the server is hacked, the client's secrets will indeed not be compromised, since only the public key and other metadata are stored on the web service side, there is no private key. However, everything that this private key protected will end up in the hands of intruders - that is, the very data dear to our hearts.
Secondly, phishing. Here, too, we agree with the developers of the standard: we remember that when registering, RP exchanges the rp.id value with the browser, to which the private key is linked. Therefore, even if you enter the wrong door, the authenticator will not sign anything. But there is nothing fundamentally new here, any password manager has such a function.
Let's move on to the most interesting part. The synchronized login attack is specific to FIDO2, but relies on good old clickjacking. If you install an invisible frame on a vulnerable site, inside which you place a panel for login from another domain where the user is also registered, both authentications will occur: the one the user planned, and the one the attacker planned.
Someone will definitely say that the authenticator shows the user a notification about what resource he is visiting. However, Tarun Kumar Yadav noted in his research ( PDF ) that only one in twenty users checks the domain name in the pop-up, and no one considers double-clicking on the authenticator to be malicious.
Another interesting attack is authenticator cloning. Now this is a difficult task, but not impossible. So, in 2024, NinjaLab specialists managed to successfully clone YubiKey 5 hardware keys.
FIDO2 has protection against such types of attacks - the same signCount, which, if it does not match on the authenticator and RP side, will not allow successful login. But this protection mechanism is easily bypassed. The fact is that the authenticator increases signCount after each successful signing of the task, and the RP - after each successful authentication, that is, in fact, both parties act independently.
Let's assume that the attacker copied your hardware token, when signCount is 200, we will designate this as A = 200, L = 200 from the words Assertion on the authenticator side and Login on the RP side. The attack progress is shown in the table below. The attacker successfully logs into the resource, while A increases only for him, and L - for all participants.
When the user tries to log in, he will get an error, because A and L will not match, but the user's authenticator will successfully sign the task and increase signCount, and the RP will not successfully log in and leave the signCount value unchanged. Accordingly, both values will be equal and the second login attempt will successfully log in to the account. Unfortunately, sites only show a general error message, often asking the user to re-login when the error no longer occurs.
Another simple attack that can be considered is session hijacking. Even after super-duper secure authentication, we are left alone with the HTTP protocol, which does not store state and relies on cookies. Therefore, if a site is vulnerable to, for example, XSS, it is possible to completely take over the user's session. And MitM attacks are not prevented in any way.
FIDO2 relies on a TLS connection, while MitM did not disappear with the introduction of TLS. So you should not expect problems to be absent in this case either.
I think it is not even worth talking about cases where the root certificate is held by your organization or a government agency. The situation could be saved by Token Binding technology ( RFC 8471 ), which binds the TLS connection to the user's browser, but, unfortunately, it is not mandatory in FIDO2, and browsers practically do not support it.
As we can see, FIDO2 has internal protocol vulnerabilities and does not provide protection against many attacks. For example, Michal Kepkowski's research provides an example of a remote timing attack to determine the keys available on the authenticator. The researcher also points out that the UP procedure is easily simulated, and since most responsible parties do not require UV, this creates another vector for bypassing FIDO2 protection mechanisms.
Tarun Kumar Yadav also points out that 47% of browser extensions from the Chrome Web Store can perform at least five FIDO2-specific attacks, although no truly malicious extensions aimed at such attacks were found.
I will also note that the issue of FIDO2 privacy remains open - the user still leaves a ton of personal data on the RP side, and profiling by standard methods has not gone away.
Of course, BA looks simpler and more convenient - the user is not required to enter or invent anything, everything, except for a few clicks, happens automatically. Also on the side of FIDO2 is the fact that this technology is supported by all major browsers and OS.
Although passwordless authentication is cool, most web resources still do not introduce it. Companies do not see the point, because, firstly, everything works fine with passwords now, secondly, users are used to passwords, and thirdly, BA is a new process, and you will have to agree on it, choose software and pay developers. That is, BA for business is long, expensive and uninteresting.
Moreover, FIDO2 is only protocols, and their implementation, correct configuration of requirements for authenticators, support of mechanisms for restoring access and storing data depends on the responsible party. This imposes additional responsibility on the business and creates new risks. Perhaps, this is why BA is still based on the sheer enthusiasm of individual companies, and serious changes can only occur after the intervention of regulators.
BA may be convenient, but does the average user understand how it works, where the magic keys are stored and what should not be done? At least now people know that passwords should be complex and should not be shared, that there is phishing, and, in fact, users consciously take risks by not observing the rules of information hygiene. And BA and hardware tokens are just magic for people.
For example, we can recall how small companies treat the CEO's digital signature: a hardware token with it walks around the entire office and each employee signs and accepts documents with the CEO's signature.
The password can be easily transferred to a trusted person, and everyone knows how to do it. BA will bring new ways to share access, but for them to work, compatibility between devices is needed. And users themselves must know how this function works and be able to use it.
Not everything is so smooth with FIDO2 itself either. The CTAP and WebAuthn protocols have internal vulnerabilities and weak security mechanisms, and between them there is an OS layer that makes us dependent on a third party whose actions FIDO2 does not regulate.
FIDO2 is still susceptible to MitM and session theft, and in terms of user privacy, it does not give new hope. Hardware tokens are not updated, as this carries the risk of infecting them, so the burden falls on the user not only to choose and buy hardware, but also to replace it in the event of a critical vulnerability.
For the sake of convenience, BA suggests abandoning the password and using only one factor. It turns out that we are sliding from the usual 2FA, where there is both a password and an OTP code, to 1FA, where there is only an authenticator. Of course, it is possible to implement a multi-factor BA and use, for example, biometrics, but what is the difference with the current password authentication? You will still need to enter different codes and even carry a hardware token with you, which increases the risk of losing it.
FIDO2, like the BA idea, certainly looks very promising. A lot of work has been done, large companies have agreed to act together for a noble goal - to make life easier and safer. And although the beginning of the passwordless revolution has already been laid, there is still a lot of work to do. This means that in the foreseeable future we are unlikely to abandon passwords.
Source
The idea of ditching passwords is almost as old as passwords themselves. However, the first serious discussions of this topic began around 2004, when Bill Gates said at the RSA security conference: "There is no doubt that over time, people will rely less and less on passwords. ... [passwords] are simply not up to the task of protecting anything of real value." Then there was a chorus of voices from IBM, Google and other companies preaching the imminent demise of passwords. But twenty years have passed since Gates' speech, and nothing has changed - passwords are still alive.
Before we move on, let's refresh our understanding of a few basic concepts:
- Identification is the procedure of presenting yourself to an information system in a unique way, that is, simply put, by entering your login, you identify yourself.
- Authentication is a process of checking authenticity, that is, by entering the correct password, you confirm that you are the owner of the account.
- Authorization is the process of granting rights to a user that occurs within an information system.
In the context of this article, we are interested in authentication. The de facto standard for it has become the login-password combination. But what's wrong with passwords?
- People often fail to follow security best practices, using the same password over and over again or making passwords too easy to guess. According to a 2022 study, each user has an average of four passwords, and for one in three, these are variations of the same password.
- Passwords should be stored securely, both on the user side and on the service side. According to LastPass, the average modern user has 191 accounts, which hints at the need for a password manager, but people use pieces of paper and spreadsheets. It’s no better with companies — just remember the story of how Facebook stored passwords in plain text.
- Since passwords have become a standard means of authentication, attackers have accumulated experience and methods for selecting them (dictionaries, rules, utilities) that even a script kiddy can use. And by adding social engineering capabilities to this, attackers get a huge attack surface. According to various studies, 80 to 90% of all attacks involve the use of compromised credentials.
And anyway, what can we say when Fernando Corbató, who first implemented the password mechanism in 1961, stated that it was not intended for the web and has now turned into a nightmare.
Passwordless evolution
With passwords, everything is clear, they may indeed have become more of a risk than a protection, but what is offered in return?It all started in the 1980s, when Security Dynamics Technologies (now RSA Security) created the first hardware token generating one-time passwords (OTP). In 1998, AT&T received a patent for two-factor authentication, combining a password with an OTP code. In the 2000s, the SSO system became widespread. In 2011, Motorola released the first smartphone with a fingerprint scanner, and two years later Apple did the same, equipping the iPhone with the Touch ID sensor. Thus, the evolution of authentication has created only three factors: knowledge factors (something you know), possession factors (something you have), and property factors (something that characterizes you). So, fundamentally, we have the following alternatives:

- minimize the shortcomings of password authentication (SSO, OAuth, OpenID);
- combine knowledge factors with other factors (2FA, MFA);
- do not use knowledge factors (passwordless authentication).
I will dispel the biggest misconception about PA. Any use of biometrics is a local solution of the authenticator manufacturer, but even in this case, no one sends your fingerprints or their derivatives anywhere or signs anything with them, this also applies to FIDO2, which will be discussed below. Many people confuse the use of biometrics and PA, which gives rise to mass hysteria about biometric data leaks.
FIDO Zoo
Through logical reasoning, we came to the use of ownership or property factors. It sounds simple, but for implementation, standards are needed that would guide service developers and device manufacturers.Since 2004, OATH, OIDF, OASIS, IDSA, OIX and others have been formed. The number of organizations and protocols grew, companies tried to create products, but did not come to any common solution. Therefore, in July 2012, PayPal, Lenovo and four other companies founded the FIDO (Fast IDentity Online) alliance, whose mission was to "reduce global dependence on passwords." Contrary to popular belief, Google and Microsoft were not among the founders, but joined only in 2013. Now the FIDO alliance includes several hundred companies.
At first, the newly formed alliance united two independent projects. First, there is the Universal Authentication Framework (UAF), developed by PayPal and Validity Sensors, a protocol that uses biometric data to authenticate a user without a password on the mobile device side. Second, there is the Universal Second Factor (U2F), created by Google and Yubico. This protocol involves using an external security token as a second authentication factor, in addition to a password. This resulted in two specifications: UAF 1.0 (December 8, 2014) and U2F 1.0 (October 9, 2014), which can be roughly called the FIDO 1.0 project.
The concept looked great, but it lacked unification, so in September 2015, the FIDO Alliance merged the two specifications and released the FIDO 2.0 proposal, which was submitted to the W3C. On this basis, the W3C released the WebAuthn protocol in May 2016, and the FIDO alliance, after several revisions, released the U2F 1.2 protocol (aka CTAP 1.0) in July 2017. This combination can already be called a full-fledged FIDO 2.0 project.
Info
W3C (World Wide Web Consortium) is an international web standards organization. There are other similar organizations, such as WHATWG (supports HTML) and ECMA (supports JavaScript). The standards issued by these organizations are not mandatory, but are generally accepted.
W3C and FIDO regularly release new iterations of their specifications. So, today the standard is WebAuthn (Level 2) from 2021 and CTAP 2.1 from 2022, but there is also a new version that is still at the proposal stage. Today, FIDO2 is the most common solution of the FIDO alliance, although U2F is also used by some web services as a 2FA method, and UAF is used in mobile applications as a method of confirming an action, for example, a transaction in a banking application. In summary, you need to remember that FIDO is an alliance, FIDO1 and FIDO2 are projects, not protocols; UAF, U2F, CTAP and WebAuthn of all versions are protocols that have specifications of the same name.

FIDO2 Architecture
FIDO2 is positioned as a secure authentication method based on public key cryptography and consists of two parts — the WebAuthn and CTAP protocols. Why two protocols? This made it easier for FIDO to formalize its creation: W3C only releases standards for the web and does not decide anything on the device side. That is why it turned out to be a semi-standard standard, for which both a non-profit consortium (W3C) and an association of commercial organizations (the FIDO Alliance) are responsible.First, I will say a few words about what FIDO2 does not cover. The protocols do not cover how we get an authenticator (buy it, or it is given to us at work), how we activate the authenticator (set our fingerprint or code) and how our keys are stored (encrypted storage or a browser password manager).
FIDO2 also does not cover Passkeys, which are now starting to be offered on some large sites. The thing is that in the first FIDO2 specifications such a concept did not exist, and later the word Passkeys began to be used for convenience to refer to those same cryptographic keys. In practice, Passkeys is one of the implementations of a key based on cryptography that can be used in FIDO2 and has other useful functions, such as synchronization between devices. But it is worth remembering that neither WebAuthn nor CTAP regulate Passkeys. This is currently simply the most common solution. The main participants in the interaction are:
- user;
- authenticator (Authenticator);
- user device;
- JS client of the user device (client);
- Responsible Party (RP).
The WebAuthn protocol is responsible for the interaction between the JS client and the RP, it can be conventionally called the client API. In most cases, the JS client is the user's browser, but it can also be a native application for Android or iOS. For simplicity, we will consider the concepts of the JS client and browser, as well as the website and RP to be equivalent.
The CTAP protocol regulates the relationship between the authenticator and the user's device, it can be conventionally called the authenticator API. The authenticator can be built-in, such as Face ID, or external, such as the YubiKey hardware token, but we will not distinguish between them.
CTAP can transmit data via USB, NFC or BLE (Bluetooth Low Energy). The most attentive will probably notice that we still have a gap in the interaction between the user's device and the JS client. Unfortunately, each platform (OS) solves this issue in its own way, there are no clear standards here.
The FIDO2 architecture is conceptually shown in the figure below, with the components in different colors depending on the team or even the vendor.
Registration ceremony
No, no, we are not talking about the registry office now. There are two ceremonies in FIDO2: the registration ceremony and the authentication ceremony. Let's start with the first one. Let's make it clear right away that for readability I will use familiar data formats instead of byte (Uint8Arrays), which are actually sent in the call fields.First, the user must log in to the site, find the registration form, enter their login and click the registration button. Then the RP forms a PublicKeyCredentialCreationOptions request to the browser. This array contains:
- RP data, where rp.id is the domain within which future keys will operate, and name is the name of the resource in human-readable form.
- User data, where user.id is a unique user identifier in the RP system, user.displayName is a non-unique user name on the platform (nickname), and user.name is a unique user login.
- A challenge is a unique random value of at least 16 bytes. When registering, the challenge is not signed; it serves to protect the integrity of the data.
- Requirements for keys (pubKeyCredParams) that the authenticator must create. The preferred algorithms are listed here in descending order. For example, -7 means ES256, and the full list from IANA can be found in the documentation.
- Authenticator requirements (authenticatorSelection), as well as attestation requirements (attestation), are usually set only if the web service has some requirements from the regulator, for example, if it is a government or banking resource. Otherwise, everything is more or less standard here. For example, attestation in 99% of cases will have the value none, that is, "not required".
Certification
Attestation is an additional security procedure. Its main purpose is to establish the authenticator model. The responsible party needs this to meet the security requirements set by the regulator.If attestation is required, the generated public key will be signed by the attestation private key. The attestation private key is created on the authenticator by the manufacturer and is unique for each device model manufactured in a given time frame: for example, all YubiKey 5 manufactured from September to December 2022 will have the same key. Then the signed public key and attestation certificate are sent to the RP. The RP may or may not verify the attestation! To establish trust, the RP checks the certificate chain from the manufacturer's signature to the GlobalSign root certificate. At the same time, to determine the authenticator's capabilities, the responsible party needs to download and update the MDS3 database monthly, which contains data on each authenticator model.
Code:
PublicKeyCredentialCreationOptions
{
"rp": {
"id": "subdomain.domain.com",
"name": "Company Name"
},
"user": {
"name": "i.ivanov@mail.com",
"displayName": "Ivan Ivanov",
"id": "123e4567-e89b-12d3-a456-426655440000"
},
"challenge": "yGvVFCug1QLmaW4OnIYw7JONQP7XDSDNZ3SELT0PBhI",
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -257,
"type": "public-key"
}
],
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"residentKey": "required"
"requireResidentKey": true,
"userVerification": "discouraged"
},
"attestation": "none",
"timeout": 30000,
"excludeCredentials": [],
"extentions": []
}
After receiving the request, the browser calls the navigator.credentials.create() function, in which it checks that the rp.id value matches the domain name, and also hashes the request data. At this point, WebAuthn ends, and the OS calls authenticatorMakeCredential from the authenticator via the CTAP protocol. In general, most of the values in this array should already be familiar to you, we will only point out clientDataHash, which is the aforementioned SHA-256 hash of the request data, and options, which contain requirements for the user presence (UP) and user verification (UV) procedures, among others.
User presence and verification
Both ceremonies (registration and authentication) require one or both procedures - user presence (UP) and user verification (UV). UP is a mandatory basic procedure, which consists of user interaction with the authenticator. For example, you need to press a button. UV is a more complex, but also optional procedure, when the authenticator makes sure that the user is authorized to use it. For example, you may need to enter a PIN or provide biometrics.The WebAuthn and CTAP specifications do not strictly define these procedures, talking about some kind of "authorization gesture" that each manufacturer can understand in its own way. For FIDO2, the difference is that UV allows you to distinguish between different users of the same authenticator, while UP does not.
Code:
authenticatorMakeCredential
{
"clientDataHash": "LNeTz6C...oYH2el7Mz1NsKQQF3Zq9ruMdVE",
"rp": {
"id": "subdomain.domain.com",
"name": "Company Name"
},
"user": {
"name": "i.ivanov@mail.ru",
"displayName": "Ivan Ivanov",
"id": "123e4567-e89b-12d3-a456-426655440000"
},
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
},
{
"alg": -257,
"type": "public-key"
}
],
"excludeCredentials": [],
"extentions": [],
"options": {
"rk": true,
"up": true,
"uv": false
}
}
After receiving the request, the authenticator creates a key pair and performs other actions, a total of 19 steps in the algorithm. As a result, the authenticator returns an AuthenticatorAttestationResponse object to the operating system via CTAP. The OS passes it to the bored navigator.credentials.create() function, which forms a PublicKeyCredential and ends its cycle.
The AuthenticatorAttestationResponse returned by the authenticator is often simply called Attestation, so sometimes you can hear that the entire registration process is also called Attestation (attestation), but this is more of a colloquial name that should not be confused with the process of establishing the authenticator model described above. The formats of AuthenticatorAttestationResponse and PublicKeyCredential are almost identical, so we will consider only the latter:
- The unique parameter id is the identifier of the created key.
- Of interest is the response array, which contains clientDataJSON - this is exactly the same SHA-256 data, the hash of which was sent to the authenticator, and attestationObject, where in most cases fmt will be equal to none, since attestation is not required, and attStmt will be empty in this case.
- Inside the attestationObject is the most important array for us, authData. Here, rpIdHash hides the SHA-256 hash of the already known rp.id, which determines the scope of the key. We also see the attestedCredentialData object, which contains the authenticator identifier (aaguid), the identifier of the created key (credentialId), and the public key itself (credentialPublicKey).
- It is important to pay attention to the signCount parameter, which increases with each successful signing of the task during authentication. We will remember it when we consider one of the attacks on the protocol.
Code:
PublicKeyCredential
{
"id": "AV19-ikcu3tKuMxfFnRZ9gU6tnDH6QqzYwUg",
"response": {
"clientDataJSON": "ew0KCSJ0eXBl...A0KCSJjaGFsbGVuZ2UiIDogInlHdl",
"attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdX...jLvw6oUiKGB"
"authData": "LNeTz6C0...hSIoYH2el7Mz1NsKQQF3Zq9ruMdV"
},
"transports": {
"internal"
},
},
"clientExtensionResults": {
"credProps": {
"rk": true
}
}
}
Array components in detail:
Code:
"clientDataJSON": {
"challenge": "qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10",
"origin": "https://subdomain.domain.com",
"type": "webauthn.create",
"crossOrigin": false,
"tokenBinding": {
"status": "unsupported"
}
}
"attestationObject": {
"fmt": "none",
"attStmt": [],
"authData": "LNeTz6C0...hSIoYH2el7Mz1NsKQQF3Zq9ruMdV"
}
"authData": {
"rpIdHash": "LNeTz6C0GMu_DqhSIoYH2el7Mz1NsKQQF3Zq9ruMdVE",
"flags": {
"up": true,
"uv": false,
"at": true,
"ed": false
},
"signCount": 0,
"attestedCredentialData": {
"aaguid": "YCiwF7HUTAK0s6_Nr8lrsg",
"credentialId": "AV19-ikcu3tKuMxfFnRZ9gU6tnDH6QqzYwUg",
"credentialPublicKey": "pAEDAzkWZFf4weLZ...kjWm6vNvT-JWMqe39MBAAE"
}
}
At the final stage, the browser sends the PublicKeyCredential to the RP. The RP verifies the received data, for example, checks whether the received keys and algorithms meet the stated requirements, and performs certification. In total, the WebAuthn specification assumes an algorithm of 19 steps. If successful, the RP saves the credentialID and public key with metadata in its database. Then the user is most often redirected to the login page to log in.
Authentication Ceremony
The second ceremony is the authentication ceremony. It is actually very similar to the one described above, and the arrays contain fewer values, so we will not analyze it in great detail. First, the user must find the login form on the site, enter his login and click the login button.Conditional UI
Conditional UI (aka Passkeys autofill) is an autofill feature. It is not part of WebAuthn, but an additional development that the RP can implement on the front end for ease of use.Conditional UI works only for authentication and is supported by most browsers or built-in OS calls for native apps. Conditional UI only works with discoverable keys (see below) and may also conflict with password manager autofill capabilities. It does not require any plugins to be installed on the user side.
The RP generates a PublicKeyCredentialRequestOptions request to the browser that contains:
- The challenge parameter. It is worth emphasizing that WebAuthn does not describe how this value should look and what algorithm should be used to create it.
- The rpId parameter defines the trust area within which the key operates. If the web resource specifies it incorrectly, the authenticator will not find the key and we will get nowhere.
- The most interesting parameter is allowCredentials. Here, RP specifies the identifiers of keys that are already registered for this login. In theory, this solution helps to save the user from choosing a key or registering a new authenticator if he forgot which one the key is stored on. But from a security point of view, it looks like a great opportunity for a user selection attack. This field is optional for discoverable keys, but for undetectable keys it will still have to be filled in.
Discoverable and Undiscoverable Keys
There are two types of keys, discoverable (or resident) and non-discoverable (or non-resident). They differ in where they are stored and how they are requested. In FIDO2, discoverable keys are created by default.Discoverable keys are stored on the authenticator, and during login, the authenticator prompts the user to select which of the domain keys (rp.id) to use.
Non-discoverable keys are not stored on the authenticator, but are created as a derivative of the authenticator's master key and seed. During login, the RP sends the authenticator the key identifier and seed, and the authenticator recreates the key and signs the challenge. Since the key is only available in the authenticator's memory for a certain time, it is also called ephemeral, and the authenticator itself does not know that the key exists unless it is told about it.
Code:
PublicKeyCredentialRequestOptions
{
"publicKeyCredentialRequestOptions": {
"challenge": "kYhXBWX0HO5GstIS02yPJVhiZ0jZLH7PpC4tzJI-ZcA=",
"timeout": 30000,
"rpId": "subdomain.domain.com",
"userVerification": "discouraged",
"allowCredentials": [
{
"id": "X9FrwMfmzj...",
"type": "public-key"
}
],
"extensions": []
}
}
Next, the browser calls the navigator.credentials.get() function, in which it checks that the rp.id value matches the interaction domain, and also hashes the request data. At this point, WebAuthn ends again, and the OS calls the authenticatorGetAssertion function of the authenticator via the CTAP protocol.
Having received the request, the authenticator finds its private key and performs other actions, including interaction with the user. The entire algorithm involves 13 steps. As a result, the authenticator via CTAP returns an AuthenticatorAssertionResponse object to the operating system, which it passes to navigator.credentials.get(). This function forms a PublicKeyCredential and ends its cycle.
The AuthenticatorAssertionResponse returned by the authenticator is often simply called Assertion, which is why you can sometimes hear that the entire authentication process is also called Assertion (confirmation) - by analogy with how registration is often called attestation.
For clarity, let's look at the difference in the data sent in the PublicKeyCredential array during registration and authentication.
- Note the signCount parameter, which has increased by one compared to the one sent during registration, as the task was successfully signed.
- The signature parameter is a task signed with a private key. In essence, this is a confirmation proving that the user owns a private key that corresponds to the public key stored by the RP.
- The userHandle parameter is new to us in form, but in content it is a unique user identifier for the responsible party. That is, it is assigned the value user.id known to us.
Code:
PublicKeyCredential
{
"id": "X9FrwMfmzj...",
"response": {
"authenticatorData": {
"authData": {
"rpIdHash": "LNeTz6C0GMu_DqhSIoYH2el7Mz1NsKQQF3Zq9ruMdVE",
"flags": {
"up": true,
"uv": false,
"at": false,
"ed": false
},
"signCount": 1,
},
"clientDataJSON": {
"challenge": "kYhXBWX0HO5GstIS02yPJVhiZ0jZLH7PpC4tzJI-ZcA",
"origin": "https://subdomain.domain.com",
"type": "webauthn.get"
},
"signature": "MEUCIQDNrG...HD3UWA",
"userHandle": "123e4567-e89b-12d3-a456-426655440000"
},
"clientExtensionResults": []
}
At the final stage, the browser sends the PublicKeyCredential to the responsible party. It verifies the received data, for example, checks whether the challenge matches. The entire verification algorithm in the WebAuthn specification is 23 steps. If successful, the RP sends the user a session cookie.
Attacks on FIDO2
FIDO2 provides protection not only from weak passwords, but also from phishing and MitM attacks, as well as increased privacy of user data. Moreover, even if hackers break into the company's server, users will not be compromised. Let's look at each of these statements one by one.First, if the server is hacked, the client's secrets will indeed not be compromised, since only the public key and other metadata are stored on the web service side, there is no private key. However, everything that this private key protected will end up in the hands of intruders - that is, the very data dear to our hearts.
Secondly, phishing. Here, too, we agree with the developers of the standard: we remember that when registering, RP exchanges the rp.id value with the browser, to which the private key is linked. Therefore, even if you enter the wrong door, the authenticator will not sign anything. But there is nothing fundamentally new here, any password manager has such a function.
Let's move on to the most interesting part. The synchronized login attack is specific to FIDO2, but relies on good old clickjacking. If you install an invisible frame on a vulnerable site, inside which you place a panel for login from another domain where the user is also registered, both authentications will occur: the one the user planned, and the one the attacker planned.
Someone will definitely say that the authenticator shows the user a notification about what resource he is visiting. However, Tarun Kumar Yadav noted in his research ( PDF ) that only one in twenty users checks the domain name in the pop-up, and no one considers double-clicking on the authenticator to be malicious.
Another interesting attack is authenticator cloning. Now this is a difficult task, but not impossible. So, in 2024, NinjaLab specialists managed to successfully clone YubiKey 5 hardware keys.
FIDO2 has protection against such types of attacks - the same signCount, which, if it does not match on the authenticator and RP side, will not allow successful login. But this protection mechanism is easily bypassed. The fact is that the authenticator increases signCount after each successful signing of the task, and the RP - after each successful authentication, that is, in fact, both parties act independently.
Let's assume that the attacker copied your hardware token, when signCount is 200, we will designate this as A = 200, L = 200 from the words Assertion on the authenticator side and Login on the RP side. The attack progress is shown in the table below. The attacker successfully logs into the resource, while A increases only for him, and L - for all participants.
When the user tries to log in, he will get an error, because A and L will not match, but the user's authenticator will successfully sign the task and increase signCount, and the RP will not successfully log in and leave the signCount value unchanged. Accordingly, both values will be equal and the second login attempt will successfully log in to the account. Unfortunately, sites only show a general error message, often asking the user to re-login when the error no longer occurs.
Stage | The intruder | Sacrifice |
---|---|---|
1. Original meaning | A=200, L=200 | A=200, L=200 |
2. The intruder entered | A=201, L=201 | A=200, L=201 |
3. The victim tries to enter | A=201, L=201 | Error because A != L |
4. The victim tries to enter again | A=201, L=201 | A=201, L=201 |
Another simple attack that can be considered is session hijacking. Even after super-duper secure authentication, we are left alone with the HTTP protocol, which does not store state and relies on cookies. Therefore, if a site is vulnerable to, for example, XSS, it is possible to completely take over the user's session. And MitM attacks are not prevented in any way.
FIDO2 relies on a TLS connection, while MitM did not disappear with the introduction of TLS. So you should not expect problems to be absent in this case either.
I think it is not even worth talking about cases where the root certificate is held by your organization or a government agency. The situation could be saved by Token Binding technology ( RFC 8471 ), which binds the TLS connection to the user's browser, but, unfortunately, it is not mandatory in FIDO2, and browsers practically do not support it.
As we can see, FIDO2 has internal protocol vulnerabilities and does not provide protection against many attacks. For example, Michal Kepkowski's research provides an example of a remote timing attack to determine the keys available on the authenticator. The researcher also points out that the UP procedure is easily simulated, and since most responsible parties do not require UV, this creates another vector for bypassing FIDO2 protection mechanisms.
Tarun Kumar Yadav also points out that 47% of browser extensions from the Chrome Web Store can perform at least five FIDO2-specific attacks, although no truly malicious extensions aimed at such attacks were found.
I will also note that the issue of FIDO2 privacy remains open - the user still leaves a ton of personal data on the RP side, and profiling by standard methods has not gone away.
Conclusions
Among the obvious advantages of FIDO2 is protection from the two most common cyberattacks: phishing and password guessing. This is certainly encouraging, but we should not forget that the combined use of the same password managers and 2FA gives almost the same effect.Of course, BA looks simpler and more convenient - the user is not required to enter or invent anything, everything, except for a few clicks, happens automatically. Also on the side of FIDO2 is the fact that this technology is supported by all major browsers and OS.
Although passwordless authentication is cool, most web resources still do not introduce it. Companies do not see the point, because, firstly, everything works fine with passwords now, secondly, users are used to passwords, and thirdly, BA is a new process, and you will have to agree on it, choose software and pay developers. That is, BA for business is long, expensive and uninteresting.
Moreover, FIDO2 is only protocols, and their implementation, correct configuration of requirements for authenticators, support of mechanisms for restoring access and storing data depends on the responsible party. This imposes additional responsibility on the business and creates new risks. Perhaps, this is why BA is still based on the sheer enthusiasm of individual companies, and serious changes can only occur after the intervention of regulators.
BA may be convenient, but does the average user understand how it works, where the magic keys are stored and what should not be done? At least now people know that passwords should be complex and should not be shared, that there is phishing, and, in fact, users consciously take risks by not observing the rules of information hygiene. And BA and hardware tokens are just magic for people.
For example, we can recall how small companies treat the CEO's digital signature: a hardware token with it walks around the entire office and each employee signs and accepts documents with the CEO's signature.
The password can be easily transferred to a trusted person, and everyone knows how to do it. BA will bring new ways to share access, but for them to work, compatibility between devices is needed. And users themselves must know how this function works and be able to use it.
Not everything is so smooth with FIDO2 itself either. The CTAP and WebAuthn protocols have internal vulnerabilities and weak security mechanisms, and between them there is an OS layer that makes us dependent on a third party whose actions FIDO2 does not regulate.
FIDO2 is still susceptible to MitM and session theft, and in terms of user privacy, it does not give new hope. Hardware tokens are not updated, as this carries the risk of infecting them, so the burden falls on the user not only to choose and buy hardware, but also to replace it in the event of a critical vulnerability.
For the sake of convenience, BA suggests abandoning the password and using only one factor. It turns out that we are sliding from the usual 2FA, where there is both a password and an OTP code, to 1FA, where there is only an authenticator. Of course, it is possible to implement a multi-factor BA and use, for example, biometrics, but what is the difference with the current password authentication? You will still need to enter different codes and even carry a hardware token with you, which increases the risk of losing it.
FIDO2, like the BA idea, certainly looks very promising. A lot of work has been done, large companies have agreed to act together for a noble goal - to make life easier and safer. And although the beginning of the passwordless revolution has already been laid, there is still a lot of work to do. This means that in the foreseeable future we are unlikely to abandon passwords.
Source