I think I may have found part of the problem. It is line 19189 of vue.js:
const render = new Function(code)();
That conflicts with our CSP which does not allow ‘unsafe-eval’. So I need to think how to allow that on that edit account page.
And after a little effort, I did add unsafe-eval to our csp for the edit-account page and the passkey form displays again.
Sorry to bother you.
I don’t know if this is practical for your plugin, but I found that the passkey registration app currently requires CSP script-src 'unsafe-eval'.
The issue appears to be Vue runtime template compilation. The bundled Vue code uses new Function(), which is blocked by a strict CSP unless unsafe-eval is allowed.
My understanding is that Vue can also be used with precompiled templates, so the browser does not need to compile the template at runtime. That would allow the passkey registration app to work under a strict CSP.
If possible, in a future version, could you provide a CSP-compatible build of the passkey registration app that does not rely on Vue runtime template compilation / new Function()?
@amanandhishoe Thank you, and sorry for the delay.
I’ll take a look at this and try to reproduce the issue first. Once I’ve had a chance to investigate it, I’ll get back to you with my findings.
Thank you for looking into this.
If you like, I did have ChatGPT make a version that does not use vue.js. I see you just released version 1.3.0. So I had ChatGPT make a version of that does not use vue.js and it works with my csp which does not allow unsafe-eval.
I think you can download a zip of that version here:
https://www.dropbox.com/scl/fi/6awzecsapkufljzn7tj18/secure-passkeys-no-vue.zip?rlkey=i6goxsnfc7b8pspbkuppsoj41&dl=0
I do like your plugin. Recently I wanted to force admin users to only log in with passkeys. I was able to make this happen by using the filter ‘wp_authenticate_user’:
add_filter( 'wp_authenticate_user', array( $this, 'block_admin_password_login' ), 10, 2 );
And blocking regular password logins by admin users like this:
/**
* Block password-based administrator logins unless explicitly allowed.
*
* Administrators must sign in with a passkey unless password login is enabled
* with the DBTN_ALLOW_ADMIN_PASSWORD_LOGIN constant. Non-administrator users
* are not affected.
*
* @param \WP_User|\WP_Error $user Authenticated user object or login error.
* @param string $password Submitted password.
*
* @return \WP_User|\WP_Error User object when login may continue, or error when blocked.
*/
public function block_admin_password_login( $user, string $password ) {
if ( defined( 'DBTN_ALLOW_ADMIN_PASSWORD_LOGIN' ) && DBTN_ALLOW_ADMIN_PASSWORD_LOGIN ) {
return $user;
}
if ( '' === $password ) {
return $user;
}
if ( ! $user instanceof \WP_User ) {
return $user;
}
if ( ! in_array( 'administrator', (array) $user->roles, true ) ) {
return $user;
}
return new \WP_Error(
'dbtn_admin_passkey_required',
__( 'Administrator accounts must sign in with a passkey.', 'dbtnsubscriber' )
);
}
Forcing admin users to login with passkeys enhances the security and I feel is better and easier than implementing 2FA.
I also use your ‘secure_passkeys_login_redirect_url’ filter so that when admin users login, they go to admin and everyone else goes to their WooCommerce Account page. It is very handy.
This feature you added to 1.3.0 is great:
On supported browsers, passkeys now appear automatically in the browser’s autofill dropdown when you click the username field on the login page, so you can sign in without clicking any button.
That’s a big improvement. Thank you.