Skip to content

Commit c96bc36

Browse files
Merge pull request from GHSA-7pxq-6xx9-xpgm
* fix: fix improper authorization when accessing with third-party application * refactor: refactor type definitions * fix: get rid of unnecessary access limitation * enhance: サードパーティアプリケーションがWebsocket APIを使えるように * fix: add missing parentheses * Revert "fix(backend): add missing kind definition for admin endpoints to improve security" This reverts commit 5150053. * frontend: 翻訳の抜けを訂正, read:adminとwrite:adminはアクセス発行トークンのデフォルトでは非表示にする * enhance(test): misskey-GHSA-7pxq-6xx9-xpgmに関するテストを追加 * enhance(test): Websocket APIに対するテストも追加 * enhance(refactor): `@/misc/api-permissions.ts`を`misskey-js/permissions`に統合 * fix(frontend): アクセストークン発行UIで全ての権限を有効にした際、管理者用APIへのアクセスも許可してしまう問題を修正 * enhance(backend): Websocketの接続に最低限必要な権限を変更 * fix(backend): `/api/admin/meta`をサードパーティアプリケーションからはアクセスできないように * fix(backend): エンドポイントにアクセスするために必要な権限を変更 * fix(frontend/locale): Add missing type declaration * chore: update `misskey-js/src/autogen` --------- Co-authored-by: tamaina <tamaina@hotmail.co.jp>
1 parent d87fecd commit c96bc36

File tree

148 files changed

+797
-581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+797
-581
lines changed

Diff for: CHANGELOG.md

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@
132132
- Fix: モデレーションログがモデレーターは閲覧できないように修正
133133
- Fix: ハッシュタグのトレンド除外設定が即時に効果を持つように修正
134134
- Fix: HTTP Digestヘッダのアルゴリズム部分に大文字の"SHA-256"しか使えない
135-
- Fix: 管理者用APIのアクセス権限が適切に設定されていない問題を修正
136135

137136
## 2023.11.1
138137

Diff for: locales/index.d.ts

