From fcf0f5f6b52efc9d7c42d4968de5590554b042f9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 9 Dec 2023 12:58:00 +0900 Subject: [PATCH] fix(frontend): disable Mk:apiExternal --- CHANGELOG.md | 1 + packages/frontend/src/os.ts | 4 +- packages/frontend/src/scripts/aiscript/api.ts | 2 + packages/frontend/src/scripts/api.ts | 48 ------------------- 4 files changed, 5 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7352db8fa..c7ee4b038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - Fix: 共有機能をサポートしていないブラウザの場合は共有ボタンを非表示にする #11305 - Fix: 通知のグルーピング設定を変更してもリロードされるまで表示が変わらない問題を修正 #12470 - Fix: 長い名前のチャンネルにおける投稿フォームの表示が崩れる問題を修正 +- Fix: セキュリティ向上のためAiScriptの`Mk:apiExternal`を無効化 ### Server - Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 8093335a2..8aed5797e 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -5,8 +5,8 @@ // TODO: なんでもかんでもos.tsに突っ込むのやめたいのでよしなに分割する -import { pendingApiRequestsCount, api, apiExternal, apiGet } from '@/scripts/api.js'; -export { pendingApiRequestsCount, api, apiExternal, apiGet }; +import { pendingApiRequestsCount, api, apiGet } from '@/scripts/api.js'; +export { pendingApiRequestsCount, api, apiGet }; import { Component, markRaw, Ref, ref, defineAsyncComponent } from 'vue'; import { EventEmitter } from 'eventemitter3'; import insertTextAtCursor from 'insert-text-at-cursor'; diff --git a/packages/frontend/src/scripts/aiscript/api.ts b/packages/frontend/src/scripts/aiscript/api.ts index fb7ab924b..038ae2310 100644 --- a/packages/frontend/src/scripts/aiscript/api.ts +++ b/packages/frontend/src/scripts/aiscript/api.ts @@ -50,6 +50,7 @@ export function createAiScriptEnv(opts) { return values.ERROR('request_failed', utils.jsToVal(err)); }); }), + /* セキュリティ上の問題があるため無効化 'Mk:apiExternal': values.FN_NATIVE(async ([host, ep, param, token]) => { utils.assertString(host); utils.assertString(ep); @@ -60,6 +61,7 @@ export function createAiScriptEnv(opts) { return values.ERROR('request_failed', utils.jsToVal(err)); }); }), + */ 'Mk:save': values.FN_NATIVE(([key, value]) => { utils.assertString(key); miLocalStorage.setItem(`aiscript:${opts.storageKey}:${key.value}`, JSON.stringify(utils.valToJs(value))); diff --git a/packages/frontend/src/scripts/api.ts b/packages/frontend/src/scripts/api.ts index 0f54f779a..8f3a16393 100644 --- a/packages/frontend/src/scripts/api.ts +++ b/packages/frontend/src/scripts/api.ts @@ -56,54 +56,6 @@ export function api( - hostUrl: string, - endpoint: E, data: P = {} as any, - token?: string | null | undefined, - signal?: AbortSignal, -): Promise> { - if (!/^https?:\/\//.test(hostUrl)) throw new Error('invalid host name'); - if (endpoint.includes('://')) throw new Error('invalid endpoint'); - pendingApiRequestsCount.value++; - - const onFinally = () => { - pendingApiRequestsCount.value--; - }; - - const promise = new Promise((resolve, reject) => { - // Append a credential - (data as any).i = token; - - const fullUrl = (hostUrl.slice(-1) === '/' ? hostUrl.slice(0, -1) : hostUrl) - + '/api/' + (endpoint.slice(0, 1) === '/' ? endpoint.slice(1) : endpoint); - // Send request - window.fetch(fullUrl, { - method: 'POST', - body: JSON.stringify(data), - credentials: 'omit', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - signal, - }).then(async (res) => { - const body = res.status === 204 ? null : await res.json(); - - if (res.status === 200) { - resolve(body); - } else if (res.status === 204) { - resolve(); - } else { - reject(body.error); - } - }).catch(reject); - }); - - promise.then(onFinally, onFinally); - - return promise; -} - // Implements Misskey.api.ApiClient.request export function apiGet( endpoint: E,