Building strong access management using Open Standards

Dec 28 / Michael Boeynaems

TL;DR

Take a look at the demo web application. It uses OpenID Connect as federation protocol, WebAuthn (FIDO2) as authentication protocol, and complies with the recent NIST 800-63B password guidelines thanks to the haveibeenpwned database of compromised credentials.

To be able to register, you need a recent web browser and a FIDO2 certified authenticator.

Introduction

Passwords are very much alive. Despite the efforts made to entice users in adopting other authentication mechanisms, the password is still the most prevalent one. Wikipedia has a long list of people who claimed the password was dead. They were wrong. I won't bother writing yet another article about why passwords are considered insecure and assume you know why.

Rather, I want to write about how to counter the risks that passwords bring along given the fact that they will remain alive for several years to come. Also, I'd like to clearly position three terms that are often heard in access management discussions, and explain how you can put them to pratcical use:

  • OpenID Connect (OIDC)
  • FIDO2 (including CTAP and WebAuthn)
  • haveibeenpwned

Risk of using weak passwords

Just about anyone can download a password database after a quick DuckDuckGo search. Next, there is almost no knowledge required to start firing off these passwords against targets at will. Surely, it is likely that lockout mechanisms are in place; however, it is dangerous to rely on these alone since passwords are often reused across systems. Simply reusing credentials does not require brute-forcing them. Lockout mechanisms are not very effective neither against offline brute-force attacks or credential spraying attacks. The 2019 Data Breach Investigation report published by Verizon confirms the fact that the state of affairs with regards to passwords is very problematic: > 29% of breaches studies involved the use of stolen credentials. (DBIR 2019, Verizon)

Therefore, using weak passwords is a risk. To understand how big of a risk, we can use the brand-new OWASP risk rating calculator. After selecting the correct option for each factor, we end up with a risk severity of 'critical'. My risk assessment of using weak passwords is visualized below.
Of course, your estimation of a certain factor may differ a bit from mine. For example, you may feel that a threat agent needs to possess at least some technical skills to execute a password attack. However, I do hope we can agree that the overall risk of using weak passwords is 'high' at least.

Why the password isn't dead

While the password is not dead yet, there are a plethora of alternatives available: biometrics, hardware tokens, software tokens, cryptographic devices, ... One could wonder why the password has been and seems to continue being the fittest around. Part of the answer is provided by Joseph Bonneau, Cormac Herley, Paul C. van Oorschot, and Frank Stajano. In a 2012 paper1 they compare 36 authentication methods on three scales:

  • usability: how easy it is for a user to use the authenticator2
  • deployability: how easy it is for a server to deploy the mechanism, including compatibility considerations
  • security: how secure the authenticator is

The result was that some mechanisms are more usable than passwords, some are more secure, but there is **not one other mechanism that is more deployable than passwords**.

As a simple example let's take the fingerprint mechanism. This is less accessible than a password, especially in environments where people wear gloves of some sort. It also has a non-negligible cost per user, requires server as well as client changes, and often involves the use of proprietary software and hardware (fingerprint readers). The authors combine all of these properties into the definition of 'deployability', this is why fingerprint scores poorly in this category.

1 scroll to page 27 of the paper for the table containing the evaluation results.
2 an authenticator is something that is used to verify the user's identity.

NIST 800-63b

Authenticator types

While the paper by Bonneau et al. contained 36 authenticators, NIST recently issued a list of 9 authenticator types. Every authenticator can be categorized in one of these 9 authenticator types. This list can be consulted in the NIST 800-63b guideline, and a summary is given in the table below for your convenience. I've added at least one example authenticator per type, but you should be aware that any authenticator existing today can be classified in this table:
SYK stands for Someting You Know, SYH for Something You Have, and SYA for Something You Are. These are the three so-called factors in which authenticators can be classified. Since that categorization is coarse, the categorization of NIST as provided in the table before is more useful.

Assurance levels

