Jump to content
Adam

FIDO/U2F Two Factor Authentication

Recommended Posts

I am back again with another crazy module that might help someone.

This time I am using the native Tfa class to add FIDO/U2F support. this includes Yubikeys 🙂

Sadly I cant seem to find a way to do multiple keys at once. and it seems you can only have one Tfa method at a time so not ideal but it was a fun challenge to code and maybe someone will a use for it

Github: https://github.com/adamxp12/Processwire-TfaU2F
ProcessWire Modules: https://modules.processwire.com/modules/tfa-u2-f/

The code is not the neatest and has limited comments but if you understand the Tfa class it should be quite easy to break apart.

And here is a demo of signing in using the Yubikey as the 2nd factor

2019-08-28_12-06-18.gif.fbe020ab851bdf8bc0d0c623e61fd211.gif

 

  • Like 9
  • Thanks 1

Share this post


Link to post
Share on other sites

I did not see an option to submit to the Tfa module category @ryan Not sure if you want to manually add it into there?

  • Like 1

Share this post


Link to post
Share on other sites

Yes! Fantastic!

This module is currently top of my list of modules to develop for Processwire - thanks so much for doing it for us! Will test with Yubikeys as soon as possible, and shorten my to-do list.

  • Like 1

Share this post


Link to post
Share on other sites

Oh yeah excellent ! 💪

 

PS: The Github link lead to a 404 page due to a typo in the url.

  • Like 1

Share this post


Link to post
Share on other sites

Hmm,

Trying to install this via the modules installation page and getting: "Session: Error reported by web service: That module is not currently tracked by the modules directory" despite the module being present in the directory. Odd.

Trying to install via the Install from zip method leads to "Compile Error: require(): Failed opening required 'php-u2flib-server/src/u2flib_server/U2F.php' (include_path='.:/usr/share/php') (line 17 of /var/www/pwgeeks.local/public_html/site/modules/TfaU2F/TfaU2F.module)" on all pages of my test site.

Share this post


Link to post
Share on other sites
24 minutes ago, netcarver said:

Trying to install this via the modules installation page and getting: "Session: Error reported by web service: That module is not currently tracked by the modules directory" despite the module being present in the directory. Odd.

This is most likely because the module is still waiting for approval 🙂

Quote

This module is currently pending approval and will appear in the directory soon.

 

  • Like 2

Share this post


Link to post
Share on other sites
2 minutes ago, teppo said:

This module is currently pending approval and will appear in the directory soon.

Ok, I missed that. Thank's Teppo.

Share this post


Link to post
Share on other sites
36 minutes ago, netcarver said:

Trying to install via the Install from zip method leads to "Compile Error: require(): Failed opening required 'php-u2flib-server/src/u2flib_server/U2F.php' (include_path='.:/usr/share/php') (line 17 of /var/www/pwgeeks.local/public_html/site/modules/TfaU2F/TfaU2F.module)" on all pages of my test site.

Looks like this library is added as a Git submodule. The GitHub zip download won't include submodules, so it's a bit of a nuisance. You'll likely need to add them manually, or do a git clone + git submodule init + git submodule update (or something along those lines).

Might make more sense to bundle the code directly into the repository, though that's obviously up to @Adam. Either that, or just include instructions on getting those files via Git – though it's probably worth noting that with the submodule approach the module won't be directly installable via ProcessWire Admin (which may or may not be a problem) 🙂

  • Like 1

Share this post


Link to post
Share on other sites
31 minutes ago, teppo said:

Looks like this library is added as a Git submodule. The GitHub zip download won't include submodules, so it's a bit of a nuisance. You'll likely need to add them manually, or do a git clone + git submodule init + git submodule update (or something along those lines).

Might make more sense to bundle the code directly into the repository, though that's obviously up to @Adam. Either that, or just include instructions on getting those files via Git – though it's probably worth noting that with the submodule approach the module won't be directly installable via ProcessWire Admin (which may or may not be a problem) 🙂

That is not what I intended. Will fix that ASAP. it should be installable via the ProcessWire admin area just with the class name (once approved)

@netcarverthe is a Zip file under the releases tab on GitHub that includes the dependencies that was not included due to my noobness with git (did not know much about submodules to be honest, they just appeared like it as I git cloned the dependencies)

  • Like 2

Share this post


Link to post
Share on other sites

@Adam

