Trouble with GitHub MFA login

I’m not sure if I’m just doing something wrong here or if this is a problem for everybody, but I can’t seem to get Kee to recognize the GitHub MFA form. It’s properly filling in the initial login form (username and password) and I’ve got the Tray TOTP plugin installed and working properly (e.g. I can use the plugin in KeePass proper to generate TOTP codes which are accepted by the site). Also, I know the {TOTP} placeholder is working because if I enter it in, say, the username field I see the expected result show.

For those who don’t have access to the page in question, the form element that GitHub uses to collect your TOTP response has the following properties:

CSS ID: otp
“name” attribute: otp
“type” attribute: tel

Here’s the full HTML of the element, in case I left out something relevant:

<input name="otp" id="otp" value="" autocomplete="off" autofocus="autofocus" class="form-control input-block" type="tel">

After doing basically every other trial and error thing I can think of, my best guess at this point is that Kee is ignoring the field because it’s of type “tel” (instead of, say, “text” or “password”). Unfortunately, the “Type” setting in the form field definition editor is a drop-down menu instead of a free text field, so I can’t specify an arbitrary value and the provided values (Text, Password, Radio, Checkbox, and Select) don’t include the necessary value.

This is what I have in the definition editor now:

Name: otp
Type: Text
Id: otp
Page: 2
Value: {TOTP}
KeePass placeholders: Enable [since my database default is to disable them]

As far as I’ve been able to guess from the available information, this is what’s supposed to go in there:

Name: The form element’s HTML “name” attribute
Type: The form element’s HTML “type” attribute
Id: The form element’s CSS ID, if available (otherwise, empty)
Page: Ignored, but may be used in the future for formalized multi-page logins
Value: The string to auto-fill
KeePass placeholders: Enable [since my database default is to disable them]

I also tried adding otp to the list of whitelisted form IDs, both globally and as a per-site for, but nothing I have tried has ever gotten Kee to fill anything into that field.

Any ideas? Does anybody have a working example of a two-page auto-fill with MFA? (Or a two-page login of any kind, for that matter :slight_smile:)

This is an approximation of the HTML type. Kee handles a few specific form field types but broadly categorises other field types into either “text” (of which the first example is of type “Username”) or “password”.

A “tel” field should be classified as “Text”

It looks like GitHub is misusing the field type semantics in this case, but I’m not sure why that would prevent Kee from filling it in.

The Kee debug log should explain why it is choosing not to fill in the form. If that doesn’t help, make sure you’re using version 3.0 (currently in Beta testing) since there are various fixes in there that might allow the form to be detected. Also, having two separate KeePass entries (one for each page) can often help, or at the very least help simplify the process of working out why the entry is not being filled in correctly.

How does one generate a debug log? I couldn’t find anything about it in the documentation, but I did find one thing in a bug report; it did give me something but it doesn’t seem to have the information necessary to troubleshoot this problem.

I did try making a separate entry for the MFA login, but that didn’t change the symptoms (although maybe I’ll give it another go now that we’re generating some kind of debugging output).

In any case, I started up with this command line:

keepass2 --debug --KPRPCDebug=debug.log

…and got this log. This is what showed up in the log through the entire process of opening a new Firefox tab, navigating to the GitHub login page, submitting the initial username/password login form (which Kee correctly auto-filled) and being directed to the MFA page (which I didn’t interact with).

%) cat debug.log
Logger initialised.
Client managers started.
RPC service started.
Starting KPRPCServer
Fleck says: Constructed server at ws://localhost:12546. Explicit port: 8181. Implicit port: 12546. Loopback only? True
Fleck says: Starting server at ws://localhost:12546. Loopback only? True
Fleck says: Server started at ws://localhost:12546
Started KPRPCServer
RPC server started.
KPRPC startup succeeded.
Fleck says: Client connected from
Fleck says: 553 bytes read
Fleck says: Building Hybi-14 Response
Fleck says: Sent 129 bytes
Fleck says: 399 bytes read
Fleck says: Sent 310 bytes
Fleck says: 215 bytes read
Fleck says: Sent 138 bytes
Fleck says: 265 bytes read
Fleck says: 265 bytes read
Fleck says: Sent 41249 bytes
Fleck says: Sent 329 bytes
Fleck says: 349 bytes read
Fleck says: Sent 6217 bytes
Fleck says: Sent 201 bytes
Fleck says: Sent 201 bytes
Fleck says: Sent 201 bytes

That’s the KeePassRPC log - there’s rarely much in there apart from crashes relating to operating system or .NET corruption problems. The Kee log is more likely to be useful - you can set the level of that in Kee options and view it in the browser or web console (Ctrl-Shift-k on Windows I think).

Success! The debug output confirmed that Kee was simply not seeing a valid candidate form to fill out. I kinda figured that’s what it was, but knowing for sure was a big help in the sense that it allowed me to narrow the troubleshooting focus significantly. Once I knew it had to be something with form detection, I could inspect those few things more closely and that’s when I found – as one often does in these cases – the PEBKAC. Turns out I hadn’t read/digested the options page enough on a previous trip through, and I put the otp whitelist value into the “Form ID” field and not the “Text field ID” field. So, GitHub’s form shenanigans prevented Kee from detecting the form in its (Kee’s) default configuration, and my error meant that my local configuration still couldn’t detect it.

So, to summarize, in order to get Kee to auto-fill both the initial GitHub login form (username/password) as well as the MFA secondary form, this is the setup. It’s assumed that you’ve already got the following going:

  1. A standard Kee auto-fill for the initial login page based off a KeePass entry, which you can generate by simply logging in and telling Kee to create an entry for you (just like you normally would).
  2. The “Tray TOTP” plugin installed and correctly generating TOTP responses for that entry. If you need help with this part, see the documentation for the plugin…explaining that part would push this over the TLDR limit.

Once you’ve got the basics set up: you’ll need to do the following:

  1. Edit the KeePass entry for your GitHub login, and go to the Kee tab. Within the Kee tab, go to the Form fields tab. You’ll see the username and password stuff already in there; just leave those alone and click Add, to add a new form field with the following properties:
  • Name: otp
  • Type: Text
  • Id: otp
  • Page: 2
  • Value: {TOTP}
  • KeePass placeholders: Enable

I don’t think the page number is used for anything at this point, but if it ever becomes relevant, setting the value to 2 should mean it’ll keep working in the future. For the placeholders…the point is that you need placeholders enabled for this entry. If your database default is to enable them, then you can leave that setting as Database default but the standard installation disables them by default.

  1. Click the Kee toolbar icon and go to Options. Switch the setting at the top to “A specific website”. Enter and click “Add”. Leave the new entry options as “Hostname”/“Exact” and click “Save”. Click the checkbox next to “White List > Text field ID” and type otp into the field. Click outside of the text box (so the input field de-focuses), which should save the setting.

That should do it…cross your fingers. :slight_smile:

1 Like


Glad it’s working for you now. It really would be great to make the whitelisting/blacklisting more user-focussed rather than requiring digging into HTML source code - that would remove the nice footgun that you found! In the meantime your instructions will no doubt help another poor soul avoid that pain so thank you.

I’ll just add that I’d advise setting the placeholders setting to Enable in any case - it will work if the database default is set to Enable, as you say, but this is a dangerous config option that may not be around forever so every little step to minimise the confusion and work you’d have to do if/when that feature gets removed (and the database then defaults to Disabling all placeholders unless overridden on a specific field) is a good idea.

And yes, Page number may be useful in future so 2 is a good suggestion.