-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FIDO2 Web Authn on Android displays a wrong text in Japanese #3345
Comments
Minimal Reproducible ExampleThis is the minimal reproducible example:
using System;
using System.Text;
using System.Text.RegularExpressions;
class Encoder {
static void Main(string[] args) {
// c.f. https://github.com/bitwarden/mobile/blob/8a43bb465515d3a775e60eb083cf88ef0e3e70c8/src/Core/Pages/Accounts/TwoFactorPageViewModel.cs#L343
// c.f. https://github.com/bitwarden/mobile/blob/8a43bb465515d3a775e60eb083cf88ef0e3e70c8/src/Core/Resources/Localization/AppResources.ja.resx#L2128
var message = "WebAuthn の認証";
var json = $"{{\"btnText\": \"{message}\"}}";
// c.f. https://github.com/bitwarden/mobile/blob/main/src/Core/Utilities/AppHelpers.cs#L523
string EncodeMultibyte(Match match)
{
return Convert.ToChar(Convert.ToUInt32($"0x{match.Groups[1].Value}", 16)).ToString();
}
var escaped = Uri.EscapeDataString(json);
Console.WriteLine(escaped);
var multiByteEscaped = Regex.Replace(escaped, "%([0-9A-F]{2})", EncodeMultibyte);
var data = Convert.ToBase64String(Encoding.UTF8.GetBytes(multiByteEscaped));
Console.WriteLine(data);
}
}
// c.f. https://github.com/bitwarden/clients/blob/48de33fc7a360e0a23df3351b3ad63d1c5579aac/apps/web/src/connectors/common.ts#L18
function b64Decode(str) {
return decodeURIComponent(
Array.prototype.map
.call(atob(str), (c) => {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
})
.join(""),
);
}
// c.f. https://github.com/bitwarden/clients/blob/48de33fc7a360e0a23df3351b3ad63d1c5579aac/apps/web/src/connectors/webauthn.ts#L88
function decode(data) {
const dataObj = JSON.parse(b64Decode(data));
console.log(dataObj.btnText);
}
decode(process.argv[2]); The next command would generate the same mojibake text as the one that WebAuth Mobile Connector displayed: $ node Decoder.js $(mono Encoder.exe)
WebAuthn ã�®èª�è FixThe next version of the using System;
using System.Text;
using System.Text.RegularExpressions;
class Encoder {
static void Main(string[] args) {
// c.f. https://github.com/bitwarden/mobile/blob/8a43bb465515d3a775e60eb083cf88ef0e3e70c8/src/Core/Pages/Accounts/TwoFactorPageViewModel.cs#L343
// c.f. https://github.com/bitwarden/mobile/blob/8a43bb465515d3a775e60eb083cf88ef0e3e70c8/src/Core/Resources/Localization/AppResources.ja.resx#L2128
var message = "WebAuthn の認証";
var json = $"{{\"btnText\": \"{message}\"}}";
var data = Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
Console.WriteLine(data);
}
} $ node Decoder.js $(mono Encoder.exe)
WebAuthn の認証 AnalysisLet's take a look at the first multibyte character in the original message, "の" (U+306E), for example.
The consumer-side implementation reverses just the step (5), (4), and (1). Therefore, we get Justification of the proposed fixIf I understand correctly, the intention of this conversion in Therefore, just In practice, Base64 encoding is also necessary for consistency with the consumer-side. In any way, the earlier steps of (2), and (3) are not necessary at all. Both of |
Fixes bitwarden#3345 Make the implementation of the character convertion consistent with their consumers in the web app.
Hi there, This issue has been escalated for further investigation. If you have more information that can help us, please add it below. Thanks! |
Thank you for your response, @daniellbw. Just in case, I have already prepared a fix for this issue in #3346 |
Production Build
Steps To Reproduce
Expected Result
The Web Authn mobile connector has a blue button whose display text is "Web Authn の認証".
The display text should be consistent with the string "Fido2AuthenticateWebAuthn" in the locale file
src/Core/Resources/Localization/AppResources.ja.resx
.Actual Result
The Web Authn mobile connector has a blue button whose display text is "WebAuthn ��証".
The actual byte sequence of the display text is:
Screenshots or Videos
Expected
Screenshot of the expected result (the display text of the button was modified by the inspection tool in Chrome):
Actual
Screenshot of the actual result:
Ref
FYI: Screenshot of the equivalent page in the Bitwarden Chrome Extension (
webauthn-fallback-connector.html
).This is consistent with the expected result.
Additional Context
I believe you can reproduce an equivalent result by inserting a unicode emoji into the
Fido2AuthenticateWebAuthn
entry in the message localization file in an arbitrary locale.If I understand correctly, the root cause of the issue is that the escape of multibyte characters is inconsistently implemented to the unescaping in the webauthn connector, and the mobile application passes a wrong
data
query parameter to https://vault.bitwarden.com/webauthn-mobile-connector.html.data
query parameter by first decoding it as BASE64 and then parsing it as a JSON object:TwoFactorPageViewModel.cs
encodes thedata
parameter with an inconsistent way:Fido2AuthenticateAsync
AppHelpers.EncodeDataParameter
Bit.App.Pages.TwoFactorPageViewModel.Fido2AuthenticateAsync
method generates thedata
parameter by passing the values toBit.App.Utilities.AppHelpers.EncodeDataParameter
.EncodeDataParameter
first encodes the given object into JSON (JsonConvert.SerializeObject)
), and then escape it with URL encoding (Uri.EscapeDataString
)Convert.ToChar(Convert.ToUInt32($"0x{match.Groups[1].Value}", 16)).ToString()
, and then the generated single byte string into a byte sequence withEncoding.UTF8.GetBytes
.Operating System
Android
Operating System Version
14
Device
Pixel6
Build Version
2024.6.0 (10746)
The text was updated successfully, but these errors were encountered: