Passbolt export to keepass using mfaMode: noninteractive-totp fails when mfaTotpToken contains padding
Describe the bug:
When executing a KeePass export using the --mfaMode noninteractive-totp, specifying the --mfaTotpToken as is (with possible '===' padding thrown in at the end), throws the error:
Error: Logging in: Getting CSRF Token: MFA Callback: Error Generating MFA Code: Decoding token string: illegal base32 data at input byte 52
To Reproduce: Run a export with mfaMode noninteractive-totp and specify the mfaTotpToken, like the following example:
passbolt export keepass -f 'keepassFile.kdbx' -p 'password' --mfaMode 'noninteractive-totp' --mfaTotpToken 'O479J4873KP50M18C65S4DSK942RH89XI8G25S8SSD52F8BE2R746=='
Output when using --debug:
Using config file: /Users/$USER/Library/Application Support/go-passbolt-cli/go-passbolt-cli.toml
[go-passbolt] Request URL: https://example.com/auth/verify.json?api-version=v2
[go-passbolt] Raw Request: {"gpg_auth":{"keyid":"...","server_verify_token":"..."}}
[go-passbolt] Raw Response: {"header":{"id":"...","status":"error","servertime":1739383356,"action":"...","message":"The authentication failed.","url":"\/auth\/verify.json?api-version=v2","code":200},"body":null}
[go-passbolt] Request URL: https://example.com/auth/login.json?api-version=v2
[go-passbolt] Raw Request: {"gpg_auth":{"keyid":"..."}}
[go-passbolt] Raw Response: {"header":{"id":"...","status":"error","servertime":1739383356,"action":"...","message":"The authentication failed.","url":"\/auth\/login.json?api-version=v2","code":200},"body":null}
[go-passbolt] Got Encrypted Auth Token: ...
[go-passbolt] Decrypted Auth Token: gpgauthv1.3.0|36|...|gpgauthv1.3.0
[go-passbolt] Request URL: https://example.com/auth/login.json?api-version=v2
[go-passbolt] Raw Request: {"gpg_auth":{"keyid":"...","user_token_result":"gpgauthv1.3.0|36|...|gpgauthv1.3.0"}}
[go-passbolt] Raw Response: {"header":{"id":"...","status":"success","servertime":1739383356,"action":"...","message":"You are successfully logged in.","url":"\/auth\/login.json?api-version=v2","code":200},"body":{"id":"...","role_id":"...","username":"...","active":true,"deleted":false,"disabled":null,"created":"2022-10-11T18:58:49+00:00","modified":"2024-10-28T15:16:54+00:00","groups_users":[],"profile":{"id":"...","user_id":"...","first_name":"...","last_name":"...","created":"2022-10-11T18:58:49+00:00","modified":"2024-10-28T15:16:54+00:00","avatar":{"id":"...","profile_id":"...","created":"2024-10-28T15:16:54+00:00","modified":"2024-10-28T15:16:54+00:00","url":{"medium":"https:\/\/example.com\/avatars\/view\/b3f75a0b-0a99-4515-9e43-13689e85ad55\/medium.jpg","small":"https:\/\/example.com\/avatars\/view\/b3f75a0b-0a99-4515-9e43-13689e85ad55\/small.jpg"}}},"gpgkey":{"id":"...","user_id":"...","armored_key":"...","bits":3072,"uid":"...","key_id":"...","fingerprint":"...","type":"RSA","expires":null,"key_created":"2022-10-11T18:58:59+00:00","deleted":false,"created":"2022-10-11T18:59:07+00:00","modified":"2022-10-11T18:59:07+00:00"},"role":{"id":"...","name":"admin","description":"Organization administrator","created":"2012-07-04T13:39:25+00:00","modified":"2012-07-04T13:39:25+00:00"},"last_logged_in":null}}
[go-passbolt] Got Cookies: [passbolt_session=...; Path=/; HttpOnly; SameSite=Lax]
[go-passbolt] Request URL: https://example.com/users/me.json?api-version=v2
[go-passbolt] Raw Response: {"header":{"id":"...","status":"error","servertime":1739383357,"action":"...","message":"MFA authentication is required.","url":"\/mfa\/verify\/error.json","code":403},"body":{"mfa_providers":["totp"],"providers":{"totp":"https:\/\/example.com\/mfa\/verify\/totp.json"}}}
Error: Logging in: Getting CSRF Token: MFA Callback: Error Generating MFA Code: Decoding token string: illegal base32 data at input byte 52
Passbolt Server Version:
- Edition: Community
- Version 4.11.0-1
go-passbolt-cli Version:
- OS: macOS
- Version 0.3.1
Hi @Stenstromen, so the reason for the failure is because your mfaTotpToken is not a valid base32 string and only valid base32 can be used to generate totps. Can you try converting it from base64 to base32 and see if it works?
Hi @Nelwhix ,
The string I use in my example is intentionally not valid, because it didn't feel right to use my actual live one.
My main point with this issue is that while the Passbolt WebUI TOTP Generator accepts a base32 string with padding added to the end as a valid one. Say 52F10769M85H704GWXJIVY39FPK8S3EZ02ZX5KVC598S91149WM2A==== (again, not an actual valid TOTP secret).
But the exact same string, with the padding added, is not considered valid by go-passbolt-cli. But when the padding at the end is removed, 52F10769M85H704GWXJIVY39FPK8S3EZ02ZX5KVC598S91149WM2A, it is considered valid by go-passbolt-cli --mfaTotpToken. (???)
TLDR
Does not Work (valid base32 string with padding)
passbolt export keepass -f 'keepassFile.kdbx' -p 'password' --mfaMode 'noninteractive-totp' --mfaTotpToken '52F10769M85H704GWXJIVY39FPK8S3EZ02ZX5KVC598S91149WM2A===='
Works (base32 padding removed)
passbolt export keepass -f 'keepassFile.kdbx' -p 'password' --mfaMode 'noninteractive-totp' --mfaTotpToken '52F10769M85H704GWXJIVY39FPK8S3EZ02ZX5KVC598S91149WM2A'
Okay I get you now, I have been able to reproduce it locally. Working on a fix
@speatzle made a PR, please tell me what you think.
Looks good, ill try to Test and Merge Tomorrow
Test with the latest release v0.3.2
@Nelwhix
I just attempted an export (go-passbolt-cli v0.3.2) with the padding still there, and it works!
Let's go💪🏾💪🏾