KeePassDX icon indicating copy to clipboard operation
KeePassDX copied to clipboard

Autofill OTP forms

Open J-Jamet opened this issue 4 years ago • 60 comments

The autofill of the OTP fields would be perfect but requires a lot of work in the realization of the parser because each form is different.

You can leave a comment in order to define the forms to study in priority.

J-Jamet avatar May 11 '20 20:05 J-Jamet

Continuation of the closed thread discussion>>>as mentioned by you in the closed thread "The notification is displayed when you select an entry in the database. This is the normal workflow for copying data. Notifications cannot be linked directly to the autofill." I understand that auto filling of TOTP is not yet implemented in Keepass DX, but after selecting the entry in the database, i am not getting any kind of notification. Really confusing....may be i am doing something wrong! I will have to reinstall and start from scratch( although i did it many times). Interestingly keepass2android is also showing similar behaviour( getting notifications only when opening links from within the app). Anyways, Thanks.

matesurano avatar Jun 04 '20 14:06 matesurano

I just retested the OTP token notifications, and it works well. Maybe the OTP of your entry is misconfigured otherwise opens a new bug if you have a problem at this level.

J-Jamet avatar Jun 04 '20 14:06 J-Jamet

I just retested the OTP token notifications, and it works well. Maybe the OTP of your entry is misconfigured otherwise opens a new bug if you have a problem at this level.

Are you opening links from browser or from inside Keepass DX? In case its browser and TOTP notifications are working for you then it must be something wrong on my side.Also, OTP is not misconfigured as its working with Dashlane,Enpass etc. Will test again from fresh. Just FYI, i am on android 9.

matesurano avatar Jun 04 '20 16:06 matesurano

Correct me if I am wrong, but I think it will be hard to implement autofill OTP forms (i am not at all a programer ,just a guess). Instead autocopy of OTP(saved along with the credentials)should be enough for this. As we can easily paste it in the respective fields. Also, i haven't come across any android PWM which autofills the OTP(again correct me if i am wrong).

matesurano avatar Jun 19 '20 07:06 matesurano

This is an important remark that you have just made. Indeed, at the moment I do not know if it is difficult to implement because I have not studied the OTP forms but you are surely right. Now I understand what you meant by creating a notification for OTP. I thought you were talking about the functionality already implemented, but what I didn't understand is that you wanted to use this method as a workaround to non-recognition of OTP forms. Which may be a good idea, but I prefer to do things in order, there may be other methods that have not yet been explored that may be more effective. I just don't have enough visibility at the moment.

J-Jamet avatar Jun 20 '20 16:06 J-Jamet

I just checked several things and did many tests:

  • There are no easy ways to detect autofill fields, they seem different every time. I can detect it when there is the otp metadata in the name but that's it. It will be a big job to check each form.
  • The alternative solution of launching a notification cannot work every time because it requires launching a service but there is no listener when you click on an element of the autofill. So I can only start the notification if there is only one possible value before filling the field with addDataset.

So for the moment I don't have a solution that satisfies me fully to fill in the OTP. If you absolutely want an autofill for this data, we need to study the source code of each OTP field with its metadata and do it on a case-by-case basis.

J-Jamet avatar Jul 14 '20 13:07 J-Jamet

+1 to what @matesurano said; Bitwarden on Android does the same thing (after autofilling, the OTP is automatically copied into the clipboard). Should not be too much of a security concern, since the OTP is meant to be temporary and non-reversible, but maybe for the more security-conscious an option can be included to disable this.

jeslinmx avatar Sep 29 '20 09:09 jeslinmx

+1 to what @matesurano said; Bitwarden on Android does the same thing (after autofilling, the OTP is automatically copied into the clipboard). Should not be too much of a security concern, since the OTP is meant to be temporary and non-reversible, but maybe for the more security-conscious an option can be included to disable this.

it's probably the best option for now. especially since this is better than nothing.

mirsella avatar Dec 05 '20 15:12 mirsella

Guys, if another app is using a method doesn't mean it's easily applicable here. It's like you completely ignore what I'm saying, putting +1 does not solve technical constraints:

The alternative solution of launching a notification cannot work every time because it requires launching a service but there is no listener when you click on an element of the autofill. So I can only start the notification if there is only one possible value before filling the field with addDataset.

I can apply the notification solution only if there is only one entry offered by the autofill. If there is more than one, the program cannot know which notification and element to copy. What are your ideas on this problem?

J-Jamet avatar Dec 15 '20 11:12 J-Jamet

I just saw that the method https://developer.android.com/reference/android/widget/RemoteViews#setOnClickPendingIntent(int,%20android.app.PendingIntent) exists. I think I can use it to identify the entry and directly copy the TOTP by fetching the response from the service. But I have to test to see if there are any issues with it.

J-Jamet avatar Dec 15 '20 11:12 J-Jamet

how I'm seeing it personally, is just when you select an entry from the keepassdx pop up, if there is a OTP associated with this entry it just create notification to copy the OTP.

