From a25d1d77eb1ca24ae1c7b60f6b5c66166664c669 Mon Sep 17 00:00:00 2001 From: Manas Choksi <162600900+choksi2212@users.noreply.github.com> Date: Fri, 16 Oct 2026 14:09:07 +0530 Subject: [PATCH] fix(webauthn): accept unsolicited client extension outputs from WebKit clients (#39792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 28.0.0 bumped `github.com/go-webauthn/webauthn` from v0.17.4 to v0.18.x. v0.18.0 made the ceremony fail whenever the client returns a client extension output the relying party did not request, unless `Config.ExtensionsUnsolicitedOutputPolicy` says otherwise; the strict behavior is the zero value, so not configuring a policy opts into it (upstream MIGRATION.md ยง2.4). Every security-key and passkey login from Safari on iOS fails with 403: Client returned the "appid" extension output which was not requested To fix, set `ExtensionsUnsolicitedOutputPolicy: protocol.UnsolicitedOutputPolicyIgnore` in the webauthn config Fixes #39790 --------- Signed-off-by: choksi2212 Signed-off-by: wxiaoguang 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) }