[GH-ISSUE #466] Cannot enable 2FA with Android Auth App #284

Closed
opened 2026-03-03 01:27:36 +03:00 by kerem · 9 comments
Owner

Originally created by @crytectobi on GitHub (Apr 23, 2019).
Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/466

Hi,
I cannot activate 2FA with my Android phone and the Microsoft Authenticator app.
The log says:
[2019-04-23 19:35:27][rocket::rocket][INFO] PUT /api/two-factor/authenticator application/json; charset=utf-8:
[2019-04-23 19:35:27][_][INFO] Matched: PUT /api/two-factor/authenticator (activate_authenticator_put)
[2019-04-23 19:35:27][bitwarden_rs::error][ERROR] Invalid TOTP code. Invalid TOTP code

Bitwarden runs in a docker hosted on a openmediavault server.
That server is in time sync, the android phone has also the correct time.

Can I set the correct timezone in the bitwarden container? Is TZ env working or is this not implemented?
The openmediavault server is running in the Europe/Berlin timezone, phone as well. When the docker container runs in another timezone it might not work, right? Or any other ideas? :)

Originally created by @crytectobi on GitHub (Apr 23, 2019). Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/466 Hi, I cannot activate 2FA with my Android phone and the Microsoft Authenticator app. The log says: [2019-04-23 19:35:27][rocket::rocket][INFO] PUT /api/two-factor/authenticator application/json; charset=utf-8: [2019-04-23 19:35:27][_][INFO] Matched: PUT /api/two-factor/authenticator (activate_authenticator_put) [2019-04-23 19:35:27][bitwarden_rs::error][ERROR] Invalid TOTP code. Invalid TOTP code Bitwarden runs in a docker hosted on a openmediavault server. That server is in time sync, the android phone has also the correct time. Can I set the correct timezone in the bitwarden container? Is TZ env working or is this not implemented? The openmediavault server is running in the Europe/Berlin timezone, phone as well. When the docker container runs in another timezone it might not work, right? Or any other ideas? :)
kerem closed this issue 2026-03-03 01:27:36 +03:00
Author
Owner

@shauder commented on GitHub (Apr 24, 2019):

Log into the docker shell and take a look at the time there. I do set my timezone for my docker container. Examples from my docker-compose.

    environment:
      - TZ=${TIME_ZONE}
    volumes:
      - /etc/localtime:/etc/localtime:ro
calvin% docker exec -ti bitwardenrs /bin/sh 
/ # date
Wed Apr 24 19:18:32 UTC 2019
<!-- gh-comment-id:486389668 --> @shauder commented on GitHub (Apr 24, 2019): Log into the docker shell and take a look at the time there. I do set my timezone for my docker container. Examples from my docker-compose. ``` environment: - TZ=${TIME_ZONE} ``` ``` volumes: - /etc/localtime:/etc/localtime:ro ``` ``` calvin% docker exec -ti bitwardenrs /bin/sh / # date Wed Apr 24 19:18:32 UTC 2019 ```
Author
Owner

@crytectobi commented on GitHub (Apr 24, 2019):

Time in the docker container seems correct:
docker exec -it Bitwarden date
Wed Apr 24 21:24:32 CEST 2019
It is about a minute off between my computer and the server. But that offset is okay for TOTP right?
Timezone is also correct.
EDIT:
Is port 3012 neccessary for this to work?

<!-- gh-comment-id:486392660 --> @crytectobi commented on GitHub (Apr 24, 2019): Time in the docker container seems correct: docker exec -it Bitwarden date Wed Apr 24 21:24:32 CEST 2019 It is about a minute off between my computer and the server. But that offset is okay for TOTP right? Timezone is also correct. EDIT: Is port 3012 neccessary for this to work?
Author
Owner

@shauder commented on GitHub (Apr 24, 2019):

I believe a minute can cause issues. Port 312 is just for web sockets.

<!-- gh-comment-id:486431510 --> @shauder commented on GitHub (Apr 24, 2019): I believe a minute can cause issues. Port 312 is just for web sockets.
Author
Owner

@dani-garcia commented on GitHub (Apr 24, 2019):

The TOTP codes are generated per 30 second block, and at this time we only check the current time block, so any time deviation of over 30 seconds will not work.

Some implementations also check X time blocks before and after the current one, which would be a bit more insecure, but more convenient if the clients or the server aren't syncing their time with an NTP server.

We could potentially improve the situation by also checking the 2 blocks immediate to the current one, which would give a margin of 1.5 minutes, and it seems like an acceptable compromise between security and convenience.