another option would be to just copy the OTP to clipboard when auto filling a entry on a site. still manual paste in the input box.

both of these method shouldn't be too hard to implement no ? when auto filling a entry and if the option is enable, copy the OTP to clipboard or create a notification which copy it.

maybe i didn't understood some things ?

mirsella avatar Dec 15 '20 11:12 mirsella

both of these method shouldn't be too hard to implement no ? when auto filling a entry and if the option is enable, copy the OTP to clipboard or create a notification which copy it.

These are assumptions that users make without having studied the subject. It's not at all as easy as you might think. I'm just sending RemoteViews in the device's autofill service response. But since it's not KeePassDX's role to display this popup views and copy the text to the fields, I don't have a direct listener to pick up the click event either. So the only solution I see to manage a clicked element is to go through a broadcast system with a recovery of the view id by service (the method indicated above). But I don't know if it's really doable.

J-Jamet avatar Dec 15 '20 12:12 J-Jamet

thanks for the explanation, didn't understood you couldn't add a hook or something when the user selected a entry from the pop up. so yeah as you said you can just give all the OTP for the entry requested by the device autofill service.

mirsella avatar Dec 15 '20 12:12 mirsella

I may not have been very specific either, I am aware that the constraint is not understandable from the start. I just tested with the method described above and it seems to partially work. No need to use a broadcast, calling it from a service with the PendingIntent seems OK. But now it doesn't fill autofill anymore, so it seems to override the basic fill method. I keep you informed if I manage to have both behavior at the same time (If it's possible).

J-Jamet avatar Dec 15 '20 12:12 J-Jamet

Despite my attempts, I cannot manage to have both behaviors simultaneously if there are several entries offered by the autofill. The setOnClickPendingIntent() method breaks the autofill if used in another way.

Finally, if the OTP and the password are in 2 different databases, you just have to use another way to fill in the OTP token when you are on the second database:

  • with the magikeyboard
  • or with the clipboard notification

So from a functional point of view, it's not a big deal. I remind you that there is no interest in having a TOTP in the same database as your password for the same entry, this second factor is useless in this case.

I haven't looked at how bitwarden works on this point, but there must be two different connections to access OTPs or additional encryption for this item. As it is necessary to make an additional database with KeePass, the problem normally no longer arises.

I can also improve the manual copy of the OTP token to make the second database workflow easier to use. Tell me if you have any ideas on this.

J-Jamet avatar Dec 15 '20 16:12 J-Jamet

Otherwise I return to the primary goal of detecting TOTP fields. HTML attribute autocomplete has the one-time-code value, if it is used more and more, it will be more and more recognized. And we will add non-standardized formats on a case-by-case basis.

J-Jamet avatar Dec 15 '20 19:12 J-Jamet

You can leave a comment in order to define the forms to study in priority.

I wish I could fill in the paypal totp. I think you need the otpCode value here? Sorry I'm not a programmer just want to help.

<input type="tel" name="otpCode" value="" class="hasHelp hasError" placeholder="Beveiligingscode" autocomplete="off" data-nemo="twofactorOTPInput" maxlength="6" id="otpCode" aria-describedby="otpCode">

And here some other codes from other websites.

<input class="ahoy-input ahoy-input-large ahoy-margin-top-2" id="mfa_token_input" autocomplete="off" type="text" placeholder="MFA token" onkeypress="return submitenter(this,event)" name="mfa_token">

<input _ngcontent-c1="" class="form-control hide-placeholder-on-desktop-view ng-pristine ng-invalid ng-touched" formcontrolname="twoFactorCodeInput" id="twoFactorCode" type="text" placeholder="Verificatiecode">

microsoftonline.com <input id="idTxtBx_SAOTCC_OTC" name="otc" class="form-control" type="tel" autocomplete="off" aria-required="true" data-bind=" attr: { 'maxlength': otcLength, 'aria-labelledby': 'idTxtBx_SAOTCC_OTC idDiv_SAOTCC_Title idDiv_SAOTCC_Description', 'aria-describedby':'idSpan_SAOTCC_Error_OTC' }, css: { 'has-error': error }, textInput: otcInputTextbox.value, ariaLabel: str['CT_SAOTCC_STR_OTC_TBHint'], hasFocusEx: otcInputTextbox.focused, placeholder: $placeholderText" maxlength="6" aria-labelledby="idTxtBx_SAOTCC_OTC idDiv_SAOTCC_Title idDiv_SAOTCC_Description" aria-describedby="idSpan_SAOTCC_Error_OTC" aria-label="Code" placeholder="Code">

Looks like everyone is using an other value. Is it the name= value you need? I can make a list if you want? I have like 24 websites with TOTP and this is for me a must have feature.

cmd1982 avatar Dec 31 '20 12:12 cmd1982

Thank you @cmd1982. This is the type of information needed to make the parser. Do not hesitate to put the site address associated with the form code. Here the name and type are important, but if we find other elements that allow us to specifically target the field as an otp type, that's good too. The goal is to generalize the rules as much as possible without making false positives.

J-Jamet avatar Jan 30 '21 09:01 J-Jamet

