From 63004e4f0f956d3228e67105022d0ffcc11c097c Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 9 Feb 2022 07:37:58 +0000 Subject: [PATCH] Prevent security failure due to bad APP_ID (#18678) Backport #18678 WebAuthn may cause a security exception if the provided APP_ID is not allowed for the current origin. Therefore we should reattempt authentication without the appid extension. Also we should allow [u2f] as-well as [U2F] sections. Signed-off-by: Andrew Thornton Co-authored-by: Lunny Xiao --- modules/setting/setting.go | 10 +++++++--- web_src/js/features/user-auth-webauthn.js | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index abd6716c74e6e..3b21bcc768a2a 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -1022,8 +1022,13 @@ func loadFromConf(allowEmpty bool, extraConfig string) { UI.CustomEmojisMap[emoji] = ":" + emoji + ":" } - sec = Cfg.Section("U2F") - U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/")) + // FIXME: DEPRECATED to be removed in v1.18.0 + U2F.AppID = strings.TrimSuffix(AppURL, "/") + if Cfg.Section("U2F").HasKey("APP_ID") { + U2F.AppID = Cfg.Section("U2F").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/")) + } else if Cfg.Section("u2f").HasKey("APP_ID") { + U2F.AppID = Cfg.Section("u2f").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/")) + } } func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) { @@ -1162,7 +1167,6 @@ func MakeManifestData(appName, appURL, absoluteAssetURL string) []byte { }, }, }) - if err != nil { log.Error("unable to marshal manifest JSON. Error: %v", err) return make([]byte, 0) diff --git a/web_src/js/features/user-auth-webauthn.js b/web_src/js/features/user-auth-webauthn.js index cf60535d404d7..1c774d6b1d97e 100644 --- a/web_src/js/features/user-auth-webauthn.js +++ b/web_src/js/features/user-auth-webauthn.js @@ -24,6 +24,19 @@ export function initUserAuthWebAuthn() { .then((credential) => { verifyAssertion(credential); }).catch((err) => { + // Try again... without the appid + if (makeAssertionOptions.publicKey.extensions && makeAssertionOptions.publicKey.extensions.appid) { + delete makeAssertionOptions.publicKey.extensions['appid']; + navigator.credentials.get({ + publicKey: makeAssertionOptions.publicKey + }) + .then((credential) => { + verifyAssertion(credential); + }).catch((err) => { + webAuthnError('general', err.message); + }); + return; + } webAuthnError('general', err.message); }); }).fail(() => {