<!-- gh-comment-id:486439201 --> @dani-garcia commented on GitHub (Apr 24, 2019): The TOTP codes are generated per 30 second block, and at this time we only check the current time block, so any time deviation of over 30 seconds will not work. Some implementations also check X time blocks before and after the current one, which would be a bit more insecure, but more convenient if the clients or the server aren't syncing their time with an NTP server. We could potentially improve the situation by also checking the 2 blocks immediate to the current one, which would give a margin of 1.5 minutes, and it seems like an acceptable compromise between security and convenience.
Author
Owner

@crytectobi commented on GitHub (Apr 25, 2019):

I fixed the offset, now it worked. I didn't know the time window is so small, most of the 2FA services I used also allow, as you mentioned, the block before and after.
Btw the offset was not a minute, it was only about 35 seconds.
Thank you for pointing this out. :)

<!-- gh-comment-id:486565856 --> @crytectobi commented on GitHub (Apr 25, 2019): I fixed the offset, now it worked. I didn't know the time window is so small, most of the 2FA services I used also allow, as you mentioned, the block before and after. Btw the offset was not a minute, it was only about 35 seconds. Thank you for pointing this out. :)
Author
Owner

@SebastianS90 commented on GitHub (Apr 25, 2019):

Right now it is possible to use the same token multiple times within the 30 seconds window. That opens an attack vector where an attacker gets password and current 2FA token (keylogger, hidden camera pointed on keyboard, just watch the victim typing, ...) and uses these to immediately login to the victim's account. By widening the window to 1.5 minutes this attack would gain more importance.

You can rule out that attack vector by saving the timestamp of the last used token on the server and for the next 2FA challenge enforce that a token for a later timestamp must be used. This prevents reuse of 2FA tokens.

lower = max (last_used_timestamp + 1, current_timestamp() - window);
upper = current_timestamp() + window;
success = false;
for (t = lower; t <= upper; t++) {
    if (check(provided_token, secret, t)) {
      success = true;
      save_timestamp(t);
      break;
    }
}
<!-- gh-comment-id:486598164 --> @SebastianS90 commented on GitHub (Apr 25, 2019): Right now it is possible to use the same token multiple times within the 30 seconds window. That opens an attack vector where an attacker gets password and current 2FA token (keylogger, hidden camera pointed on keyboard, just watch the victim typing, ...) and uses these to immediately login to the victim's account. By widening the window to 1.5 minutes this attack would gain more importance. You can rule out that attack vector by saving the timestamp of the last used token on the server and for the next 2FA challenge enforce that a token for a later timestamp must be used. This prevents reuse of 2FA tokens. ``` lower = max (last_used_timestamp + 1, current_timestamp() - window); upper = current_timestamp() + window; success = false; for (t = lower; t <= upper; t++) { if (check(provided_token, secret, t)) { success = true; save_timestamp(t); break; } } ```
Author
Owner

@BlackDex commented on GitHub (Oct 7, 2019):

Is this still an issue?
As @dani-garcia posted on the 24th of April about allowing previous and next also.
I think this is kinda the default according to the wiki page:
https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm#Practical_considerations

It also is mentioned in the RFC6238: https://tools.ietf.org/html/rfc6238#section-6
There they talk about even going 2 time-steps back and forward. That would be to much if you ask me, since that kind of time drift will probably only occur with hardware-totp tokens which are older.
And not with the software/apps that will show the tokens most people use.

And if we implement the token-used-cache as explained by @SebastianS90, that would rule-out some hack-attempts. I even think that this could be a default item to include. Since, we just want it to be used ONCE, and not Twice.

<!-- gh-comment-id:539087892 --> @BlackDex commented on GitHub (Oct 7, 2019): Is this still an issue? As @dani-garcia posted on the 24th of April about allowing previous and next also. I think this is kinda the default according to the wiki page: https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm#Practical_considerations It also is mentioned in the RFC6238: https://tools.ietf.org/html/rfc6238#section-6 There they talk about even going 2 time-steps back and forward. That would be to much if you ask me, since that kind of time drift will probably only occur with hardware-totp tokens which are older. And not with the software/apps that will show the tokens most people use. And if we implement the token-used-cache as explained by @SebastianS90, that would rule-out some hack-attempts. I even think that this could be a default item to include. Since, we just want it to be used ONCE, and not Twice.
Author
Owner

@crytectobi commented on GitHub (Oct 8, 2019):

@BlackDex from my side the issue is fixed/closed, but there should be enhancements I guess.

<!-- gh-comment-id:539330481 --> @crytectobi commented on GitHub (Oct 8, 2019): @BlackDex from my side the issue is fixed/closed, but there should be enhancements I guess.
Author
Owner

@dani-garcia commented on GitHub (Apr 8, 2020):

TOTP has been checking both the previous and next slots for some time now so this can be closed.

<!-- gh-comment-id:610947229 --> @dani-garcia commented on GitHub (Apr 8, 2020): TOTP has been checking both the previous and next slots for some time now so this can be closed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vaultwarden#284
No description provided.