Terence Eden. He has a beard and is smiling.
Theme Switcher:

Some minor bugs in Proton's new Authenticator app

· 1 comment · 900 words · Viewed ~1,146 times


I maintain a a test-suite for TOTP codes. It contains a bunch of codes which adhere to the specification, some of which stretch it to breaking point, and some that are completely invalid. These codes are a good starting point for checking whether a 2FA / MFA app works correctly.

Proton have release a swish new authenticator app for Android, iOS, Mac, Linux and Windows. Sadly, their open source repository doesn't allow for bug reports so I'm blogging in public instead.

The good news is, the majority of tests pass. It accepts a wide range of acceptable codes and refuses to store most broken ones. There are a few niggles though. None of these are severe security issues, but they probably ought to be fixed.

Very long codes

The maximum number of digits which can be generated by the standard TOTP algorithm is 10. Proton happily scans codes containing 1 - 9 digits, but complains about 10 digit codes. So this fails:

otpauth://totp/issuer%3Aaccount%20name?secret=QWERTYUIOP&digits=10&issuer=issuer&algorithm=SHA1&period=30

QR code for a 10 digit TOTP.

The TOTP RFC says:

Basically, the output of the HMAC-SHA-1 calculation is truncated to obtain user-friendly values

1.2. Background

But doesn't say how far to truncate.

There's nothing I can see in the spec that prevents an implementer using all 10.

Risk: The user may not be able to store a valid code.

Recommendation: Allow 10 digit codes.

Invalid Secrets

Here we get to yet another deficiency in the TOTP specification. How is a secret defined?

Google says the secret is:

an arbitrary key value encoded in Base32 according to RFC 3548. The padding specified in RFC 3548 section 2.2 is not required and should be omitted.

Whereas Apple says it is:

An arbitrary key value encoded in Base32. Secrets should be at least 160 bits.

Either way, the Base32 alphabet contains only uppercase letters and a few numbers. What happens if we give it a secret like QWERT!£$%^)*(YUIOP?

QR code for an invalid secret.

Proton Authenticator just accepts it. It stores the full secret but I'm not sure how it generates the code based on it.

Risk: The code may be generated incorrectly.

Recommendation: Warn the user that the secret may be invalid and that a correct 2FA code cannot be guaranteed.

Issuer Mismatch

In this example, the first issuer is example.com but the second issuer is microsoft.com

otpauth://totp/example.com%3Aaccount%20name?secret=QWERTYUIOP&digits=6&issuer=microsoft.com&algorithm=SHA1&period=30

What should the TOTP reader do with this? Proton chooses microsoft.com.

This is something which, again, is inconsistent between major providers.

Google says this parameter is:

Strongly Recommended The issuer parameter is a string value indicating the provider or service this account is associated with, URL-encoded according to RFC 3986. If the issuer parameter is absent, issuer information may be taken from the issuer prefix of the label. If both issuer parameter and issuer label prefix are present, they should be equal.

Apple merely says:

The domain of the site or app. The password manager uses this field to suggest credentials when setting up a new code generator.

Yubico equivocates with

The issuer parameter is recommended, but it can be absent. Also, the issuer parameter and issuer string in label should be equal.

Risk: The code may be displayed with the wrong issuer.

Recommendation: Warn the user that there are multiple issuers. Let them choose which one is correct.

Dealing With Defaults

What should a TOTP app do if there is missing information? Proton does the following:

  • If the code has no number set for digits, it defaults to 6
  • If the code has no time set for period, it defaults to 30
  • If the code has no algorithm, it defaults to SHA1

Risk: Low. The user normally has to confirm with the issuer that the the TOTP code has been correctly stored.

Recommendation: Let the user know that the code has missing data and may not be correct.

Odd Labels

The label allows you to have multiple codes for the same service. For example Big Bank:Personal Account and Big Bank:Family Savings. The Google spec is slightly confusing:

The issuer prefix and account name should be separated by a literal or url-encoded colon, and optional spaces may precede the account name. Neither issuer nor account name may themselves contain a colon.

What happens if there are spaces before the account name?

otpauth://totp/Spaces:%20%20%20%20%20%20%20%20%20%20%20%20test%40example.com?secret=QWERTYUIOP&digits=6&issuer=&algorithm=SHA1&period=30 QR code for a TOTP.

Proton strips the spaces (probably wise) but also removes the issuer.

Risk: The user will not know which account the code is for.

Recommendation: Keep the issuer.

Timeline

These aren't particularly high severity bugs, nevertheless I like to give organisations a bit of time to respond.

  • 2025-07-31 - Discovered.
  • 2025-08-01 - Disclosed via a web form.
  • 2025-08-31 - Automatically published.

Next Steps

  • If you're a user, please contribute tests or give feedback.
  • If you're a developer, please check your app conforms to the specification.
  • If you're from a security company - wanna help me write up a proper RFC so this doesn't cause issues in the future?

Share this post on…

One thought on “Some minor bugs in Proton's new Authenticator app”

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

See allowed HTML elements: <a href="" title="">
<abbr title="">
<acronym title="">
<b>
<blockquote cite="">
<br>
<cite>
<code>
<del datetime="">
<em>
<i>
<img src="" alt="" title="" srcset="">
<p>
<pre>
<q cite="">
<s>
<strike>
<strong>

To respond on your own website, write a post which contains a link to this post - then enter the URl of your page here. Learn more about WebMentions.