[GH-ISSUE #388] Login Failure Due to Incorrect Base64 Decoding of Japanese Characters in JWT #6133

Closed
opened 2026-04-20 16:43:40 -05:00 by GiteaMirror · 12 comments
Owner

Originally created by @miikun77 on GitHub (Jan 8, 2025).
Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/388

Description

The current implementation of base64 decoding in the frontend application leads to incorrect handling of non-ASCII characters, specifically Japanese characters. This leads to a complete login failure when processing user information extracted from JWT tokens received during the OpenID Connect login flow.

Current behavior

The code responsible for decoding the base64-encoded payload of the JWT token (obtained via OpenID Connect) incorrectly replaces only the first instance of - with + and _ with /. Additionally, it fails to properly decode non-ASCII characters.

Steps to reproduce

  1. Attempt to log in to Vikunja using OpenID Connect.
  2. Use an account where the returned JWT token contains Japanese characters in the user information.
  3. Observe that the login process fails.

Additional context

The current code for base64 decoding in frontend/src/stores/auth.ts is:

const base64 = jwt.split('.')[1].replace('-', '+').replace('_', '/')
const info = new UserModel(JSON.parse(atob(base64)))

This code only replaces the first instance of - and _. A correct implementation should use regular expressions with the g (global) flag to replace all occurrences.

// Replace all occurrences of - and _
const base64 = jwt.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')
// Decode correctly, handling non-ASCII characters
const info = new UserModel(JSON.parse(decodeURIComponent(window.atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''))))

Reference

This issue is similar to a problem reported in the microsoft-authentication-library-for-js repository: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/985

Note

I am including the code directly in this report because my Gitea account is not yet approved. I apologize for any inconvenience this may cause.

Vikunja Version

v0.24.6

Browser and version

Chrome/131.0.6778.206

Can you reproduce the bug on the Vikunja demo site?

No

Screenshots

No response

Originally created by @miikun77 on GitHub (Jan 8, 2025). Original GitHub issue: https://github.com/go-vikunja/vikunja/issues/388 ### Description The current implementation of base64 decoding in the frontend application leads to incorrect handling of non-ASCII characters, specifically Japanese characters. This leads to a **complete login failure** when processing user information extracted from JWT tokens received during the OpenID Connect login flow. ## Current behavior The code responsible for decoding the base64-encoded payload of the JWT token (obtained via OpenID Connect) incorrectly replaces only the first instance of - with + and _ with /. Additionally, it fails to properly decode non-ASCII characters. ## Steps to reproduce 1. Attempt to log in to Vikunja using OpenID Connect. 1. Use an account where the returned JWT token contains Japanese characters in the user information. 1. Observe that the login process fails. ## Additional context The current code for base64 decoding in `frontend/src/stores/auth.ts` is: ``` const base64 = jwt.split('.')[1].replace('-', '+').replace('_', '/') const info = new UserModel(JSON.parse(atob(base64))) ``` This code only replaces the first instance of - and _. A correct implementation should use regular expressions with the g (global) flag to replace all occurrences. ``` // Replace all occurrences of - and _ const base64 = jwt.split('.')[1].replace(/-/g, '+').replace(/_/g, '/') // Decode correctly, handling non-ASCII characters const info = new UserModel(JSON.parse(decodeURIComponent(window.atob(base64).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')))) ``` ## Reference This issue is similar to a problem reported in the microsoft-authentication-library-for-js repository: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/985 ## Note I am including the code directly in this report because my Gitea account is not yet approved. I apologize for any inconvenience this may cause. ### Vikunja Version v0.24.6 ### Browser and version Chrome/131.0.6778.206 ### Can you reproduce the bug on the Vikunja demo site? No ### Screenshots _No response_
GiteaMirror added the needs reproduction label 2026-04-20 16:43:40 -05:00
Author
Owner

@kolaente commented on GitHub (Jan 10, 2025):

Is that reproducible on the demo when you set the accounts' name to contain non-ascii characters and then log in again?

<!-- gh-comment-id:2582509386 --> @kolaente commented on GitHub (Jan 10, 2025): Is that reproducible on the demo when you set the accounts' name to contain non-ascii characters and then log in again?
Author
Owner

@kolaente commented on GitHub (Jan 21, 2025):

I'm unable to reproduce this with a local account on the demo with a display name set to Japanese or an openid account with a Japanese name.

Can you add more details about how to reproduce this?

<!-- gh-comment-id:2604349432 --> @kolaente commented on GitHub (Jan 21, 2025): I'm unable to reproduce this with a local account on the demo with a display name set to Japanese or an openid account with a Japanese name. Can you add more details about how to reproduce this?
Author
Owner

@kolaente commented on GitHub (Jan 21, 2025):

From your analysis, it seems like this is not specific to Japanese characters in the token?

<!-- gh-comment-id:2604353551 --> @kolaente commented on GitHub (Jan 21, 2025): From your analysis, it seems like this is not specific to Japanese characters in the token?
Author
Owner

@miikun77 commented on GitHub (Feb 3, 2025):

Sorry for the delayed reply.

Thank you for your feedback. I tested by setting the account name to “日本語憂鬱髙” and confirmed that the issue occurs when decoding the Base64 payload containing Japanese characters in the JWT token.

