From 70fe23a3ce8a37b9a848c2da80c0a84cf8f559bf Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 9 Feb 2023 18:01:12 +0900 Subject: [PATCH] fix(client): validate url to improve security --- packages/frontend/src/pages/auth.vue | 2 ++ packages/frontend/src/pages/miauth.vue | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/auth.vue b/packages/frontend/src/pages/auth.vue index bb55881a2..b7727ca30 100644 --- a/packages/frontend/src/pages/auth.vue +++ b/packages/frontend/src/pages/auth.vue @@ -77,6 +77,8 @@ export default defineComponent({ accepted() { this.state = 'accepted'; if (this.session.app.callbackUrl) { + const url = new URL(this.session.app.callbackUrl); + if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url'); location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`; } }, onLogin(res) { diff --git a/packages/frontend/src/pages/miauth.vue b/packages/frontend/src/pages/miauth.vue index 3debaeeb6..9a4019e5b 100644 --- a/packages/frontend/src/pages/miauth.vue +++ b/packages/frontend/src/pages/miauth.vue @@ -70,7 +70,7 @@ async function accept(): Promise { state = 'accepted'; if (props.callback) { const cbUrl = new URL(props.callback); - if (!['http:', 'https:'].includes(cbUrl.protocol)) throw new Error('invalid url'); + if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(cbUrl.protocol)) throw new Error('invalid url'); cbUrl.searchParams.set('session', props.session); location.href = cbUrl.href; }