You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(webauthn): enforce userVerification=required on the shared-secret path (#248)
When a ceremony also needed a shared secret, for example any request
using the PRF extension, the check that enforces required user
verification was skipped. On a device that can verify the user but is
not yet enrolled, a registration requested with required user
verification could complete with no user verification at all, and the
PRF output came from the non-verified variant.
This enforces required user verification regardless of whether a shared
secret is needed. When the device cannot verify the user, the request
now fails clearly instead of proceeding. Requests that prefer or
discourage user verification are unaffected.
Includes a regression test covering the required, not-yet-enrolled case.
let can_establish_shared_secret = get_info_response.can_establish_shared_secret();
142
142
let needs_shared_secret = ctap2_request.needs_shared_secret(get_info_response);
143
143
// If it is not discouraged and either RP or device requires it.
144
144
let uv = !rp_uv_discouraged && (rp_uv_preferred || dev_uv_protected);
145
145
146
146
debug!(%rp_uv_preferred, %rp_uv_discouraged, %dev_uv_protected, %uv, %needs_shared_secret, %can_establish_shared_secret,"Checking if user verification is required");
147
+
// Enforce required UV even on the shared-secret path. A shared-secret-only result performs no UV.
148
+
if user_verification.is_required() && !dev_uv_protected {
149
+
error!(
150
+
"Request requires user verification, but device user verification is not available. Try letting the user set a PIN."
151
+
);
152
+
// Lets try setting a PIN. Either we succeed in some fashion, or we return the resulting error here instead.
153
+
try_to_set_pin(
154
+
channel,
155
+
get_info_response,
156
+
PinNotSetReason::PinNotSet,
157
+
timeout,
158
+
)
159
+
.await?;
160
+
// Update get_info_response, because now maybe "clientPin" is set to `Some(true)`
0 commit comments