Some types are less trustworthy than others and thus provide a different assurance level. NIST defines three assurance levels (level 1, level 2, level 3). Each assurance level has one or more permitted authenticators that are secure enough for that level. For example, all authenticators may be used for assurance level 1, whereas a limited set of authenticators are secure enough for assurance level 3 (e.g. a multi-factor cryptographic device). The full overview of the link between the NIST assurance levels and permitted authenticators is provided in my course Introduction to cyber security but can just as well be consulted in section 4 of the NIST guideline.

Theoretically, we are now fully equipped to set up secure access management. But in reality, we have a hard problem since there are M authenticators and N applications that we need to secure. A change in any one authenticator may impact all applications supporting that authenticator, requiring expensive development rework. Worse yet, this rework may lead to security vulnerabilities when not done properly. Adding to the complexity is the fact that our application landscape may consist of X technologies which each have their peculiarities when it comes to supporting the NIST authenticator types.

FIDO2 and OpenID Connect

Simply said:
  • FIDO2 solves the problem of having M authenticators by defining a standard interface which can be used to interact with these authenticators, and tries to improve on the 'deployability' factors discussed previously;
  • OpenID Connect (OIDC) solves the problem of having N applications by defining a protocol which moves the authentication logic out of the application and places it in one central server;

FIDO2

FIDO2 is the successor of the original FIDO standard. The original FIDO standard did not get adopted by many vendors and could not really be called a success. FIDO2 is a different story since it was co-created together with W3C, an international community where web standards are developed. Therefore it is now being supported by many browsers and is quickly gaining a lot of traction.
It is important to understand FIDO2 has been split up in two specifications:

  • WebAuthn, now maintained by W3C
  • CTAP, still maintained by the FIDO Alliance


CTAP specifies the communication between an authenticator (e.g. a Yubikey, which is a USB or NFC enabled security key used for strong authentication) and a platform (e.g. Windows). By extension, this spec describes the link between the platform and recent browsers as well. CTAP is relevant only to manufacturers of authenticators, developers of the firmware for these devices, and to browser creators such as Mozilla or Google. Therefore, I will not explain CTAP further in this post.

The WebAuthn part, on the other hand, defines an API (callable via Javascript) which enables the use of strong, public key-based credentials to authenticate users. This API can be called by anyone creating a web application. In other words, WebAuthn enables the use of strong single-factor cryptographic authenticators such as a Yubikey or Windows Hello in an easy, platform-independent manner.

What's in it for me?

The impact of this should not be misunderstood: any web-based application can now effortlessly support the plethora of FIDO2 compliant strong authenticators. They can do so simply by calling the APIs as specified in the WebAuthn standard. Before WebAuthn, if an application wished to adopt facial recognition, they had to search for complex and sometimes expensive facial recognition software that could be run in Javascript, or build middleware that users had to install first. WebAuthn will work for mobile apps too, which means that requiring a fingerprint to authenticate in your app will be easier than ever before3!

3 Android, Windows, MacOS and various Linux distributions currently support WebAuthn. iOS currently limits the use of WebAuthn to NFC authenticators only: TouchID and FaceID are not yet WebAuthn ready.

Federated identity with OpenID Connect (OIDC)

Contrarily to what the previous paragraph suggests, it turns out that deploying your application and calling the WebAuthn API's in the browser using Javascript is not super-easy. It is easy, but not super-easy. This is mainly due to the fact that something needs to be stored in your database: when using passwords, you need to store a password. When using WebAuthn, you need to store a public key.

All of that is easy to do for one application, but most likely you have a whole set of applications that you would like to prepare for use with strong authenticators. Now, if you remember well, that's the problem of having N applications. You had to support password-based authentication in all of your N applications. Now you have to support WebAuthn in all of your N applications. Tomorrow there's a vulnerability in some WebAuthn library you are using and you need to update all of your N applications.

Why not put all of that authentication logic in one single server, and have multiple applications _trust_ that one single server? Basically, all applications keep most of their (functional) responsibilities, but one responsibility moves to the central server: authentication. That's exactly what federation means, and it is technically enabled by protocols like SAML, OAuth2, and OpenID Connect.

FIDO2 en OpenID Connect - Conclusion

So now we have a central server that supports password-based authentication. It also supports the WebAuthn standard and therefore M strong authenticators. The only thing your N applications now have to do is simply trust that central server by supporting at least one federation standard: SAML or OpenID Connect (OAuth2). For those in need of a sequence diagram that ties it all together, here you go. Don't forget to use the demo application to see this flow in practice4:
4 the demo application currently does not call an API (the most right-hand component on the sequence diagram).

But... what about my passwords?

The old complexity requirements

I started this post by saying the password wasn't dead yet, and yet I moved on to explaining the abundance of strong alternatives to passwords. For all of you out there who use passwords (myself included), there is some good news: the rules became easier!

Remember those nifty password complexity rules that were (and still often are) required when choosing a new password? For years you were using the word password as your, well... password and nobody complained. And suddenly, websites started requiring adding a number to it (passw0rd). Some even required the use of a symbol (p@ssw0rd). Others needed you to come up with a capital (P@ssw0rd), whereas some of them required a length of at least 12 (P@ssw0rd123!).

The updated complexity requirements

Do you think P@ssw0rd123! is a strong password?

Nope, it isn't. And while I'm not going to go into detail about tricks to come up with a strong password, I do want to dive into the new NIST password complexity requirements.

NIST 800-63b contains what NIST suggests as being the best password complexity requirements. These are:
  • a password must be at least 8 characters in length
  • a password cannot appear in a blacklist (dictionary words, passwords obtained from previous breach corpuses, etc.)

That's it! No more symbols, no more capital letters, no more periodic changes. All of that can go out of the window.

Password blacklists

Let's take our complex password that we came up with before: P@ssw0rd123!. It's definitely more than 8 characters in length. But does it appear in a blacklist? One of the most well-known password blacklists is haveibeenpwned. The maintainer of that website executes those quick Duckduckgo searches that we discussed before for a whole bunch of breaches, and indexes the result.

P@ssw0rd123! sadly is not a good password:

Integration with the haveibeenpwned database

Great, so we have the haveibeenpwned blacklist and some other good blacklists simply there to grab. The only technicality remaining is now to integrate them with our systems that actually use passwords. Luckily, we are using federation which basically means we only have one system storing passwords.

The other good news is that there is an haveibeenpwned API available, waiting to be called by our central authentication server. Our central authentication server can simply compare my password with that blacklist during registration5, and deny the password in case it is present in the list. Depending on which authentication server we are using, it may need some research as to how the haveibeenpwned API can be called, but examples exist.

In case you do not wish to be dependant on an external API, an alternative is to download the password list and use it as a blacklist6. An example of Active Directory is here.

5 to protect the privacy and the passwords of your users, you should never send a plaintext password to the haveibeenpwned servers. However, that does not mean you cannot use the API. All of that is explained here.
6 Note that the haveibeenpwned download contains the SHA1 version of breached passwords, not the plaintext version.

Putting it all together

The demo application puts all considerations into practice:
  • It uses a central authentication server based on Keycloak
  • It uses federation by means of OpenID Connect to trust that central authentication server
  • The central authentication server supports WebAuthn and therefore Windows Hello, Yubikeys, etc.
  • The central authentication server will enforce a minimum length restriction of 8 characters and call out to the haveibeenpwned API during registration;


 Trying to register using our weak password (P@ssw0rd123!) will, therefore, produce an error:

Conclusion

I guess I must admit that the title of this post may have promised more than what I delivered. This post mainly talked about authentication. Authorization on the other side of the access management coin, discussed more in detail in my course Introduction to cyber security.

Final note:
The source code for the demo application is on GitHub

References:
  • https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-817.pdf
  • https://haveibeenpwned.com/PwnedWebsites
  • https://pages.nist.gov/800-63-3/sp800-63b.html