It would also be valid to copy the contents of the generated OTP key (in addition to the option to display an icon to populate the OTP key field). Enpass also does this on PC and mobile and is very helpful under certain conditions (sites that do not allow you to fill in automatically or sites that do not allow copying/pasting content).

gabeweb avatar Apr 15 '21 13:04 gabeweb

I'd be happy with auto copy to clipboard of totp if a single entry match. m1finance.com has a checkbox so you can enter user/pass/otp all on same screen or if you just enter user/pass it then prompts for otp on 2nd screen. Would any of the code from keepassxc be relevant because they fill otp at click of button on the desktop after entering user and pass. I was hoping to migrate to keepass specifically because I'm tired of swapping windows to launch aegis, logging in, copy otp, swap back to app, paste.

famewolf avatar Apr 23 '21 20:04 famewolf

@J-Jamet maybe take look at the keepassxc browser plugin (firefox & chromium) and topt part. Yeah it is a different language, but the detection works on most pages. https://github.com/keepassxreboot/keepassxc-browser/blob/develop/keepassxc-browser/content/totp-field.js

xf- avatar Jun 15 '21 08:06 xf-

Thank you @xf- , this will indeed be a good entry point for the creation of the feature! :)

J-Jamet avatar Jun 15 '21 11:06 J-Jamet

Ok guys, it's very complicated to test code blindly without having a form to test with, so if you have the ability to create html files that contain OTP forms from your favorite services it would be much easier for debugging.

You can generate a file from the source code of the page from your phone. (on chrome based browser add view-source: before the URL address then copy paste the code source in an html file and remove your login credentials from the code if there are any traces) Thank you for your help

J-Jamet avatar Aug 23 '21 13:08 J-Jamet

Here is one from m1finance but not sure it's helpful.

On August 23, 2021 9:48:19 AM Jérémy JAMET @.***> wrote:

Ok guys, it's very complicated to test code blindly without having a form to test with, so if you have the ability to create html files that contain OTP forms from your favorite services it would be much easier for debugging. You can generate a file from the source code of the page from your phone. (on chrome based browser add view-source: before the URL address then copy paste the code source in an html file and remove your login credentials from the code if there are any traces) Thank you for your help— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

famewolf avatar Aug 23 '21 14:08 famewolf

@famewolf Unfortunately that does not help, it would take the structure of the DOM in fact it would be better. And be careful because your copy paste contains id info.

J-Jamet avatar Aug 23 '21 15:08 J-Jamet

@J-Jamet I think starting with most common stuff like GitHub would be a good starting point. Some sites have some extra steps if a second 2FA is registered as well. For example Nextcloud using an OTP or hardware Token. I think Google has the same option.

xf- avatar Aug 23 '21 15:08 xf-

@famewolf Unfortunately that does not help, it would take the structure of the DOM in fact it would be better. And be careful because your copy paste contains id info.

Hmm I tried looking through it but obviously didn't know what to look for. Do I need to change my password on that site?

famewolf avatar Aug 23 '21 16:08 famewolf

Hey i hope these helps : github and nextcloud

mirsella avatar Aug 23 '21 17:08 mirsella

As this is a difficult feature, I will already release a version 3.0.0_beta_01 without it. Then I will improve the OTP code for the next beta. It will allow to have a feedback of the bugs with a shorter cycle.

J-Jamet avatar Aug 29 '21 10:08 J-Jamet

OK guys. Bad news, I made few tests and the OTP forms are not even parsed by the autofill. So I'm out of solutions.

  • Native Autofill OTP form : Does not fit in the parser, so I can't recognize the form metadata. Maybe the structure of the form is not properly constructed, I don't really know why. (tested with @mirsella forms on a local server, note that the main github credentials form works on the local server)

  • Compatibility mode Autofill OTP form : Recognizes only the fields as text, without metadata so not usable. (Cannot be differentiated from a username field)

  • TOTP in the clipboard during Autofill : Can't be done natively because the views of the autofill elements are delegated to the system and there is no listener for an autofill selection event (see https://github.com/Kunzisoft/KeePassDX/issues/553#issuecomment-745424894). A hack that allows copying before displaying the autofill (as Bitwarden does) is possible but has huge cons :

    • There is no point in displaying autofill if the second factor is separate from the main identifiers (which must be the case, otherwise why implementing 2FA?). The autofill will fill empty fields in main credential form.
    • The copy that is made cannot be done on all the fields returned by the autofill, so in the best case, only the first OTP token will be copied in the clipboard if several entries are retrieved during a domain search.
    • The time between the copy of the token in the clipboard which is done at the display of the autofill and the validation of the form leaves time for the token to expire.

So the only thing I can suggest is to make it easier to copy a token from the list of entries. Now the token (and its expiration time) is displayed in the list without opening the details of an entry, I can add the copy in the clipboard there. What do you think about it?

Note : If someone can recognize natively OTP forms from Android autofill, feel free to propose your solution.

J-Jamet avatar Sep 04 '21 08:09 J-Jamet