User tests: Successful: Unsuccessful:
Pull Request for new feature: passwordless authentication with W3C Web Authentication (WebAuthn)
This PR replaces the ill-fated PR gh-25797 and comes with the following changes:
This PR adds support for WebAuthn (W3C Web Authentication). This is a W3C standard made official in March 2019.
WebAuthn allows users to authenticate (log in) securely into a site without using a password. Instead it uses authenticators. An authenticator is either a discrete hardware device or a Trusted Platform Module (TPM) / Secure Enclave built into your device. Moreover, it only works under HTTPS. By using secure hardware and secure transport it makes sure that the authentication is resistant to eavesdropping, phishing, brute-force and other attack modes associated with fixed passwords.
Before continuing please take a minute to learn more about WebAuthn and play with it.
The following is a collection of errata for the Joomla 4 build process which have nothing to do with this PR but may get in your way while testing. I wasted time so here's my distilled experience so you don't have to suffer :)
After merging this PR to your local 4.0-dev branch (or cloning the repo it pulls from) you need to run composer install
and npm install
. If you fail to do that there will be missing PHP dependencies and JS files and the whole thing will fail.
If npm install
fails you need to delete the folders node_modules
and administrator/components/com_media/node_modules
. Then you can run npm install
again.
Joomla will fail to load after installing when you run composer install
. You'll get some cryptic error about Atum missing assets and / or missing classes. That's not a bug in this PR, it's a "feature" of Joomla 4's build process. You need to delete the libraries/autoload_psr4.php
file. Your site will magically work.
FWIW, these issues are currently being fixed by someone else.
If you are applying this PR on an existing Joomla 4 development site please remember to not only do the steps above but also go to System, Fix Database. You will then need to use Discover to find and install the plugin. Finally, make sure that the System - WebAuthn Passwordless Login plugin is enabled.
i. Requirements
Your site must be using HTTPS with a certificate your browser recognizes as valid. For simplicity's sake, please use a live server with a valid SSL certificate, e.g. one issued by Let's Encrypt.
An authenticator. A FIDO or FIDO 2 compatible hardware key is the best. You may also use a software FIDO key such as Krypton. I have tested this PR with a YubiKey Neo (FIDO over USB and NFC), a Security Key NFC by Yubico (FIDO 2 over USB and NFC) and Krypton (FIDO over Bluetooth / browser extension).
WebAuthn compatible browser. Not all browser versions are compatible with WebAuthn. If unsure, check if you can use the WebAuthn.io site with it BEFORE trying to test this PR. At the time of this writing no browser on iOS will work with WebAuthn, Safari is mostly broken and Chromium-based browsers (except Chrome itself) do not work with Touch ID on macOS. Your best bet is Google Chrome and Firefox on desktop operating systems or Android.
ii. Enabling the plugin
Go to Plugins and enable the “System - WebAuthn Passwordless Login” plugin.
iii. Perform basic tests
Please conduct the following tests in the following order. If something doesn't work please first read the FAQs below.
If your solution is not there first check if the same combination of operating system, browser and authentication work with the webauthn.io site. If not, the problem is between your OS, browser and authenticator. It is not a bug in the plugin and cannot be magically fixed.
If you could not find an answer in the FAQs and your authenticator worked with webauthn.io please provide the following information:
Log out from your site's frontend and backend.
Go to your site's frontend home page and look at the login module. You should see a “Web Authentication” button under the Remember Me checkbox.
Go to your site's frontend user page (/index.php/component/users/login
). You should see a “Web Authentication” button under the Remember Me checkbox.
Go to your site's backend page (/administrator/index.php
). You should see a “Web Authentication” button under the Remember Me checkbox.
Log out from your site's frontend and backend.
Go to your site's frontend home page and locate the login module.
Type your username but NOT your password.
Click on the “Web Authentication” button.
Expected: an error message that the username does not exist or is not linked to WebAuthn.
Log in to your site's backend using your username and password.
Go to Users, Manage and click on your username.
Click on the “W3C Web Authentication (WebAuthn) Login” tab.
Click on the big, green “+ Add New Authenticator” button and interact with your authenticator. Please note that the prompt to interact with your authenticator is specific to and rendered by your browser.
Expected: You see a new authenticator appearing on the list above the green button. There is no need to click on “Save & Close”; the authenticator assignment is (and has to be, for seriosu security reasons) saved during the previous interaction.
Log in to your site's backend using your username and password.
Go to Users, Manage and click on your username.
Click on the “W3C Web Authentication (WebAuthn) Login” tab.
Find the authenticator you created before and click the “Edit Name” button next to it.
Expected: The name becomes and editable text field with a Save and Cancel button next to it.
Click on “Cancel” next to the text field.
Expected: the old name remains.
Click the “Edit Name” button again. This time enter a new name and click on “Save” next to the text field.
Expected: the new name sticks.
Log in to your site's backend using your username and password.
Go to Users, Manage and click on your username.
Click on the “W3C Web Authentication (WebAuthn) Login” tab.
Find the authenticator you created before and click the “Remove” button next to it.
Expected: the authenticator is gone.
Also repeat test 2 and make sure you still get the expected message.
Log in to your site's frontend using your username and password.
Go to the user profile editor page (/index.php?option=com_users&view=profile
). Please note that if you try using Joomla's sample data menu items such as Your Profile it won't work. This is a bug in the sample data that has nothing to do with this PR (I confirmed it happens with a from-scratch installation of the current Joomla! 4 development branch).
Click on the Edit Profile link at the top right of the main content area and find the “W3C Web Authentication (WebAuthn) Login” area towards the bottom of the page's content area.
Perform tests 3, 4 and 5 replacing the first three instructions of each test with Test 6's first three instructions.
Perform test 3 again. You will now have an authenticator registered for your user account.
Go to the frontend of your site and locate the Login module.
If you are already logged in please click on Logout to log out of your site.
Enter your username but NOT your password.
Click on the “Web Authentication” button in the Login module.
Expected: your browser asks you to interact with your authenticator. Please note that the prompt to interact with your authenticator is specific to and rendered by your browser.
Interact with your authenticator as requested.
Expected: you are logged into your site's frontend.
Make sure you have an authenticator registered for your user account. If not, perform test 3 again.
Go to the frontend login page (/index.php/login
). Please note that if you try using Joomla's sample data menu items it won't work. This is a bug in the sample data that has nothing to do with this PR (I confirmed it happens with a from-scratch installation of the current Joomla! 4 development branch).
If you are already logged in please click on Logout to log out of your site.
Enter your username but NOT your password.
Click on the “Web Authentication” button in the Login module.
Expected: your browser asks you to interact with your authenticator. Please note that the prompt to interact with your authenticator is specific to and rendered by your browser.
Interact with your authenticator as requested.
Expected: you are logged into your site's frontend.
Make sure you have an authenticator registered for your user account. If not, perform test 3 again.
Go to the backend login page (/administrator
).
If you are already logged in please log out now.
You should be seeing the backend login page now.
Enter your username but NOT your password.
Click on the “Web Authentication” button in the Login module.
Expected: your browser asks you to interact with your authenticator. Please note that the prompt to interact with your authenticator is specific to and rendered by your browser.
Interact with your authenticator as requested.
Expected: you are logged into your site's backend.
Repeat test 3 as many times as necessary to attach multiple authenticators to your Super User account.
Repeat tests 7, 8 and 9 once for each authenticator you have registered. You should be able to log into your site with any of your authenticators.
Important! Not all authenticators are supported in all browsers. For example, you may register a Krypton software authenticator and a Touch ID / Windows Hello / biometric authenticator using Chrome but you won't be able to use either using Firefox for example. This is NOT a bug in the PR; it's a browser limitation. The idea behind registering multiple authenticators is that you may actually need to have multiple physical authenticators to support all your devices e.g. Touch ID for your work MacBook Pro, a USB hardware key for your personal desktop PC and an NFC hardware key for your Android device. If it wasn't for this much-needed flexibility we'd only allow a single authenticator per user account.
As far as I can reasonably tell, this PR does not adversely affect backwards compatibility.
It should be noted that login modules will require to support the onUserLoginButtons event for user plugins to ensure full compatibility with Joomla 4 and the WebAuthn feature. However, any module not supporting this new feature will still work without any adverse effects.
Finally, com_ajax is available in the backend login page with no authenticated user. If there are any insane developers out there who assume that a com_ajax request in the backend of the site means that someone is logged in should change their code and reconsider their life choices because, frankly, this is a sign of not knowing what they're doing. Always use Factory::getApplication()->getIdentity()
to get the currently logged in user to figure out if it's logged in and which permissions it has.
A new plugin was added which requires translating the following files:
administrator/language/en-GB/en-GB.plg_system_webauthn.ini
administrator/language/en-GB/en-GB.plg_system_webauthn.sys.ini
The plugin itself as well as two smaller core but backwards compatible changes implemented will need documentation.
The plugin module and com_users now use the onUserLoginButtons
event, defined and called in Joomla\CMS\Helper\AuthenticationHelper::getLoginButtons
, to retrieve the definitions of any additional buttons which need to be placed after the regular login button.
All developers implementing a login module or, more generally, a login form should also use the Joomla\CMS\Helper\AuthenticationHelper::getLoginButtons
public static method to retrieve said definitions and render these buttons to make their software fully compatible with Joomla 4.
Developers wishing to implement custom buttons should look at how the WebAuthn system plugin implements this functionality. Such buttons can be used for implementing third party single-sign-on services or even logging in using third party identity services such as those offered by popular social media (Facebook, Google, Twitter, GitHub etc).
This change does not adversely impact backwards compatibility. Third party login modules and login forms will continue functioning normally even if they do not implement the extra login buttons feature with the notable omission of integrations afforded by said feature such as Web Authentication itself. That is to say they won't stop functioning (which would be a b/c break) but they won't be feature-complete. Therefore the impact is much more benign that, for example, that of not including the Two Factor Authentication's Secret Code field back in Joomla! 3.2.
Throughout Joomla! 3 com_ajax was limited to logged in and guest frontend users, as well as logged in backend users. This PR whitelists com_ajax in AdministratorApplication
so it can be used to handle requests by guest users viewing the backend login page.
This change does not cause any backwards compatibility issues as long as developers use sane practices and do not assume that being called by com_ajax in the backend is proof that the user is logged into the backend. That would be a bad security practice. The sane practice is to use Joomla's User
object to detect if it's a guest user and if not whether the user is allowed a permission required to effect the action requested through com_ajax. That is to say, if this change broken your code then your code was already broken six ways to Sunday and needed to be reworked anyway. You are welcome for the unexpected security audit :)
Obviously someone other than me needs to write some documentation for this plugin. A good idea would be to base it off the tests and information I include in this PR, especially the FAQ that follows. Someone who can translate engineer-speak to user-speak would be fantastic for this task :)
You are not accessing your site under HTTPS. WebAuthn is only available for HTTPS sites with a valid certificate. This is a security precaution baked into the WebAuthn standard. The plugin actually checks if the site is accessed through HTTPS using Uri
(the former JUri
class). In rare cases where the server lies about the protocol you might not see the button even though your site (claims to be) HTTPS. However, I'd argue that if your SSL terminator doesn't inform your web server that the site is being accessed through HTTPS you have a major security issue with cookies and you should fix it instead of complaining about this PR not rendering the WebAuthn button.
Also note that third party login modules and components implementing their own login form will not display these buttons just yet. We added new infrastructure to support them, much like what we had to do in Joomla! 3.2 to support Two Factor Authentication.
Yes and no. The current implementation in browsers only allows authentication, not identity validation.
It is a bug but not with the plugin itself.
One or more plugins on your site throw PHP Notices, Warnings or Errors, thus corrupting the reply sent back by your server. As a result the JavaScript on the page cannot parse the server response and is unsure whether any authenticators are registered by the user.
Go to your site's backend, System, Global Configuration and set Error Reporting to None. In most cases of misbehaving core and 3PD plugins this is enough. Otherwise please examine the output of the request using your browser's developer tools to see what is corrupting the request.
This should no longer be happening with iOS 13, iPadOS 13 and macOS Catalina.
This is a Safari bug in older versions of Safari. Older versions of Safari only included support for WebAuthn as an experimental feature and not quite finished. In my tests it also only worked with USB hardware keys (FIDO and FIDO 2).
This should no longer be happening with iOS 13, iPadOS 13 and macOS Catalina.
This is another bug in older versions of Safari. Close your browser (CMD-Q) and restart it. In most cases it will work. If you've registered more than one authenticator it will still not work properly.
Only Google Chrome on a limited number of platforms correctly supports built-in authenticators with biometric security. Chrome-derived browsers such as Opera or Brave will ask you if you want to use a built-in sensor but will promptly crash when you select this option. Other browsers such as Firefox and Safari won't even offer this option. This is a limitation of the browsers and cannot be worked around.
If you are using Windows please remember that your device MUST have a Trusted Platform Module (TPM) chip and it must be enabled in the BIOS. Just having a Windows Hello-compatible biometric sensor won't do the trick. This is a security precaution in the WebAuthn standard itself: the authenticator information must be processed using secure, tamper-resistant hardware to prevent key subversion (e.g. malware running on the computer cannot steal the key used for authentication).
Also, please do remember that WebAuthn is still a very new standard. By the time Joomla 4 is released browsers will have progressed far enough to make WebAuthn more usable for the average user. We are currently experiencing the bleeding edge of secure logins as it's being developed.
The linchpin of WebAuthn is the absolute secrecy of the private key. It is only known to the authenticator and it should be impossible to communicate to the outside world.
In the case of a hardware authenticator, be it a discrete hardware device or a TPM / Secure Enclave, this is a given by the very nature of the authenticator.
A software authenticator generates and stores a secret key. However, it is still a regular software application which runs inside your regular operating system, be it your phone's or your computer's. As a result it is susceptible to several classes of attacks which can be used to surreptitiously steal information (security issues in the software itself, malware using Spectre-class vulnerabilities in modern CPUs etc).
So, a software authenticator is far more convenient and secure than a regular password but a hardware authenticator offers the best security. Choose your authenticator based on your budget and security needs.
Considering that the price of a FIDO key –which is compatible with WebAuthn– is under €10 on Amazon you can use a hardware authenticator in most practical cases.
The only thing stored in the database is the public key returned by the authenticator when we are performing the registration ceremony (that's what the W3C specification calls it). Being a public key it does not need protecting from reading. Even if an unauthorised user was able to read this information they would not be able to impersonate the authenticator e.g. by cloning it.
However, if a malicious user had write access just to the #__webauthn_credentials database table, without read access to the filesystem and without write access to any other table, they could conceivably insert their own authenticator therefore impersonating a targeted user on the system. This is a very theoretical attack since they would also need to know the user handle for the user they are attacking. Besides, having write access to just this table and not the entire database (in which case they could create a new Super User) is extremely unlikely. Still, we are encrypting the credentials to make it impossible for even this entirely theoretical attack to succeed.
I am fully aware that if a user has read access to the filesystem they have access to the encryption key and the database connection information, all of which is stored in configuration.php. However, in this case you are already hacked: the attacker can read configuration.php therefore they know how to connect to your database. In this case they can do whatever they please to your site, including deleting all existing Super Users and creating their own Super User account. Therefore there's no reason to try to address this situation; you'd be fully pwned. The only that could be a saving grace is regular, tested, off-site backups.
No, it's intentional and by design.
When I contributed Two Factor Authentication (TFA) in Joomla! 3.2 you were only able to log into your site using a username and password. Passwords can be stolen or guessed. Therefore TFA was the only way to provide a modicum of security on high risk and high value targets. That was back in 2013, seven years ago.
WebAuthn is an entirely different beast. It uses strong cryptography and secure hardware to make it practically impossible to subvert the authentication cryptographic keys (so far nobody has a proven ability to compromise hardware security keys and trusted hardware modules as explained above). It's also unphishable, i.e. you cannot be fooled into using it on an impersonating site since the WebAuthn credential is tied to the exact domain name it was issued for (yeah, if you use multiple domains for your site or transfer your site to another domain you'll need to re-register all your WebAuthn authenticators – you got that right!). As a result, authentication with WebAuthn is incredibly secure and supersedes the reasons that necessitated TFA. Therefore, if you successfully authenticate using WebAuthn the TFA secret key needs not be –and is therefore not– checked at all.
You should use both WebAuthn and TFA on your account for maximum security. WebAuthn is an additional way of logging into Joomla, not the only one. Password authentication is still allowed and cannot be disabled either globally or on a per-account basis (at least, not yet). Therefore someone can still guess or steal your password just like they could do back in 2013 when I contributed TFA to Joomla. TFA will protect your password authentication. WebAuthn allows you to NOT use a password for everyday use, making it far less likely that your password will be stolen.
TFA alone is good enough in most cases but suffers from two issues.
First, it has a rather awkward user experience. You need to provide your ever-changing secret key with your username and password. Most people use TOTP (the six digit PIN that changes every 30 seconds) which slows down logging in and tends to frustrate users. Using a YubiKey is much faster but also expensive and more complicated to provision. In YubiKey-OTP mode it also has an expected life of about 2 years of everyday use (it runs out of the write-once memory it uses to keep track of the signatures it has issued).
Second, if you are using TOTP you are susceptible to security issues such as keyloggers, phishing and the possibility that the secret key used for generating the TOTP is stolen. Moreover, with one million possibilities and thirty seconds to try them it is conceivable that an attacker can get lucky since Joomla doesn't lock your account or otherwise employ rate limiting for failed login attempts. While these protections could be implemented, the implementation itself could be abused to create a denial of service situation which locks a legitimate user out of their site while the attacker is busy infiltrating it. It's a case of the rememdy being worse than the disease.
WebAuthn greatly improves the user experience. In the short year between my first implementation of it (March 2019) to now (February 2020) the browsers embraced WebAuthn and offer a compelling user experience, guiding the users into using authenticators successfully. I find logging in with WebAuthn to be more convenient than even using my trusted password manager's auto-fill feature. The interaction is still slightly awkward on mobile but this is changing rapidly as well.
Where WebAuthn is truly killing it is at the security front. By virtue of using secure hardware and strong validation of the site's domain name it is practically immune to keyloggers, phishing and key subversion. It even has built-in protection against key cloning. Yes, you can still lose your hardware or have it stolen but the same goes with your house keys. At least you can cancel your WebAuthn authenticator much more easily than changing your locks (ever lost a car key or, worse, a car key card?).
Status | New | ⇒ | Pending |
Category | ⇒ | Repository SQL Administration com_admin Postgresql Language & Strings Modules NPM Change JavaScript Front End com_users External Library Composer Change Installation Layout Libraries Plugins |
Labels |
Added:
?
?
NPM Resource Changed
?
|
@zero-24 Thank you! You can make PRs against my repo.
The biggest concern right now is that the violations reported by Hound are NOT reported by ESlint (e.g. npm run js:lint
) on the repo. If I "fix" what Hound reports ESlint complains and vice versa. It'd be comical if it wasn't an automatic merge blocker.
Either ESlint is configured wrong on the repo or Hound is configured wrong. I can't tell which is the case. Any help most welcome.
@nikosdion Thanks so much for this! I look forward to testing soon.
The only thing that stood out was the use of PHP short tags.
If you are applying this PR on an existing Joomla 4 development site please remember to not only do the steps above but also go to System, Fix Database. Then check that the System - Web Authentication plugin is enabled.
This is not enough because the database fixer only runs DDl (data definition language), i.e. the "create table" statement, but it doesn't run DML (data manipulation language), i.e. the "insert into #__extensions" statements are not run. So the plugin will not be installed.
It requires either to have an own installation sql script for the plugin, like we have them for other extensions, so the plugin can be installed with the "Discover" functionality, or it needs to run the "insert" statements from the schema update sql "manually" e.g. in PhpMyAdmin.
@C-Lodder I understand your confusion but they are not, in fact, short PHP tags. Since PHP 5.4 the short echo tags are always enabled, regardless of PHP's short tags toggle. Rasmus Lerdorf said that PHP developers should actually use them to make the code easier to read. Since we're targeting at least 7.2 I think it's safe to say that we can use them.
I'll look into the JS linter this evening after work.
@richard67 You are right. I suppose that Discover would, however, let you install the missing plugin. Right?
I suppose that Discover would, however, let you install the missing plugin. Right?
@nikosdion Not sure, it needs to try. Am not at my desk here so can't try. But this is relevant only for testing, and people could run also the sql manually for testing. When updating, the installer runs the complete update sql, so the inserts would take place.
@richard67 I updated the PR text to include the note about Discover as well.
@rdeutz Can it be that there is missing some PHP extension in our ci test docker images for this PR? At least the "composer" step of the drone log reads like this, see https://ci.joomla.org/joomla/joomla-cms/29618/1/8 .
@rdeutz @richard67 It looks like Drone is failing because the WebAuthn library requires spomky-labs/cbor-php which requires the gmp PHP extension. Since our Composer task uses the joomlaprojects/docker-images:php7.3-composer image to which I do not have edit / build privileges I cannot fix it. Any chance of updating this Docker image?
@nikosdion I don't have these privileges either, and if I had them I would still not have the necessary knowledge ... let's hope for Robert to help.
@richard67 I have the knowledge, but I don't have the power to fix what needs fixing. Dang.
@rdeutz I created an issue with a proposed patch to address the Drone issue, see joomla-projects/docker-images#15
Title |
|
Thank you @nikosdion for your work! Really appreciate, that you built this functionallity.
@nikosdion I fixed the docker image issue for drone and appveyor. For appveyor you have to include my PR #28099 or wait till it is merged and update to dev
I cloned your branch
cloned your branch
sql updated
composer install
npm i
del autoload
Fatal error: Class Joomla\CMS\Application\SiteApplication contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Joomla\CMS\Application\CMSApplicationInterface::getSession) in C:\htdocs\joomla-cms\libraries\src\Application\SiteApplication.php on line 34
What did I miss
What did I miss
Looks like a full composer update
was done, which as pointed out in #27996 and #27997 is a bit problematic right now.
The quickest solution I can think of here is to reset composer.lock
so it matches the current 4.0 branch state, composer install
to get the local environment back to the right state, then run composer update web-auth/webauthn-lib ramsey/uuid
which should only update those two packages without touching the rest of the dependency tree.
that would explain it
The brute force solution to clean up a 4.0-dev branch (requires a remote named "upstream" pointing to the cms repo):
git checkout 4.0-dev
git remote update
git clean -d -x -f
git reset --hard upstream/4.0-dev
git push origin +4.0-dev
This will make your 4.0-dev branch (locally and in your repo) be exactly same as 4.0-dev branch of the CMS repo.
After that, composer install
and npm ci
and all should be fine.
@nikosdion I've had a look into the eslint stuff. I've managed to get Hound and local linting to match, however the rules seem to have differed. Hound uses eslint 4.19.1
by default, so I've bumped all eslint deps to their respective latest version
Now, I'm only getting two of the following
error Expected parentheses around arrow function argument arrow-parens
I've tried moving from Hound to Github Actions and still getting the same thing.
@nikosdion The hound is happy now, but we have PHP a few small code style errors reported by drone. Shall I fix them for you so you can focus on the real stuff?
@wilsonge @mbabker I would say that the current situation means that Joomla is using Composer the wrong way. If a library should be bound to a specific version it should be in composer.json, not some arcane, undocumented knowledge. Otherwise why the fsck do we use Composer instead of copying files around like cavemen? :)
IMHO it would be far better to tag a 2.0.0.a1 release in the Joomla Framework repos from the commits that Joomla CMS' 4.0-dev branch is using and update composer.json.
The current situation is unworkable since we can't update dev dependencies which means that anyone using PHP 7.4, i.e. me, can't safely run the dev tools such as PHP-CS which is a damn shame. I'll have to do weird things to get phpStorm showing me code-style issues again. Not how I envisioned spending my night at 11 pm.
@richard67 The solution to hard reset to 4.0-dev is not viable because it would undo the PR as far as I can tell. Instead, I switched composer.lock back to 4.0-dev and used composer require web-auth/webauthn-lib "2.1.*"
to install my dependencies. Apparently we no longer need to require ramsey/uuid because the library finally does that automatically.
Regarding PHP-CS issues, sure, I'll fix them as soon as I can see them in phpStorm :D
@C-Lodder I understood the part about the versions being different. The points made in your issue is above my pay grade. I can work miracles on PHP but when it comes to JS and its automation I'm still a little more than a caveman.
@brianteeman Everything should be in working order now. Pull the changes, delete the libraries/vendor folder, do composer install and npm install, delete libraries/autoload_psr4.php and you should be ready. Hopefully. At least that's how it worked for me.
@richard67 I gave in and selectively update the Joomla code style standard in the repo as there was no other way to stop it breaking PHP-CS with PHP 7.4. I also used a globally installed, up to date copy of PHP-CS which is compatible with PHP 7.4. Good news is that worked. I was able to update the three small code style issues: a missing line, a missing docblock and PHP-CS getting a stroke when there's an inline array in a function call.
@HLeithner @wilsonge @C-Lodder I will ignore the Hound's recommendations. ESlint on the repo says it's all good, I'm gonna go with that since it's an up-to-date version, whereas Hound's is not.
Let the functional, manual testing begin.
@nikosdion Well I would not care about PHPCS but it somes so early in the drone test sequence and when it fails, all the other more interesting tests are not run, that's why I asked for fixing. So or so thanks a lot for your work here, and I hope to find time on weekend for testing ... have to get some key first ;-)
I would say that the current situation means that Joomla is using Composer the wrong way. If a library should be bound to a specific version it should be in composer.json, not some arcane, undocumented knowledge. Otherwise why the fsck do we use Composer instead of copying files around like cavemen? :)
IMHO it would be far better to tag a 2.0.0.a1 release in the Joomla Framework repos from the commits that Joomla CMS' 4.0-dev branch is using and update composer.json.
I haven't touched things in a long time, but it's not so much that the CMS repo relies on some random commit from the various Framework repos, it's more that composer update
hasn't been regularly run on most packages and there are a couple of changes from the Application package (well, most specifically joomla-framework/application#88 and moving the $input
property from the root application class down to the web application class since the console application doesn't use that at all) that effectively block running a full update on all packages here until that change is dealt with in the context of the CMS. So it might make sense to pin those 4 packages to the specific commit they're at now so updates can be run in a more safe manner, but things are not totally FUBAR'd in the Composer stack right now (I hope).
nikosdion Well I would not care about PHPCS but it somes so early in the drone test sequence and when it fails, all the other more interesting tests are not run, that's why I asked for fixing. So or so thanks a lot for your work here, and I hope to find time on weekend for testing ... have to get some key first ;-)
@richard67 phpcs is already happy, it's hound complaining about js and scss and if I see it correctly @C-Lodder already is trying to solve this.
Updated hound Eslint version to match that in our package lock file. Nice catch there. If you merge in 4.0-dev should go green all being good
The package.json is kinda irrelevant for this. What counts is what's in the package-lock.json at the given time. That's what needs to be kept in sync with hound - we can't run hound against a loose version constraint. Currently it's https://github.com/joomla/joomla-cms/blob/4.0-dev/package-lock.json#L4970 which matches what i wrote in the hound file. This is also why we tell people to use npm ci
;)
This is also why we tell people to use npm ci ;)
Where? The readme just says "npm install" which is "npm i" not "npm ci"
the docs https://docs.joomla.org/J4.x:Setting_Up_Your_Local_Environment#Steps_to_Setup_the_Local_Environment - missed the readme didn't match - will fix that now
the readme is the only place most people would see
I have tested this item
I tested all given tests on an updated j4 installation in windows 10 with Firefox and vivaldi authendicating with a Yubico YubiKey 4.
While testing on a non-https site and clicking on Add new Authenticator
Googling on the message took me to pypa/warehouse#6343
Reading the comments and subsequent PR to address this it would appear to be the same issue
You said:
While testing on a non-https site and clicking on Add new Authenticator
But I have explicitly stated:
Testing Instructions
i. Requirements
Your site must be using HTTPS with a certificate your browser recognizes as valid. For simplicity's sake, please use a live server with a valid SSL certificate, e.g. one issued by Let's Encrypt.
Even if I pass an HTTPS URL for the icon it will still fail to work because browsers disable WebAuthn for insecure sites. In this context "insecure" means any site which is not being accessed over HTTPS or whose TLS certificate is not trusted by the browser.
I'll have to run a few checks. When Joomla reports the protocol as HTTP I should be hiding the WebAuthn login buttons and the tab from the user profile editor. If I am not I have either forgotten to implement what I documented or I screwed up. I'll get back to you on that.
Yes I realised you said https but there was no check for https and the software loaded and then i got the unfriendly message. This was a stupid user test
@nikosdion could you merge latest 4.0 branch, after this we should have successful tests.
I think the plugin should only run if https site is loaded and add a warning like on smart search and the content plugin.
Or we only allow to activate this plugin if the site is "https only" in our options (basically the same as the browser does)
@brianteeman I most definitely don't disagree with you. There were two parts in my previous reply.
First part: No, the issue you experienced is not the same as the PyPI issue you referenced. Their problem was that they were creating HTTP avatar URLs on an HTTPS site when setting up WebAuthn. The issue you experienced is that you were allowed to access the WebAuthn set up page on HTTP at all.
Second part: You shouldn't be allowed to access that tab because I know it can't possibly work. I also know that my intention when writing the plugin was to automatically prevent its buttons and tab from showing at all if the site is not HTTPS (see note below). So I told you I needed to run further checks. The idea is that either I forgot to do something or your server environment is reporting the wrong URL to Joomla.
Now that I've run the further checks I can tell you that I forgot to disable the tab on HTTP sites. I only prevent the login buttons from showing. I fixed that. Thank you for the bug report!
Note: You might wonder, why only hide the buttons and tabs on HTTP sites when I said that they won't work when the browser doesn't trust your TLS certificate? The answer is that I cannot tell from the server side if your browser trusts your TLS certificate or not. A naive soul might think that we can get the server TLS certificate and check its validity server-side. That would be slow, precarious (loopback connections are disallowed on many shared hosts) and ultimately wrong. "Wrong? Why?" I hear some of you asking. Well, we don't have the browser's CA trust database on server-side, we only have cacert.pem which includes the default CA trust db of Mozilla. In enterprise deployments it's not unheard of having an organization-wide root CA which signs certificates used by internal sites. These are client-side and most assuredly not in our cacert.pem. So, lest we ask Joomla enterprise users to hack core as standard practice, we can't plausibly check the validity of TLS certificates server-side. The client-side failure mode in this case is far less confusing than what Brian experienced. The user will be told that their browser doesn't support WebAuthn or that their site is not using a valid, signed TLS certificate. So as far as I'm concerned, only checking for availability of HTTPS is a pragmatic approach. Sorry for the egregiously long paragraph; I really needed to document a development decision that would have otherwise been lost in Joomla arcana like so many other things.
thanks
PS why had I never heard of krypton before - it is awesome!!!!
@HLeithner I am going to merge 4.0-dev, don't worry. I was working on that.
Regarding the plugin, it is now changed to not load (most of) its features when the site is not running under HTTPS. The plugin still needs to load because onUserAfterDelete
still needs to delete the now unnecessary credentials of a user we just removed.
Regarding showing a warning, I think we shouldn't do that. It is not very good UX since the fix is not "click here to fix it" but "do something outside of Joomla and then go back and do something to Joomla and then come back here". This sounds more like a side quest given to you by an elf in an RPG game than a pragmatic solution for people who don't already know what HTTPS is ;)
@brianteeman Krypton is really cool but keep in mind that I would only use it for medium trust sites. It's a software implementation of FIDO over Bluetooth. Between CPU and Bluetooth security issues discovered over the last two years I don't consider this kind of implementation very secure.
That said, considering the main target audience of Joomla, yes, it's secure enough for their use case. It's something you can plausibly install on your clients' mobile devices and teach them how to securely log into their sites without having to carry around yet another piece of expensive hardware they might lose. That's why I mentioned it in the PR ;)
I like side quests ;-) but yes maybe not ideal. Anyway we should at least mention it on the plugin config site.
Because now I have no chance to know why it's not showing.
Please remove prefix en-GB.
from language file names.
@HLeithner I merged 4.0-dev and updated the plugin description per your request.
@Quy I renamed the language files. You might want to check the XML files of all other core extensions; they still reference the old-style filenames which might be confusing for developers without prior Joomla experience.
@nikosdion @Quy there is an outstanding PR for that waiting to be merged
@nikosdion latest 4.0-dev should fix appveyor too
I have tested this item
Works great. I have tested it with the Google Titan Security Key and Google Chrome. Epic.
@HLeithner Could you test again?
I have just added the docs required label to be sure we don't miss to add the docs as mention in the intial post.
Labels |
Added:
?
|
I have tested this item
Great instructions! Did all 10 tests. Everything works as desired.
Small note: I would write the following URL in Test 8 /index.php?option=com_users&view=login
Status | Pending | ⇒ | Ready to Commit |
RTC
@HLeithner As far as I could see your requested changes have all been implemented.
@rdeutz Reminder to pimp the Appveyor tests for this PR before merging ;-)
@nikosdion finally if you merge 4.0-dev into this pr appveyor should be solved and we can merge this.
Labels |
Added:
?
|
Yup, Appveyor worked after merging 4.0-dev. Drone will take a little bit but I don't expect any problems there.
Finally thanks for your time creating this awesome feature. I'm pretty sure there will be some cleanups but basically it's working fine. Also a thank you on all testers and commentators.
Status | Ready to Commit | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2020-03-05 13:24:20 |
Closed_By | ⇒ | HLeithner |
Thank you for the merge!
Documentation: I found a very short, incomplete proto-document and expanded it on the basis of my own experience and the PR description above. It is here:
https://docs.joomla.org/WebAuthn_Passwordless_Login
It may not be good enough! A week ago I had no clue how to use WebAuthn or even what a hardware device looked like.
@ceford This is good and I can tell you how we can expand the authenticator information even more.
Any FIDO2 authenticator device will do e.g. https://www.amazon.com/s?k=FIDO2&crid=3VRB2JJME0KF3&sprefix=fid%2Caps%2C185&ref=nb_sb_noss_2
Many devices have built-in FIDO2-compliant authentication:
We must definitely note that this feature requires HTTPS. It's been a major caveat during early development and testing.
Maybe in the developer docs we should link back to this PR so anyone curious enough can see my more detailed and more technical notes? Speaking of which, I think it's a good idea to do that as a minimum for new features where there's a main PR tracking them with an updated description that includes documentation.
Some Android devices have a fingerprint scanner
Works on my pixel 5 - now with android 12 but worked with 10 at least before that
@brianteeman Thanks! I know 100% it works on Android 10. I am not sure if it works on Android 9. My old Nokia which only upgraded to 9 got a bloated battery and had to retire it. The battery got so bloated it broke the screen and cracked the back case. It was very close to getting ruptured and becoming an incendiary grenade
A phone with a fingerprint scan is high end so it's very unlikely to find one that has not been updated
I was hoping someone with an older Xperia phone. Sony's the only manufacturer I know which only pushes updates for the Android version which was current at release and the next version but not anything beyond that (yeah, barely 18 months of updates for flagship phones, made the mistake once and never again).
I have one of those in my collection but it's been updated
And another way to do it is to use caBLE https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/go6GoFW27Dw/m/9flCLR5pBQAJ?pli=1
Hello,
I had no idea of that outstanding WebAuthn Feature.
I will submit 2 Language overrides making things clearer...
One thing in question - on Windows 11 I cannot use the PIN Option (only Webcam or Fingerprint Scanner).
But on https://webauthn.io/ tests I can also use the Windows PIN. Is that an option, to enable also PIN for users that do not own a face recognition camera or fingerprint reader?
I have incorporated the comments from @nikosdion and @brianteeman into the documentation.
@kitepascal That's a good question. According to Microsoft, Windows Hello with a PIN should have been supported since 2018. On our end, we do tell the browser to let the user use either a roaming authenticator (USB key, Bluetooth key, ...) or a platform (built-in) authenticator which on Windows translates to Windows Hello. We don't have any further control I can see.
This weekend I'll be installing Windows 11 on my tertiary computer so I can test further.
So, I found out why Windows Hello doesn't offer PIN authentication with Joomla.
Apparently, Microsoft chose to only support RSASSA-PKCS1-v1_5 (RFC8017, article 8.1) public key signing and only with with SHA-256 as the hashing function for Windows Hello when using PIN authentication. Thisis not considered a very secure signing method, since it can be cracked if collisions against SHA-256 are found (right now SHA-1 is broken and we can't expect SHA-256 to hold up much longer).
For this reason I had not added this algorithm in the WebAuthn implementation for Joomla. Instead, I had only added Edwards-curve Digital Signature Algorithm (EdDSA; only if libsodium is supported on the server); Elliptic Curve Cryptography with NIST P-521, P-384 or P-256; RSASSA-PSS with SHA-512, SHA-384 and SHA-256; Shared secret w/ HKDF and SHA-512; and Shared secret w/ AES-MAC 256-bit key. The algorithms I had added are the only truly secure ones based on what we currently know.
Why Microsoft chose to only implement the weaker version of RSASSA signing, especially when they have suffered from it in the past (Stuxnet), is beyond me. It would have made sense if it was a limitation in Windows Hello, yet its biometric authentication does support the more secure signing algorithms. Huh.
Anyway, for the average user using Windows Hello with a PIN should still be secure enough for all practical purposes, at least until the day comes when collisions against SHA-256 become computationally efficient. So, yeah, we can add support for it.
The good news is that adding RSASSA-PKCS1-v1_5 support is as easy as adding three lines of code. I will make a PR later today after some further testing.
Nice. I also checked some secure (Joomla maintenance) Services with WebAuthn - PIN option offered there but not Android biometrics yet (yesterday). @PhilETaylor
That you get "Pixel 5" as an option on Windows 11 is an exciting thing. I try to link my Samsung S21 to my Desktop Windows auth today.
That could be another addition to the documentation.
The more options enabled the better. More easy - more secure - crispy documented straight in Backend and detailed explanations in the wiki.
I think ~1% WebAuthn users will raise to at least ~15%
So, I found out why Windows Hello doesn't offer PIN authentication with Joomla.
it also doesnt offer biometric and yet github does (weird)
@brianteeman Yeah, I noticed that the code that actually went into Joomla only supports ECDSA with NIST P-256. This won't work for biometric authentication on Windows 11 or TouchID/FaceID on Apple devices. Grumble.
I am working on the PR right now, transferring the (very few and backwards compatible) changes I had already done in LoginGuard to support these features.
Please try #37205
I am very interested in the environments I do not have:
This looks awesome thanks for your work on this @nikosdion I really love to see this as a feature for 4.0?
I have just added it to my list, to test this in full in the coming days.
Just one organisational question how do you want us to contribute and fix things we found? Maybe as PR against this branch or do you like to merge after the functional tests and adjust that kind of things after merge with individual PRs? cc @HLeithner @wilsonge ?