Skip to content
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

Invalid Base 64 Url Safe character #401

Closed
willbrowningme opened this issue Aug 31, 2022 · 4 comments · Fixed by #402
Closed

Invalid Base 64 Url Safe character #401

willbrowningme opened this issue Aug 31, 2022 · 4 comments · Fixed by #402
Labels

Comments

@willbrowningme
Copy link
Contributor

willbrowningme commented Aug 31, 2022

This issue is only present for versions of Webauthn newer than v4.0.5.

Description of the issue

When trying to login with a key, the following exception is thrown:

[2022-08-31 08:03:31] local.ERROR: Invalid Base 64 Url Safe character. {"userId":"498f0da2-76a2-436e-913e-231f963ef32a","exception":"[object] (Assert\\InvalidArgumentException(code: 17): Invalid Base 64 Url Safe character. at /path/to/project/vendor/beberlei/assert/lib/Assert/Assertion.php:2728)
[stacktrace]
#0 /path/to/project/vendor/beberlei/assert/lib/Assert/Assertion.php(779): Assert\\Assertion::createException()
#1 /path/to/project/vendor/web-auth/webauthn-lib/src/Util/Base64.php(16): Assert\\Assertion::regex()
#2 /path/to/project/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(132): Webauthn\\Util\\Base64::decodeUrlSafe()
#3 /path/to/project/vendor/web-auth/webauthn-lib/src/PublicKeyCredentialLoader.php(77): Webauthn\\PublicKeyCredentialLoader->createResponse()
#4 /path/to/project/vendor/asbiin/laravel-webauthn/src/Services/Webauthn/CredentialAssertionValidator.php(54): Webauthn\\PublicKeyCredentialLoader->loadArray()
#5 /path/to/project/vendor/asbiin/laravel-webauthn/src/Services/Webauthn.php(135): LaravelWebauthn\\Services\\Webauthn\\CredentialAssertionValidator->__invoke()
#6 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): LaravelWebauthn\\Services\\Webauthn::validateAssertion()
#7 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(92): Illuminate\\Support\\Facades\\Facade::__callStatic()
#8 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/AttemptToAuthenticate.php(56): LaravelWebauthn\\Actions\\AttemptToAuthenticate->attemptValidateAssertion()
#9 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\AttemptToAuthenticate->handle()
#10 /path/to/project/vendor/asbiin/laravel-webauthn/src/Actions/EnsureLoginIsNotThrottled.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#11 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): LaravelWebauthn\\Actions\\EnsureLoginIsNotThrottled->handle()
#12 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#13 /path/to/project/vendor/asbiin/laravel-webauthn/src/Http/Controllers/AuthenticateController.php(65): Illuminate\\Pipeline\\Pipeline->then()
#14 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): LaravelWebauthn\\Http\\Controllers\\AuthenticateController->store()
#15 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction()
#16 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(261): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#17 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(204): Illuminate\\Routing\\Route->runController()
#18 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\\Routing\\Route->run()
#19 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#20 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#21 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#22 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#23 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#24 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#25 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\AuthenticateSession->handle()
#26 /path/to/project/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#27 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#28 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /path/to/project/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#30 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle()
#31 /path/to/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#33 /path/to/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#35 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(726): Illuminate\\Pipeline\\Pipeline->then()
#37 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(703): Illuminate\\Routing\\Router->runRouteWithinStack()
#38 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\\Routing\\Router->runRoute()
#39 /path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(656): Illuminate\\Routing\\Router->dispatchToRoute()
#40 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch()
#41 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#42 /path/to/project/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle()
#44 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#45 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#46 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#47 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#48 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#49 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#50 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#51 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#52 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#53 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#54 /path/to/project/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#55 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle()
#56 /path/to/project/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#57 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#58 /path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#59 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then()
#60 /path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#61 /path/to/project/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#62 {main}
"}

Steps to reproduce:

  1. Clone the https://github.com/asbiin/laravel-webauthn-example repo
  2. Install dependencies (you may need to update vite to v0.6.0 to get it to work)
  3. Register a new key
  4. You will be able to login successfully since the composer.lock file currently has v4.0.5
  5. Run composer update, this will update Webauthn to v4.1.2 (latest version currently)
  6. Logout and try to log back in with the same key
  7. You will see the above exception

The issue is still present even if you add a new key after running composer update.

It seems quite a few files were changed in Webauthn from v4.0.5 to v4.1.2. As far as I can see the authenticatorData returned from webauthn.js has characters not considered base64 URL safe by Webauthn. So I'm not sure if an update is required there.

For the time being I've had to keep Webauthn at v4.0.5 so that my users are still able to login.

@mayestik1
Copy link

mayestik1 commented Sep 1, 2022

Our authentication has been broken too.
It is related to commit web-auth/webauthn-framework@2dc9ce5
Waiting for fix.

@willbrowningme
Copy link
Contributor Author

Looks like it will be sorted in v5.0.0 - web-auth/webauthn-framework#259

@asbiin
Copy link
Owner

asbiin commented Sep 6, 2022

Thank you for the research!
Although it might been fixed in the next version of webauthn-lib, I've made a quick fix.

@github-actions
Copy link

github-actions bot commented Sep 6, 2022

🎉 This issue has been resolved in version 3.2.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants