In the initial launch of the WebOTP API, because we didn't find enough demand that outweighs the risk / complexity, we deliberately ignored the cross-origin iframe support. i.e. calling the API in a cross-origin iframe does not work.
With more partners requesting the feature, we should revisit the underlying privacy issue / risks and add the support if considered necessary.
Proposal
SMS format
There are ongoing discussions regarding how to update the existing "Origin-bound one-time codes delivered via SMS" specification to accommodate cross-origin iframes. We proposed the following format to preserve backward compatibility for other UAs:
@top #code @iframe
See the discussions for more details.
Nested iframes
From the extensibility’s point of view, we should support an arbitrary level of nested iframes in the long run. In theory, we should include origins from all the intermediate frames to reduce ambiguity. For example, consider the following artificial example:
store.com -> productA.com -> payment.com
store.com -> productB.com -> payment.com
On the random merchandise website store.com there are two products from two different origins. However both products use the same payment widget to verify the payment info. In this case, when payment.com sends out the SMS, it must include the intermediate origin otherwise the user will receive two SMSes with the same format:
SMS 1: @store.com #1234 @payment.com
SMS 2: @store.com #5678 @payment.com
However there are some practical concerns:
-
Including all intermediate origins may easily break the 160 character limit for SMS (and 67 char for UCS-2 encoding)
- Note: this could be mitigated in verification via email
-
Including all intermediate origins may confuse users
-
There are security concerns for the innermost iframe to access top-frame’s origin to use it in the SMS.
As a result, we proposed to limit the support to cross-origin iframes who have no more than 1 unique origin in its ancestor chain. In the following scenarios:
- a.com -> b.com
- a.com -> b.com -> b.com
- a.com -> a.com -> b.com
- a.com -> b.com -> c.com
using WebOTP in b.com will be supported but not in c.com.
Note that the following scenario is not supported because of lack of demand and UX complexities.
Permissions Policy
By default, navigator.credentials.get()
requires a secure origin and all its ancestor frames must have the same origin as the requestor does. Therefore we should add an otp-credentials
permissions policy to obtain the credentials assertions in cross-origin iframes. Note that navigator.credentials.create()
is still disabled in cross-origin iframes. Sample usage:
<! -- top_origin.com -->
<iframe allow="otp-credentials" src="cross-origin.com"></iframe>
Chromium tracking issue: https://bugs.chromium.org/p/chromium/issues/detail?id=1136506