NginxProxyManager / NginxProxyManager/nginx-proxy-manager

TOTP verification consistently rejects correctly-computed codes after initial 2FA setup (v2.15.1)

Open
#5,866 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
34.2k
Forks
3.9k
Avg merge
21h 12m
Merged PRs (30d)
20

Description

NPM version: 2.15.1 (self-hosted via Docker, image jc21/nginx-proxy-manager:latest)

Summary: After enabling 2FA, TOTP codes computed with the exact secret stored in the database (standard SHA1, 6 digits, 30s step) are rejected — both for "Regenerate Backup Codes" and for normal login — even though the same method produced a code that was accepted during the initial setup/verify step.

Steps taken to rule out common causes:

Host and container clocks verified in sync (checked twice, <1s difference).
Confirmed via direct SQLite inspection that the secret is unchanged between auth.meta.totp_pending_secret (during setup) and auth.meta.totp_secret (after activation) — only the JSON key name changes, value identical.
A code computed independently with standard TOTP parameters (HMAC-SHA1, 6 digits, 30s period, current Unix time // 30) against this exact secret was accepted once, completing 2FA setup successfully.
Multiple subsequent freshly-computed correct codes (verified against the same unchanged secret, at the moment of submission) were rejected with "Invalid verification code" — both on the "Regenerate Backup Codes" dialog and on a fresh login attempt after logging out.
This resulted in a full account lockout; recovery required manually clearing auth.meta in the SQLite database via docker cp (container has no sqlite3 binary).

This looks related to #5142 but with more detailed reproduction steps. Happy to provide more details/logs if useful.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the 2FA setup verification, normal login, and Regenerate Backup Codes flows described in the issue, then inspect how auth.meta.totp_pending_secret becomes auth.meta.totp_secret in SQLite. Reproduce the setup and subsequent verification attempts with the stated SHA1, six-digit, 30-second parameters; done means correctly computed codes are accepted after activation without requiring manual auth.meta recovery.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, sqlite, typescript
Domain
authentication, backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.