From c7406dde0eacd1b8b6d2698a89dd324377f52409 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 15 Oct 2019 11:07:04 -0700 Subject: [PATCH] Truncate strings for authenticators where needed. There exist a significant number of authenticators that do not conform to the current WebAuthn requirements in that they fail requests with name/displayName strings longer than 64 bytes, rather than truncating them. This change adds a new requirement on user-agents that they maintain the authenticator model for RPs by doing the truncation on their behalf in this case. The alternative is that each RP will hit this edge-case and do the truncation itself, thus the ecosystem will never be able to support longer strings. Since user-agents may now be doing truncation, this change also permits truncation at the level of grapheme clusters (since user-agents presumably have Unicode tables available). Fixes #1296. --- images/string-truncation.svg | 265 +++++++++++++++++++++++++++++++++++ index.bs | 19 ++- 2 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 images/string-truncation.svg diff --git a/images/string-truncation.svg b/images/string-truncation.svg new file mode 100644 index 000000000..fb0dfdf23 --- /dev/null +++ b/images/string-truncation.svg @@ -0,0 +1,265 @@ + + + + + + + + + + image/svg+xml + + + + + + + 61 67 cc 88 + + + + + Codepoints + Graphemeclusters + + + + [63] + [64] + [62] + [61] + + + + + Bytes + UTF-8codepoints + Graphemeclusters + Truncationpoints + + diff --git a/index.bs b/index.bs index a36b66cff..4ef69053d 100644 --- a/index.bs +++ b/index.bs @@ -2393,8 +2393,7 @@ associated with or [=scoped=] to, respectively. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialEntity/name}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialEntity/name}} member's - value. Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value to a length equal to or greater - than 64 bytes. See also [[#sctn-strings]]. + value. Authenticators MAY truncate a {{PublicKeyCredentialEntity/name}} member's value so that it fits within 64 bytes. See [[#sctn-strings]] about truncation and other considerations. : icon :: A [=URL serializer|serialized=] URL which resolves to an image associated with the entity. For example, this could be @@ -2462,8 +2461,7 @@ credential. When [=clients=], [=client platforms=], or [=authenticators=] display a {{PublicKeyCredentialUserEntity/displayName}}'s value, they should always use UI elements to provide a clear boundary around the displayed value, and not allow overflow into other elements [[css-overflow-3]]. [=Authenticators=] MUST accept and store a 64-byte minimum length for a {{PublicKeyCredentialUserEntity/displayName}} - member's value. Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value to a length - equal to or greater than 64 bytes. See also [[#sctn-strings]]. + member's value. Authenticators MAY truncate a {{PublicKeyCredentialUserEntity/displayName}} member's value so that it fits within 64 bytes. See [[#sctn-strings]] about truncation and other considerations. @@ -3651,11 +3649,18 @@ or [=authenticatorGetAssertion=] operation currently in progress. Authenticators may be required to store arbitrary strings chosen by a [=[RP]=], for example the {{PublicKeyCredentialEntity/name}}, {{PublicKeyCredentialUserEntity/displayName}}, and {{PublicKeyCredentialEntity/icon}} members in a {{PublicKeyCredentialUserEntity}}. Each will have some accommodation for the potentially limited resources available to an [=authenticator=]. -If string value truncation is the chosen accommodation, the [=authenticator=] SHOULD take care to truncate on character boundaries, although the authenticator MAY truncate without reference to any character encoding. For example, an authenticator could truncate a {{PublicKeyCredentialEntity/name}} and leave a partial UTF-8 sequence at the end. If the authenticator is using [[!FIDO-CTAP]] then future messages from the authenticator may contain invalid CBOR since the value is typed as a CBOR string and thus is required to be valid UTF-8. +If string value truncation is the chosen accommodation then the amount truncated MUST be, at most, the minimum amount neccessary while respecting UTF-8 sequence and [=grapheme cluster=] boundaries. For example, in the following example the string is 65 bytes long. If truncating to 64 bytes then the final 0x88 byte must be dropped purely because of space reasons. Since that leaves a partial UTF-8 sequence an authenticator MAY drop the remainder of that sequence. Since that leaves a partial [=grapheme cluster=] an authenticator MAY drop the remainder of that cluster. That defines that maximum truncation permitted and authenticators MUST NOT truncate further. -Additionally, a [=grapheme cluster=] may be truncated [[UTR29]], altering the resulting character in the mind of the user. +
+ +
A UTF-8 encoded string showing the positions where different truncation algorithms would cut it.
+
+ +[=Conforming User Agents=] are responsible for ensuring that the authenticator behaviour observed by [=[RPS]=] conforms to this specification with respect to string handling. For example, if an authenticator is known to behave incorrectly when asked to store large strings, the user-agent should perform the truncation for it in order to maintain the model from the point of view of the [=[RP]=]. User-agents that do this SHOULD truncate at [=grapheme clusters=]. + +Authenticators that truncate on UTF-8 sequences alone may cause a [=grapheme cluster=] to be truncated [[UTR29]], altering the resulting character in the mind of the user. -User agents are tasked with handling this to avoid burdening authenticators with understanding character encodings and Unicode character properties. Thus, when dealing with [=authenticators=], user agents SHOULD: +In addition to that, truncating on byte boundaries alone causes a known issue that user-agents should be aware of: if the authenticator is using [[!FIDO-CTAP]] then future messages from the authenticator may contain invalid CBOR since the value is typed as a CBOR string and thus is required to be valid UTF-8. User agents are tasked with handling this to avoid burdening authenticators with understanding character encodings and Unicode character properties. Thus, when dealing with [=authenticators=], user agents SHOULD: 1. Ensure that any strings sent to authenticators are validly encoded. 1. Handle the case where strings have been truncated resulting in an invalid encoding. For example, any partial code point at the end may be dropped or replaced with [U+FFFD](http://unicode.org/cldr/utility/character.jsp?a=FFFD).