Thanks for the speedy update - the zip under the releases tab does now work for me and I can install the module. I'm now hitting a problem trying to activate it on the user's page. I choose U2F as the TFA method and submit the page and am then asked to click the on-screen "Add Security Key" button to enable U2F - but nothing happens when this is clicked but an error does show up in the js console in Chrome... 

"u2f-api-polyfill.js:545 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('chrome-extension://kmendfapggjehodndflmmgagdbamhnfd') does not match the recipient window's origin ('null')."

Share this post


Link to post
Share on other sites
25 minutes ago, netcarver said:

@Adam

Thanks for the speedy update - the zip under the releases tab does now work for me and I can install the module. I'm now hitting a problem trying to activate it on the user's page. I choose U2F as the TFA method and submit the page and am then asked to click the on-screen "Add Security Key" button to enable U2F - but nothing happens when this is clicked but an error does show up in the js console in Chrome... 

"u2f-api-polyfill.js:545 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('chrome-extension://kmendfapggjehodndflmmgagdbamhnfd') does not match the recipient window's origin ('null')."

You have to use either localhost or a FQDN. you also need to use SSL. these are just restrictions on the FIDO/U2F protocols that I should of mentioned on the project page. I should also probably put some better error checking in on the admin panel side. the login page side does have error messages but their vague.

This exact error occurs when your not using SSL. the U2F-API JavaScript library does notseem to have any error handling for that scenario. I should add on the ProcessWire side so your not in the blind with the cryptic error message

This is really just the 1.0.0 version the first version that works essentially. Just need to iron out any bugs and improve the UX

Share this post


Link to post
Share on other sites

@Adam

Ok, I am on localhost, but not using SSL. Will try (another day now) on a test site with an SSL certificate installed.

Thanks for your help so far!

Share this post


Link to post
Share on other sites

@netcarverNo worries. I will probably look into making a 2nd module which uses the Yubikey specific OTP methods to get around the localhost/FDQN and SSL requirements (though I cant see why anyone would desire a site that has no domain and no SSL) but also means you can create a backup security key. this U2F module can only address a single security key. I am not sure how I would add support for multiple as each key needs 4x fields and not to mention a lot of challenges back and forth. But a single security key is better than TOTP or other forms of TFA

Share this post


Link to post
Share on other sites

@Adam

Whilst it may be more difficult to allow multiple Yubikey's on an account, I'd definitely support a move to a Yubikey-specific module that permitted multiple key registrations. I would not want to be without a backup key registered on any accounts - potential lock-out is too risky (for me) should a lone key be lost/stolen or fail, that I still favour TOTP (on a client like Authy) over a single Yubikey on an account.

Share this post


Link to post
Share on other sites
Just now, netcarver said:

@Adam

Whilst it may be more difficult to allow multiple Yubikey's on an account, I'd definitely support a move to a Yubikey-specific module. I would not want to be without a backup key registered on any accounts - potential lock-out is too risky should a lone key be lost/stolen or fail, that I still favour TOTP (on a client like Authy) over a single Yubikey on an account.

I will look at maybe adding support for 2x keys into this module? I might get away with 8x fields being used 😄
The only way I can imagine it working though is if you enrolled all your keys one after the other on the initial setup. If you can reuse the same challenge for registration then its worth experimenting.

Ideally I would have access to a database table and can add infinite amount of keys without fear of having to essentially just cram all this data into text fields. and it would of made a lot of my debugging work easier as a lot of it was trying to wedge it around the ProcessWire hooks/Tfa module. I felt like using the $sql API was a bit too jank though even for my subpar coding skills (not to mention much less secure as I am sure ProcessWire does a ton of validation behind the scenes)

as for a Yubikey specific module that shouldn't be too hard. in fact probably easier. but I have not got a compatible YubiKey. I only have a cheap FIDO key and a Yubikey Security key (FIDO/FIDO2 not OTP/OATH/PIV/etc) I have bought a Yubikey 4 cheaply used just to experiment with the OTP idea (not going to spend £50 on a USB dongle for the latest 5th gen) but that has not arrived yet

Share this post


Link to post
Share on other sites

Would using a single json-fieldtype for packing config values for multiple keys help? There are a couple I know of, but bitpoet's is probably the most up-to-date.

  • Like 2

Share this post


Link to post
Share on other sites
Just now, netcarver said:

Would using a single json-fieldtype for packing config values for multiple keys help? There are a couple I know of, but bitpoet's is probably the most up-to-date.

Yes that would be ideal. I could also just save JSON into a string field to lower the dependencies on other modules. I had not thought about doing this actually

Food for thought... I will experiment tomorrow I think. I wanted to get a proof of concept working to start with as I had coded a ton of it then realised the settings get locked out once you enable Tfa and then found out that only the Tfa_code field is sent to the validate function. had to get creative with some session variables to get it working but now it works somewhat I feel like I can improve/expand

  • Like 2

Share this post


Link to post
Share on other sites

Really like what I‘m reading here. 😀❤️

  • Like 1

Share this post


Link to post
Share on other sites

Right been trying to get multiple keys working. I have figured out how to do I think? but I am hitting the dumb 2048 length limit on the field. if I add the maxlength attribute it still gets truncated to 2048 characters (possible bug?) So the only way I can do this is a very janky method of multiples fields and having to recreate arrays and stuff.

What I need is to save one huge JSON array into a field as a string but I have found no info on increasing the max size on any field via the API. well I can but it seems to be truncated somewhere else 😞 but looking inside tfa.php I cant see where its being cut down in size. Real downer to be honest. I am going to say that multiple keys is as a result not possible unless someone can enlighten me on how to correctly expand the maxlength on a field without the sanitizer just going hard-headed in and destroying everything.

It seems that InputFieldHidden has no sanitizer or maxlength but it still gets truncated so its something deeper. I dont know enough about how ProcessWire handles forms on the admin side to know where to look for where this stupid 2048 limitation is being applied

Share this post


Link to post
Share on other sites

I have just pushed a commit that cleans up the code a bit. the registered keys are now saved in one field. Again in theory this can support multiple keys... but the bulk of the code is not there as I failed to find a work around to the 2048 truncation. Each key uses like 1040 characters. I could put each key in its own field but that means I have to reconstruct the array and have more complicated JS instead of just concatenating.

I am not a huge Processwire module developer so someone with more experience feel free to chime in. I tried adding ->attr('maxlength', 4096) and ->maxlength(4096) and it does increase the maxlength of the field on the HTML side but the processing side is still truncating to 2048 characters even though I cant see where its doing that. the only field that has a hardcoded 2048 limit is the Text field. both hidden/textarea still truncate though even though I cant find the code anywhere that does this. I think it might be a POST request limit?? but surely that would fire a HTTP error instead of getting truncated

I feel dumb XD under getUserSettingsInputFields I have to set the maxlength under the if POST section otherwise it will truncate it there. Such a weird design. tripped me up before. but now I can continue trying to do multiple keys 😄

  • Like 1

Share this post


Link to post
Share on other sites

@Adam

Not sure if this will help, but have you tried setting the maximum length for text fields to "0" in the InputfieldJsonNativeFields config page?

Share this post


Link to post
Share on other sites

@netcarver Edited my last reply. I figured it out. Was me being played by the strange design of forms on ProcessWire. It was being converted into a text field for the POST section and the default maxlength for a text field is 2048. doh

Now working on multiple key support. fingers crossed with this

  • Like 2

Share this post


Link to post
Share on other sites

Right! Multiple Key support is now included. you can put about 19 in before you run out of space (20480 characters, each key uses about 1040) if someone has 19 keys I will be very surprised.

I have bumped the version to 1.0.1 as a result. I ain't a big versioning guy but this is a minor change from the users perspective. you can just click the add button more than once now. Just be sure to only click the save button once you have added all yours keys. I have tried it with the 3x keys I have and it works fine. More than 3? not sure cant test that yet. if you click save before you add all your keys then you will only get the ones you added and have to disable/re-enable Tfa to add them all again. This is a limitation of the Tfa class sadly.

  • Like 6

Share this post


Link to post
Share on other sites

@Adam

Success! Version 1.0.1 works for me. Registered 3 keys (a Yubico Security Key, a NEO and a Yubikey 4) and can log in with any of them.

Thank you for the module!

Share this post


Link to post
Share on other sites

@netcarver Glad to here it works for you 🙂 it is such a hacky module. I don't think the Tfa class was coded with security keys in mind 😄 but so far so good. let me know if you discover any bugs/issues using it. I know of at least one bug that you shouldn't come across too often (if you login to an account with Tfa but don't use the key and then try to login with a 2nd account it will fail as it will still have a different challenge set for the session. it self-fixes when you try a 2nd time, I cant think of an easy solution to this problem though as it was done that way on purpose to get around the buildAuthForm function being called twice and resulting in a bad challenge on every attempt)

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...