Skip to content

MFA setup fails on iOS because displayed TOTP seed differs from stored temporary database seed #116

Description

@abraxas-von-abrasax

MFA setup fails on iOS because displayed TOTP seed differs from stored temporary database seed

Description

We are self-hosting HumHub and have installed/configured the official MFA module.

When users sign in, they are redirected to the MFA setup screen where they can scan the TOTP QR code. We observed that MFA setup works correctly on Android devices, but fails on iOS devices.

The issue appears to be that the TOTP seed shown to the user on the frontend differs from the temporary seed stored in the database on iOS.

Observed behavior

During MFA setup, the temporary TOTP secret is stored in the database in the following location:

  • Table: contentcontainer_setting
  • Key: twofaGoogleAuthSecretTemp

On Android devices, the seed stored in the database matches the seed displayed on the frontend / encoded in the QR code. As a result, entering the TOTP code generated by the authenticator app successfully completes the MFA setup.

On iOS devices, however, the seed displayed on the frontend / encoded in the QR code appears to be different from the seed stored in the database under twofaGoogleAuthSecretTemp. Because of this mismatch, the generated TOTP code is rejected, and the user cannot complete MFA setup.

Since the MFA setup cannot be completed on iOS, the temporary seed is never moved from twofaGoogleAuthSecretTemp to twofaGoogleAuthSecret.

Expected behavior

The TOTP seed displayed to the user / encoded in the QR code should always match the temporary seed stored in the database during setup, regardless of the client device, operating system, or browser.

Users on iOS should be able to scan the QR code, enter the generated TOTP code, and complete MFA setup successfully.

Actual behavior

On iOS devices:

  1. The user is redirected to the MFA setup screen.
  2. The user scans the QR code with an authenticator app.
  3. The authenticator app generates a TOTP code.
  4. The user enters the code in HumHub.
  5. HumHub rejects the code.
  6. The user cannot complete MFA setup.
  7. The temporary seed remains stored under twofaGoogleAuthSecretTemp and is never moved to twofaGoogleAuthSecret.

After checking the database, the stored twofaGoogleAuthSecretTemp value does not match the seed shown/used on the frontend.

Steps to reproduce

  1. Set up a self-hosted HumHub instance.
  2. Install and configure the official MFA module.
  3. Sign in with a user who has not completed MFA setup yet.
  4. Open the MFA setup screen on an iOS device.
  5. Scan the TOTP QR code with an authenticator app.
  6. Enter the generated TOTP code.
  7. Observe that the code is rejected.
  8. Compare the seed shown/encoded on the frontend with the value stored in contentcontainer_setting under key twofaGoogleAuthSecretTemp.

Additional observations

  • The same flow works correctly on Android.
  • On Android, the frontend seed and database seed are identical.
  • On iOS, the frontend seed and database seed are consistently different.
  • The issue affects multiple browsers tested on iOS (tested on: Chrome, Safari, Firefox, Vivaldi).
  • Since all browsers on iOS are required to use WebKit, this may point to an iOS/WebKit-specific behavior rather than a browser-vendor-specific issue.
  • This prevents affected users from completing MFA setup.

Environment

  • HumHub version: Professional Edition 1.15.5
  • MFA module version: 1.1.3
  • PHP version: 8.2.31
  • Database: MariaDB 10.11.14-MariaDB-0+deb12u2-log
  • Server OS: Debian 12 (bookworm), Linux Kernel: 6.1.164-1
  • Affected client OS/browser: iOS / Chrome, Safari, Firefox, Vivaldi, Brave
  • Working client OS/browser: Android / Chrome, Firefox, Vivaldi, Brave
  • Authenticator app used on iOS: Microsoft Authenticator

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions