From 96cb6cd16f6b4ef144c8a63ea57d8e28502e54d8 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Fri, 16 Oct 2026 02:28:24 -0700 Subject: [PATCH] fix(webauthn): accept unsolicited client extension outputs from WebKit clients (#39792) (#39806) Backport #39792 Fixes #39790 Signed-off-by: choksi2212 Signed-off-by: wxiaoguang Co-authored-by: Manas Choksi <162600900+choksi2212@users.noreply.github.com> Co-authored-by: choksi2212 Co-authored-by: wxiaoguang --- modules/auth/webauthn/webauthn.go | 8 ++++++++ modules/auth/webauthn/webauthn_test.go | 2 ++ 2 files changed, 10 insertions(+) diff --git a/modules/auth/webauthn/webauthn.go b/modules/auth/webauthn/webauthn.go index d3dfe4c3607..ab026e2ab8a 100644 --- a/modules/auth/webauthn/webauthn.go +++ b/modules/auth/webauthn/webauthn.go @@ -32,6 +32,14 @@ func Init() { RPID: setting.AppDomain, RPOrigins: []string{appURL}, AttestationPreference: protocol.PreferNoAttestation, // Gitea never verifies attestation + // WebKit (Safari on iOS and macOS) returns an unsolicited "appid" client + // extension output even when the relying party did not request it. Since the + // webauthn library upgrade to v0.18, the default policy fails such ceremonies + // ('Client returned the appid extension output which was not requested'), breaking + // every passkey and security-key login from Safari on iOS. Ignore unsolicited + // extension outputs, the same policy other relying parties adopted for the + // same WebKit behavior. + ExtensionsUnsolicitedOutputPolicy: protocol.UnsolicitedOutputPolicyIgnore, }, } } diff --git a/modules/auth/webauthn/webauthn_test.go b/modules/auth/webauthn/webauthn_test.go index f24fd5fa634..490c4dc7971 100644 --- a/modules/auth/webauthn/webauthn_test.go +++ b/modules/auth/webauthn/webauthn_test.go @@ -8,6 +8,7 @@ import ( "gitea.dev/modules/setting" + "github.com/go-webauthn/webauthn/protocol" "github.com/stretchr/testify/assert" ) @@ -22,4 +23,5 @@ func TestInit(t *testing.T) { assert.Equal(t, setting.AppDomain, WebAuthn.Config.RPID) assert.Equal(t, setting.AppName, WebAuthn.Config.RPDisplayName) assert.Equal(t, rpOrigin, WebAuthn.Config.RPOrigins) + assert.Equal(t, protocol.UnsolicitedOutputPolicyIgnore, WebAuthn.Config.ExtensionsUnsolicitedOutputPolicy) }