+49
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,55 @@ export interface Locale {
20662066
"write:flash": string;
20672067
"read:flash-likes": string;
20682068
"write:flash-likes": string;
2069+
"read:admin:abuse-user-reports": string;
2070+
"write:admin:delete-account": string;
2071+
"write:admin:delete-all-files-of-a-user": string;
2072+
"read:admin:index-stats": string;
2073+
"read:admin:table-stats": string;
2074+
"read:admin:user-ips": string;
2075+
"read:admin:meta": string;
2076+
"write:admin:reset-password": string;
2077+
"write:admin:resolve-abuse-user-report": string;
2078+
"write:admin:send-email": string;
2079+
"read:admin:server-info": string;
2080+
"read:admin:show-moderation-log": string;
2081+
"read:admin:show-user": string;
2082+
"read:admin:show-users": string;
2083+
"write:admin:suspend-user": string;
2084+
"write:admin:unset-user-avatar": string;
2085+
"write:admin:unset-user-banner": string;
2086+
"write:admin:unsuspend-user": string;
2087+
"write:admin:meta": string;
2088+
"write:admin:user-note": string;
2089+
"write:admin:roles": string;
2090+
"read:admin:roles": string;
2091+
"write:admin:relays": string;
2092+
"read:admin:relays": string;
2093+
"write:admin:invite-codes": string;
2094+
"read:admin:invite-codes": string;
2095+
"write:admin:announcements": string;
2096+
"read:admin:announcements": string;
2097+
"write:admin:avatar-decorations": string;
2098+
"read:admin:avatar-decorations": string;
2099+
"write:admin:federation": string;
2100+
"write:admin:account": string;
2101+
"read:admin:account": string;
2102+
"write:admin:emoji": string;
2103+
"read:admin:emoji": string;
2104+
"write:admin:queue": string;
2105+
"read:admin:queue": string;
2106+
"write:admin:promo": string;
2107+
"write:admin:drive": string;
2108+
"read:admin:drive": string;
2109+
"read:admin:stream": string;
2110+
"write:admin:ad": string;
2111+
"read:admin:ad": string;
2112+
"write:invite-codes": string;
2113+
"read:invite-codes": string;
2114+
"write:clip-favorite": string;
2115+
"read:clip-favorite": string;
2116+
"read:federation": string;
2117+
"write:report-abuse": string;
20692118
};
20702119
"_auth": {
20712120
"shareAccessTitle": string;

Diff for: locales/ja-JP.yml

+49
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,55 @@ _permissions:
19711971
"write:flash": "Playを操作する"
19721972
"read:flash-likes": "Playのいいねを見る"
19731973
"write:flash-likes": "Playのいいねを操作する"
1974+
"read:admin:abuse-user-reports": "ユーザーからの通報を見る"
1975+
"write:admin:delete-account": "ユーザーアカウントを削除する"
1976+
"write:admin:delete-all-files-of-a-user": "ユーザーのすべてのファイルを削除する"
1977+
"read:admin:index-stats": "データベースインデックスに関する情報を見る"
1978+
"read:admin:table-stats": "データベーステーブルに関する情報を見る"
1979+
"read:admin:user-ips": "ユーザーのIPアドレスを見る"
1980+
"read:admin:meta": "インスタンスのメタデータを見る"
1981+
"write:admin:reset-password": "ユーザーのパスワードをリセットする"
1982+
"write:admin:resolve-abuse-user-report": "ユーザーからの通報を解決する"
1983+
"write:admin:send-email": "メールを送る"
1984+
"read:admin:server-info": "サーバーの情報を見る"
1985+
"read:admin:show-moderation-log": "モデレーションログを見る"
1986+
"read:admin:show-user": "ユーザーのプライベートな情報を見る"
1987+
"read:admin:show-users": "ユーザーのプライベートな情報を見る"
1988+
"write:admin:suspend-user": "ユーザーを凍結する"
1989+
"write:admin:unset-user-avatar": "ユーザーのアバターを削除する"
1990+
"write:admin:unset-user-banner": "ユーザーのバーナーを削除する"
1991+
"write:admin:unsuspend-user": "ユーザーの凍結を解除する"
1992+
"write:admin:meta": "インスタンスのメタデータを操作する"
1993+
"write:admin:user-note": "モデレーションノートを操作する"
1994+
"write:admin:roles": "ロールを操作する"
1995+
"read:admin:roles": "ロールを見る"
1996+
"write:admin:relays": "リレーを操作する"
1997+
"read:admin:relays": "リレーを見る"
1998+
"write:admin:invite-codes": "招待コードを操作する"
1999+
"read:admin:invite-codes": "招待コードを見る"
2000+
"write:admin:announcements": "お知らせを操作する"
2001+
"read:admin:announcements": "お知らせを見る"
2002+
"write:admin:avatar-decorations": "アバターデコレーションを操作する"
2003+
"read:admin:avatar-decorations": "アバターデコレーションを見る"
2004+
"write:admin:federation": "連合に関する情報を操作する"
2005+
"write:admin:account": "ユーザーアカウントを操作する"
2006+
"read:admin:account": "ユーザーに関する情報を見る"
2007+
"write:admin:emoji": "絵文字を操作する"
2008+
"read:admin:emoji": "絵文字を見る"
2009+
"write:admin:queue": "ジョブキューを操作する"
2010+
"read:admin:queue": "ジョブキューに関する情報を見る"
2011+
"write:admin:promo": "プロモーションノートを操作する"
2012+
"write:admin:drive": "ユーザーのドライブを操作する"
2013+
"read:admin:drive": "ユーザーのドライブの関する情報を見る"
2014+
"read:admin:stream": "管理者用のWebsocket APIを使う"
2015+
"write:admin:ad": "広告を操作する"
2016+
"read:admin:ad": "広告を見る"
2017+
"write:invite-codes": "招待コードを作成する"
2018+
"read:invite-codes": "招待コードを取得する"
2019+
"write:clip-favorite": "クリップのいいねを操作する"
2020+
"read:clip-favorite": "クリップのいいねを見る"
2021+
"read:federation": "連合に関する情報を取得する"
2022+
"write:report-abuse": "違反を報告する"
19742023

19752024
_auth:
19762025
shareAccessTitle: "アプリへのアクセス許可"

Diff for: packages/backend/src/misc/api-permissions.ts

-40
This file was deleted.

Diff for: packages/backend/src/server/api/ApiCallService.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ export class ApiCallService implements OnApplicationShutdown {
330330
}
331331
}
332332

