fusionauth-issues icon indicating copy to clipboard operation
fusionauth-issues copied to clipboard

Can send a code during step up auth when user has only TOTP authenticator

Open mooreds opened this issue 2 years ago • 3 comments

Can send a code during step up auth when user has only TOTP authenticator

Description

During step up auth, as documented here and here, you can provide an optional code parameter. This allows you to use step up auth with alternate delivery methods (slack, carrier pigeon).

However, when providing the code, if the user only has TOTP enabled, it doesn't make sense to allow the code parameter to be sent. This is because the whole point of TOTP is the shared secret means there's no need for delivery of a code.

We should disallow any start requests that contain a code when the user has TOTP enabled. Additionally, if the user has TOTP and a delivery based mechanism, the code should not be used for the TOTP auth method, but instead the calculated value based on the time and the shared secret should be used.

Affects versions

1.36.4

Steps to reproduce

  • Enable TOTP on an account. I did it with this curl script: curl -XPATCH -H 'Content-type: application/json' -H "Authorization: $API_KEY" 'https://local.fusionauth.io/api/user/00000000-0000-0000-0000-000000000004' -d '{"user": {"twoFactor": {"methods": [ {"authenticator": {"algorithm": "HmacSHA1", "codeLength": 6, "timeStep": 30}, "id": "Q4CZ", "method": "authenticator"} ] }}}'
  • Start step up auth: REQUEST_PAYLOAD='{ "loginId": "[email protected]", "applicationId": "3c219e58-ed0e-4b18-ad48-f4f92793ae32", "code": "123456" }' curl -XPOST -H 'Content-type: application/json' -H "Authorization: $API_KEY" 'https://local.fusionauth.io/api/two-factor/start' -d "$REQUEST_PAYLOAD"

You'll get back this: {"code":"123456","methods":[{"authenticator":{"algorithm":"HmacSHA1","codeLength":6,"timeStep":30},"id":"QJGG","method":"authenticator"}],"twoFactorId":"mecpLEbalBVoziJPGeauIod-jaHRkQlZEEuxE304ZGY"}

If you actually try to complete the step up, you end up getting an error from FusionAuth and a NPE in the system logs, as mentioned here: https://github.com/FusionAuth/fusionauth-issues/issues/1715#issuecomment-1119796308

Expected behavior

Any 2fa happening where the code is provided and an authenticator app is used should ignore the code (for the authenticator method).

Community guidelines

All issues filed in this repository must abide by the FusionAuth community guidelines.

mooreds avatar May 05 '22 23:05 mooreds

In this example, can you then use the code 123456 to complete the Two-Factor Login (/api/two-factor/login)?

robotdan avatar May 06 '22 15:05 robotdan

Yes.

I updated the doc here: https://github.com/FusionAuth/fusionauth-site/pull/1373 to make it more clear that you shouldn't provide the code, but if you do, the step up completes.

mooreds avatar May 06 '22 16:05 mooreds

Actually, I'm wrong. I get this message when I complete the step up:

{"generalErrors":[{"code":"[Exception]","message":"FusionAuth encountered an unexpected error. Please review the troubleshooting guide found in the documentation for assistance and the available support channels."}]}

And in the system log I see:

teststepupauth-fusionauth-1   | java.lang.NullPointerException: Cannot invoke "String.getBytes(java.nio.charset.Charset)" because "src" is null
teststepupauth-fusionauth-1   | 	at java.base/java.util.Base64$Decoder.decode(Base64.java:589)
teststepupauth-fusionauth-1   | 	at io.fusionauth.api.service.authentication.DefaultAuthenticationService.validateTOTP(DefaultAuthenticationService.java:665)
teststepupauth-fusionauth-1   | 	at io.fusionauth.api.service.authentication.DefaultAuthenticationService.validateTwoFactorCode(DefaultAuthenticationService.java:409)
teststepupauth-fusionauth-1   | 	at io.fusionauth.api.service.authentication.DefaultAuthenticationService.authenticateTwoFactor(DefaultAuthenticationService.java:222)
teststepupauth-fusionauth-1   | 	at io.fusionauth.app.action.api.twoFactor.LoginAction.lambda$post$0(LoginAction.java:55)
teststepupauth-fusionauth-1   | 	at io.fusionauth.app.action.api.BaseLoginAction.callLogin(BaseLoginAction.java:175)
teststepupauth-fusionauth-1   | 	at io.fusionauth.app.action.api.twoFactor.LoginAction.post(LoginAction.java:55)
teststepupauth-fusionauth-1   | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

mooreds avatar May 06 '22 16:05 mooreds