<!-- gh-comment-id:2630012260 --> @miikun77 commented on GitHub (Feb 3, 2025): Sorry for the delayed reply. Thank you for your feedback. I tested by setting the account name to “日本語憂鬱髙” and confirmed that the issue occurs when decoding the Base64 payload containing Japanese characters in the JWT token.
Author
Owner

@kolaente commented on GitHub (Feb 3, 2025):

Did you reproduce it on the demo?

<!-- gh-comment-id:2630233107 --> @kolaente commented on GitHub (Feb 3, 2025): Did you reproduce it on the demo?
Author
Owner

@miikun77 commented on GitHub (Feb 6, 2025):

On the demo, I can't use OpenID Connect, so I can't reproduce the issue.

<!-- gh-comment-id:2639114928 --> @miikun77 commented on GitHub (Feb 6, 2025): On the demo, I can't use OpenID Connect, so I can't reproduce the issue.
Author
Owner

@kolaente commented on GitHub (Feb 6, 2025):

But can you reproduce it on the demo if you change the name in the settings?

<!-- gh-comment-id:2639118181 --> @kolaente commented on GitHub (Feb 6, 2025): But can you reproduce it on the demo if you change the name in the settings?
Author
Owner

@miikun77 commented on GitHub (Feb 6, 2025):

It seems like the issue is related to OpenID Connect, not just the name change in the settings. The problem appears to be in transferring OpenID token-related data.

<!-- gh-comment-id:2639129971 --> @miikun77 commented on GitHub (Feb 6, 2025): It seems like the issue is related to OpenID Connect, not just the name change in the settings. The problem appears to be in transferring OpenID token-related data.
Author
Owner

@kolaente commented on GitHub (Feb 7, 2025):

I've created a test account with the name 日本語憂鬱髙 in my authentik instance and was able to log in through that without issues.

If you're seeing the problem in the frontend, it might be unrelated to openid auth since the openid auth token is parsed on the server only.

<!-- gh-comment-id:2642182671 --> @kolaente commented on GitHub (Feb 7, 2025): I've created a test account with the name `日本語憂鬱髙` in my authentik instance and was able to log in through that without issues. If you're seeing the problem in the frontend, it might be unrelated to openid auth since the openid auth token is parsed on the server only.
Author
Owner

@miikun77 commented on GitHub (Mar 28, 2025):

Sorry for the delay. After a deeper investigation, I found that the issue is not related to OpenID Connect itself. Instead, it was caused by certain characters in the user database.

Specifically, when the username field contains some non-ASCII characters (such as certain Japanese characters), it triggers an error during login.

Here is an example of the data that caused the issue:

*************************** 1. row ***************************
                             id: 1
                           name: 八九寺 真宵
                       username: 八九寺 真宵
                       password:
                          email: example@example.com
                         status: 0
                avatar_provider: upload
                 avatar_file_id: 63
                         issuer: https://example.com/
                        subject: abcdefg

<!-- gh-comment-id:2760211874 --> @miikun77 commented on GitHub (Mar 28, 2025): Sorry for the delay. After a deeper investigation, I found that the issue is not related to OpenID Connect itself. Instead, it was caused by certain characters in the user database. Specifically, when the username field contains some non-ASCII characters (such as certain Japanese characters), it triggers an error during login. Here is an example of the data that caused the issue: ``` *************************** 1. row *************************** id: 1 name: 八九寺 真宵 username: 八九寺 真宵 password: email: example@example.com status: 0 avatar_provider: upload avatar_file_id: 63 issuer: https://example.com/ subject: abcdefg
Author
Owner

@kolaente commented on GitHub (Mar 28, 2025):

Which database are you using?

<!-- gh-comment-id:2761228541 --> @kolaente commented on GitHub (Mar 28, 2025): Which database are you using?
Author
Owner

@miikun77 commented on GitHub (Apr 7, 2025):

Upon further analysis, it became clear that this issue is not related to the database but rather to the frontend JWT base64 decoding implementation, which does not comply with RFC 4648 (and RFC 7519).
https://datatracker.ietf.org/doc/html/rfc4648#section-4
Specifically, when handling Base64 URL-encoded JWT payloads (as described in RFC 4648 Section 5), the following two corrections are necessary:

  • Replace all occurrences of - with + and _ with / in the Base64 URL-encoded JWT string.
  • Use the JavaScript replace method with the global (g) option, as these characters (- and _) may appear multiple times within a JWT.

Please verify and confirm this solution at your convenience.

<!-- gh-comment-id:2781944110 --> @miikun77 commented on GitHub (Apr 7, 2025): Upon further analysis, it became clear that this issue is not related to the database but rather to the frontend JWT base64 decoding implementation, which does not comply with RFC 4648 (and RFC 7519). https://datatracker.ietf.org/doc/html/rfc4648#section-4 Specifically, when handling Base64 URL-encoded JWT payloads (as described in RFC 4648 Section 5), the following two corrections are necessary: - Replace all occurrences of - with + and _ with / in the Base64 URL-encoded JWT string. - Use the JavaScript replace method with the global (g) option, as these characters (- and _) may appear multiple times within a JWT. Please verify and confirm this solution at your convenience.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vikunja#6133