Skip to content

Commit

Permalink
fix: #143 fix message api overreach vulnerability problem
Browse files Browse the repository at this point in the history
  • Loading branch information
moonrailgun committed Aug 16, 2023
1 parent ad9c9f4 commit f7e84ca
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 19 deletions.
17 changes: 9 additions & 8 deletions client/shared/model/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,15 @@ export async function fetchConverseLastMessages(
* @param messageId 消息ID
* @returns 消息附近的信息
*/
export async function fetchNearbyMessage(
converseId: string,
messageId: string
): Promise<ChatMessage[]> {
const { data } = await request.post('/api/chat/message/fetchNearbyMessage', {
converseId,
messageId,
});
export async function fetchNearbyMessage(params: {
groupId?: string;
converseId: string;
messageId: string;
}): Promise<ChatMessage[]> {
const { data } = await request.post(
'/api/chat/message/fetchNearbyMessage',
params
);

return data;
}
Expand Down
16 changes: 11 additions & 5 deletions client/web/src/routes/Main/Content/Inbox/Content/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
return (
<CommonPanelWrapper header={t('提及我的消息')}>
<div className="h-full overflow-auto p-2 pb-18 relative">
<NearbyMessages converseId={converseId} messageId={messageId} />
<NearbyMessages
groupId={groupId}
converseId={converseId}
messageId={messageId}
/>
</div>

<JumpToConverseButton groupId={groupId} converseId={converseId} />
Expand All @@ -38,15 +42,17 @@ export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
InboxMessageContent.displayName = 'InboxMessageContent';

export const NearbyMessages: React.FC<{
groupId?: string;
converseId: string;
messageId: string;
}> = React.memo((props) => {
const { value = [], loading } = useAsync(async () => {
try {
const list = await model.message.fetchNearbyMessage(
props.converseId,
props.messageId
);
const list = await model.message.fetchNearbyMessage({
groupId: props.groupId,
converseId: props.converseId,
messageId: props.messageId,
});

return list;
} catch (err) {
Expand Down
2 changes: 2 additions & 0 deletions server/packages/sdk/src/structs/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ interface GroupMemberStruct {
roles?: string[]; // 角色

userId: string;

muteUntil?: string;
}

export interface GroupPanelStruct {
Expand Down
3 changes: 2 additions & 1 deletion server/services/core/chat/converse.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
UserStruct,
call,
DataNotFoundError,
NoPermissionError,
} from 'tailchat-server-sdk';
import type {
ConverseDocument,
Expand Down Expand Up @@ -225,7 +226,7 @@ class ConverseService extends TcService {

const memebers = converse.members ?? [];
if (!memebers.map((member) => String(member)).includes(userId)) {
throw new Error(t('没有获取会话信息权限'));
throw new NoPermissionError(t('没有获取会话信息权限'));
}

return await this.transformDocuments(ctx, {}, converse);
Expand Down
61 changes: 56 additions & 5 deletions server/services/core/chat/message.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
NoPermissionError,
call,
PERMISSION,
NotFoundError,
SYSTEM_USERID,
} from 'tailchat-server-sdk';
import type { Group } from '../../../models/group/group';
import { isValidStr } from '../../../lib/utils';
Expand All @@ -36,6 +38,7 @@ class MessageService extends TcService {
});
this.registerAction('fetchNearbyMessage', this.fetchNearbyMessage, {
params: {
groupId: { type: 'string', optional: true },
converseId: 'string',
messageId: 'string',
num: { type: 'number', optional: true },
Expand Down Expand Up @@ -109,13 +112,18 @@ class MessageService extends TcService {
*/
async fetchNearbyMessage(
ctx: TcContext<{
groupId?: string;
converseId: string;
messageId: string;
num?: number;
}>
) {
const { converseId, messageId, num = 5 } = ctx.params;
const { groupId, converseId, messageId, num = 5 } = ctx.params;
const { t } = ctx.meta;

// 鉴权是否能获取到会话内容
await this.checkConversePermission(ctx, converseId, groupId);

const message = await this.adapter.model
.findOne({
_id: new Types.ObjectId(messageId),
Expand Down Expand Up @@ -176,11 +184,10 @@ class MessageService extends TcService {
/**
* 鉴权
*/
await this.checkConversePermission(ctx, converseId, groupId); // 鉴权是否能获取到会话内容
if (isValidStr(groupId)) {
// 是群组消息
const groupInfo: Group = await ctx.call('group.getGroupInfo', {
groupId,
});
// 是群组消息, 鉴权是否禁言
const groupInfo = await call(ctx).getGroupInfo(groupId);
const member = groupInfo.members.find((m) => String(m.userId) === userId);
if (member) {
// 因为有机器人,所以如果没有在成员列表中找到不报错
Expand Down Expand Up @@ -441,6 +448,50 @@ class MessageService extends TcService {

return true;
}

/**
* 校验会话权限,如果没有抛出异常则视为正常
*/
private async checkConversePermission(
ctx: TcContext,
converseId: string,
groupId?: string
) {
const userId = ctx.meta.userId;
const t = ctx.meta.t;
if (userId === SYSTEM_USERID) {
return;
}

// 鉴权是否能获取到会话内容
if (groupId) {
// 是群组
const group = await call(ctx).getGroupInfo(groupId);
console.log('group.members', group.members, group);
if (group.members.findIndex((m) => String(m.userId) === userId) === -1) {
// 不存在该用户
throw new NoPermissionError(t('没有当前会话权限'));
}
} else {
// 是普通会话
const converse = await ctx.call<
any,
{
converseId: string;
}
>('chat.converse.findConverseInfo', {
converseId,
});

if (!converse) {
throw new NotFoundError(t('没有找到会话信息'));
}
const memebers = converse.members ?? [];
if (memebers.findIndex((member) => String(member) === userId) === -1) {
throw new NoPermissionError(t('没有当前会话权限'));
}
}
}
}

export default MessageService;

0 comments on commit f7e84ca

Please sign in to comment.