TypingDNA Authenticator is browser-based authenticator app that is designed to replace mobile phone authenticator apps like Google Authenticator and Duo Mobile. Like Google Authenticator and Duo Mobile, TypingDNA Authenticator uses Time-based One-Time Passwords (TOTP) to produce short codes that users use as a second factor (alongside traditional user names and passwords) to log in to websites.

At the time of writing (2018-05-09), TypingDNA Authenticator version 0.0.28 exposes users’ TOTP secrets to Google. In addition, it logs every interaction the user has with the extension pop up page via Google Analytics, including which services users create accounts with. As of 0.0.30, both issues have been resolved. See updates below.

TOTP

TOTP is a clever approach to multi-factor authentication. When the user of a website that supports TOTP wishes to enable it, the web server generates a secret value1 which it shares with the user.

The secret is typically shared by showing a quick response (QR) code which encodes a OTPAUTH URI. The user will scan this code with her authenticator app which then records the information.

The OTPAUTH URI contains a label (e.g., the user’s email address), the TOTP secret, and the issuer (the service that the account is associated with).

For example, the URI

otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example

is issued by Example for alice@google.com and has the base-32-encoded secret JBSWY3DPEHPK3PXP. This URI could be displayed to the user as the following QR code which the user would typically scan with an authenticator app.

QR code for example URI

When the user wants to log in to a website, she will typically enter her user name and password as well as a 6–8 digit code generated by her authentication app. The authentication app generates the code by combining the secret from the QR code with the current time using an HMAC. The full details are spelled out in RFC 6238. The web server performs the same computation, computing the expected digits from the shared secret and the current time and compares the expected value with the value received from the user. If they match, then the user is authenticated.

Exposing secrets via Google Charts

To add new accounts to TypingDNA Authenticator, the user logs in to the TypingDNA service via the Chrome extension.2 Next, the extension asks Chrome to take a screen shot of the current tab which the extension scans for the presence of a QR code containing an OTPAUTH URI. Finally, the three components of the OTPAUTH URI are extracted, encrypted, and stored locally.

The encryption key comes from the TypingDNA service after successfully logging in and is not stored locally.

Users are free to modify or export their TOTP data by clicking on the pencil icon.

TypingDNA UI

Doing so opens a new window displaying, among other things, a QR code encoding the OTPAUTH URI. The idea is that users can scan the QR code with another authenticator app if they wish.

TypingDNA QR code

The problem is in how this QR code is generated.

Google Charts has a deprecated API which developers can use to embed a QR code using an HTTP GET request that contains the data to be encoded.

TypingDNA Authenticator uses this API to fetch a QR code containing the OTPAUTH URI which itself contains the TOTP secret. The relevant code from the extension is this JavaScript function.

function showQRCode(qrbool0) {
  var qrbool = qrbool0 || true;
  var account = $('#accountNameIE').val()
  var issuer = account.split(" ")[0];
  var accountStr = account.replace("(", ":").replace(")", "").replace(" ", "");
  var secret = $('#accountSecretIE').val();
  var url = "https://www.google.com/chart?chs=250x250&chld=M|0&cht=qr&chl=otpauth://totp/" + accountStr + "?secret=" + secret + "&issuer=" + issuer;
  $('#qrdiv').html("<img src='" + url + "'>");
  if (qrbool == true) {
    trackPage("showQR");
    $('#qrdiv').show();
  } else {
    $('#qrdiv').hide();
  }
}

You can see the url variable contains the OTPAUTH URI as a GET parameter. Google Chrome’s developer tools can be used to verify that this is indeed how the QR code is generated.

The QR code in the image above was fetched from this URL.

https://www.google.com/chart?chs=250x250&chld=M|0&cht=qr&chl=otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example

I’ve copied the image locally since this particular API is deprecated.

QR code from Google

Logging interactions with the extension

The TypingDNA Authenticator extension uses Google Analytics extensively to track every interaction you have with the extension. Each button you click and each page of the extension is tracked using Google Analytics.

In my experiments, both HTTP and HTTPS requests were made for each tracked action. Some of the logged information includes

  • Issuers (service names) for each account created
  • Error messages
  • Buttons pressed
  • Settings changed
  • Each page of the extension viewed (e.g., the registration, login, add and edit accounts, and show QR code pages)
  • The fact that the TOTP code was copied by clicking on it (but not the code itself)

I’m not sure why this information is being tracked at all, let alone with such fine granularity.

The one obviously sensitive piece of information that is being logged via Google Analytics that I’ve seen is the names of the services where the user has created an account. That said, I’ve only taken a cursory look at the information that is being tracked so there could be more.

This tracking data, including service names, is initially sent in the clear using HTTP. Google servers respond with a temporary redirect to their HTTPS pages. Thus anyone who can see a TypingDNA user’s network traffic while she adds a new account can see which service she is using. This is in addition to TypingDNA who can see all of the services all of their users are using.

Conclusions

I have reported my findings to TypingDNA and will update this post if I hear back.

In the meantime, you should avoid using TypingDNA Authenticator.

Updates:

  1. 2018-05-09. The title and description of this post were updated from “TypingDNA Authenticator shares secrets with Google” and “TypingDNA Authenticator Google Chrome extension shares TOTP secrets with Google and tracks your actions” respectively to better reflect the fact that, although Google is the recipient of this information, Google was not involved in the decision to share the information.

    The second paragraph was updated to explicitly mention the sharing of the services’ names via Google Analytics. The last paragraph of logging section was added to point out that the logging information is revealed over HTTP.

  2. The CEO of TypingDNA, Raul Popa, emailed me. He said that TypingDNA Authenticator will be updated to generate QR codes locally, without the use of the Google Charts API. He defended the fine-grained use of Google Analytics for tracking how users use the extension, including which services users use. The use of HTTP rather than HTTPS appears to be due to Google’s ga.js script.

  3. 2018-05-22. As of version 0.0.30, TypingDNA Authenticator no longer uses Google APIs to generate QR codes. The QR images displayed are now created entirely in JavaScript. Furthermore, the service names are no longer sent via Google Analytics.

    I appreciate that TypingDNA took quick action to update their software.

Notes

  1. This value is unrelated to the user’s password. It’s typically just a pseudorandomly-chosen integer. 

  2. I have some concerns around whether this is actually a second factor in a multi-factor authentication scheme since what you need to log in to TypingDNA’s service is an email address and optionally a password. Their claim is that how one types can be used as a biometric identifier and the extension records how you type your email address and password and sends that off to the service to validate you. I have some security and privacy concerns about this approach separate from the issues described here.