333-
if (token && ep.meta.kind && !token.permission.some(p => p === ep.meta.kind)) {
333+
if (token && ((ep.meta.kind && !token.permission.some(p => p === ep.meta.kind))
334+
|| (!ep.meta.kind && (ep.meta.requireCredential || ep.meta.requireModerator || ep.meta.requireAdmin)))) {
334335
throw new ApiError({
335336
message: 'Your app does not have the necessary permissions to use this endpoint.',
336337
code: 'PERMISSION_DENIED',

Diff for: packages/backend/src/server/api/StreamingApiServerService.ts

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ export class StreamingApiServerService {
7171

7272
try {
7373
[user, app] = await this.authenticateService.authenticate(token);
74+
75+
if (app !== null && !app.permission.some(p => p === 'read:account')) {
76+
throw new AuthenticationError('Your app does not have necessary permissions to use websocket API.');
77+
}
7478
} catch (e) {
7579
if (e instanceof AuthenticationError) {
7680
socket.write([

Diff for: packages/backend/src/server/api/endpoints.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import type { Schema } from '@/misc/json-schema.js';
7+
import { permissions } from 'misskey-js';
78
import { RolePolicies } from '@/core/RoleService.js';
89

910
import * as ep___admin_meta from './endpoints/admin/meta.js';
@@ -724,7 +725,7 @@ const eps = [
724725
['retention', ep___retention],
725726
];
726727

727-
export interface IEndpointMeta {
728+
interface IEndpointMetaBase {
728729
readonly stability?: 'deprecated' | 'experimental' | 'stable';
729730

730731
readonly tags?: ReadonlyArray<string>;
@@ -823,6 +824,23 @@ export interface IEndpointMeta {
823824
readonly cacheSec?: number;
824825
}
825826

827+
export type IEndpointMeta = (Omit<IEndpointMetaBase, 'requireCrential' | 'requireModerator' | 'requireAdmin'> & {
828+
requireCredential?: false,
829+
requireAdmin?: false,
830+
requireModerator?: false,
831+
}) | (Omit<IEndpointMetaBase, 'secure'> & {
832+
secure: true,
833+
}) | (Omit<IEndpointMetaBase, 'requireCredential' | 'kind'> & {
834+
requireCredential: true,
835+
kind: (typeof permissions)[number],
836+
}) | (Omit<IEndpointMetaBase, 'requireModerator' | 'kind'> & {
837+
requireModerator: true,
838+
kind: (typeof permissions)[number],
839+
}) | (Omit<IEndpointMetaBase, 'requireAdmin' | 'kind'> & {
840+
requireAdmin: true,
841+
kind: (typeof permissions)[number],
842+
})
843+
826844
export interface IEndpoint {
827845
name: string;
828846
meta: IEndpointMeta;

Diff for: packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEnt
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'read:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'read:admin:abuse-user-reports',
2019

2120
res: {
2221
type: 'array',

Diff for: packages/backend/src/server/api/endpoints/admin/accounts/create.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { DI } from '@/di-symbols.js';
1515
export const meta = {
1616
tags: ['admin'],
1717

18-
kind: 'write:admin',
18+
secure: true,
1919

2020
res: {
2121
type: 'object',

Diff for: packages/backend/src/server/api/endpoints/admin/accounts/delete.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
1414
export const meta = {
1515
tags: ['admin'],
1616

17-
kind: 'write:admin',
18-
1917
requireCredential: true,
2018
requireAdmin: true,
19+
kind: 'write:admin:account',
2120
} as const;
2221

2322
export const paramDef = {

Diff for: packages/backend/src/server/api/endpoints/admin/accounts/find-by-email.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ApiError } from '@/server/api/error.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'read:admin',
17-
1816
requireCredential: true,
1917
requireAdmin: true,
18+
kind: 'read:admin:account',
2019

2120
errors: {
2221
userNotFound: {

Diff for: packages/backend/src/server/api/endpoints/admin/ad/create.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'write:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'write:admin:ad',
2019
res: {
2120
type: 'object',
2221
optional: false,

Diff for: packages/backend/src/server/api/endpoints/admin/ad/delete.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ApiError } from '../../../error.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'write:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'write:admin:ad',
2019

2120
errors: {
2221
noSuchAd: {

Diff for: packages/backend/src/server/api/endpoints/admin/ad/list.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ import { DI } from '@/di-symbols.js';
1212
export const meta = {
1313
tags: ['admin'],
1414

15-
kind: 'read:admin',
16-
1715
requireCredential: true,
1816
requireModerator: true,
17+
kind: 'read:admin:ad',
1918
res: {
2019
type: 'array',
2120
optional: false,

Diff for: packages/backend/src/server/api/endpoints/admin/ad/update.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ApiError } from '../../../error.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'write:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'write:admin:ad',
2019

2120
errors: {
2221
noSuchAd: {

Diff for: packages/backend/src/server/api/endpoints/admin/announcements/create.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import { AnnouncementService } from '@/core/AnnouncementService.js';
1010
export const meta = {
1111
tags: ['admin'],
1212

13-
kind: 'write:admin',
14-
1513
requireCredential: true,
1614
requireModerator: true,
15+
kind: 'write:admin:announcements',
1716

1817
res: {
1918
type: 'object',

Diff for: packages/backend/src/server/api/endpoints/admin/announcements/delete.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ApiError } from '../../../error.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'write:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'write:admin:announcements',
2019

2120
errors: {
2221
noSuchAnnouncement: {

Diff for: packages/backend/src/server/api/endpoints/admin/announcements/list.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ import { IdService } from '@/core/IdService.js';
1414
export const meta = {
1515
tags: ['admin'],
1616

17-
kind: 'read:admin',
18-
1917
requireCredential: true,
2018
requireModerator: true,
19+
kind: 'read:admin:announcements',
2120

2221
res: {
2322
type: 'array',

Diff for: packages/backend/src/server/api/endpoints/admin/announcements/update.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import { ApiError } from '../../../error.js';
1313
export const meta = {
1414
tags: ['admin'],
1515

16-
kind: 'write:admin',
17-
1816
requireCredential: true,
1917
requireModerator: true,
18+
kind: 'write:admin:announcements',
2019

2120
errors: {
2221
noSuchAnnouncement: {

Diff for: packages/backend/src/server/api/endpoints/admin/avatar-decorations/create.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
1010
export const meta = {
1111
tags: ['admin'],
1212

13-
kind: 'write:admin',
14-
1513
requireCredential: true,
1614
requireRolePolicy: 'canManageAvatarDecorations',
15+
kind: 'write:admin:avatar-decorations',
1716
} as const;
1817

1918
export const paramDef = {

Diff for: packages/backend/src/server/api/endpoints/admin/avatar-decorations/delete.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ import { ApiError } from '../../../error.js';
1212
export const meta = {
1313
tags: ['admin'],
1414

15-
kind: 'write:admin',
16-
1715
requireCredential: true,
1816
requireRolePolicy: 'canManageAvatarDecorations',
17+
kind: 'write:admin:avatar-decorations',
1918
errors: {
2019
},
2120
} as const;

Diff for: packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
1515
export const meta = {
1616
tags: ['admin'],
1717

18-
kind: 'read:admin',
19-
2018
requireCredential: true,
2119
requireRolePolicy: 'canManageAvatarDecorations',
20+
kind: 'read:admin:avatar-decorations',
2221

2322
res: {
2423
type: 'array',

0 commit comments

Comments
 (0)