mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-01-07 19:49:01 +08:00
feat: Add OB11GroupGrayTipEvent for detecting forged gray tip attacks (#1492)
* feat: Add OB11GroupGrayTipEvent for detecting forged gray tip attacks - Add new OB11GroupGrayTipEvent class to report unknown gray tip messages - Modify parseOtherJsonEvent to detect forged gray tips by checking senderUin - Real system gray tips have senderUin='0', forged ones expose attacker's QQ - Include message_id in event for downstream recall capability - Add try/catch for JSON.parse to handle malformed content - Use Number() for consistent type conversion * fix: simplify logWarn to match upstream style * fix: remove extra closing brace that broke class structure * fix: add validation for malformed title gray tip events
This commit is contained in:
parent
b241881c74
commit
2d3f4e696b
@ -19,6 +19,7 @@ import { OB11GroupCardEvent } from '@/napcat-onebot/event/notice/OB11GroupCardEv
|
|||||||
import { OB11GroupPokeEvent } from '@/napcat-onebot/event/notice/OB11PokeEvent';
|
import { OB11GroupPokeEvent } from '@/napcat-onebot/event/notice/OB11PokeEvent';
|
||||||
import { OB11GroupEssenceEvent } from '@/napcat-onebot/event/notice/OB11GroupEssenceEvent';
|
import { OB11GroupEssenceEvent } from '@/napcat-onebot/event/notice/OB11GroupEssenceEvent';
|
||||||
import { OB11GroupTitleEvent } from '@/napcat-onebot/event/notice/OB11GroupTitleEvent';
|
import { OB11GroupTitleEvent } from '@/napcat-onebot/event/notice/OB11GroupTitleEvent';
|
||||||
|
import { OB11GroupGrayTipEvent } from '@/napcat-onebot/event/notice/OB11GroupGrayTipEvent';
|
||||||
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
||||||
import { OB11GroupNameEvent } from '../event/notice/OB11GroupNameEvent';
|
import { OB11GroupNameEvent } from '../event/notice/OB11GroupNameEvent';
|
||||||
import { FileNapCatOneBotUUID } from 'napcat-common/src/file-uuid';
|
import { FileNapCatOneBotUUID } from 'napcat-common/src/file-uuid';
|
||||||
@ -206,15 +207,24 @@ export class OneBotGroupApi {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
async parseOtherJsonEvent (msg: RawMessage, jsonGrayTipElement: GrayTipElement['jsonGrayTipElement'], context: InstanceContext) {
|
||||||
async parseOtherJsonEvent (msg: RawMessage, jsonStr: string, context: InstanceContext) {
|
let json: { items?: { txt?: string; param?: string[] }[] };
|
||||||
const json = JSON.parse(jsonStr);
|
try {
|
||||||
const type = json.items[json.items.length - 1]?.txt;
|
json = JSON.parse(jsonGrayTipElement.jsonStr);
|
||||||
|
} catch (e) {
|
||||||
|
context.logger.logWarn('灰条消息JSON解析失败', jsonGrayTipElement.jsonStr, e);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const type = json.items?.[json.items.length - 1]?.txt;
|
||||||
await this.core.apis.GroupApi.refreshGroupMemberCachePartial(msg.peerUid, msg.senderUid);
|
await this.core.apis.GroupApi.refreshGroupMemberCachePartial(msg.peerUid, msg.senderUid);
|
||||||
if (type === '头衔') {
|
if (type === '头衔') {
|
||||||
const memberUin = json.items[1].param[0];
|
const memberUin = json.items?.[1]?.param?.[0];
|
||||||
const title = json.items[3].txt;
|
const title = json.items?.[3]?.txt;
|
||||||
context.logger.logDebug('收到群成员新头衔消息', json);
|
context.logger.logDebug('收到群成员新头衔消息', json);
|
||||||
|
if (memberUin == null || title == null) {
|
||||||
|
context.logger.logWarn('收到格式异常的群成员新头衔灰条消息', json);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
return new OB11GroupTitleEvent(
|
return new OB11GroupTitleEvent(
|
||||||
this.core,
|
this.core,
|
||||||
+msg.peerUid,
|
+msg.peerUid,
|
||||||
@ -225,6 +235,27 @@ export class OneBotGroupApi {
|
|||||||
context.logger.logDebug('收到机器人被踢消息', json);
|
context.logger.logDebug('收到机器人被踢消息', json);
|
||||||
} else {
|
} else {
|
||||||
context.logger.logWarn('收到未知的灰条消息', json);
|
context.logger.logWarn('收到未知的灰条消息', json);
|
||||||
|
|
||||||
|
// 如果有真实发送者(非0),生成事件上报,可用于检测和撤回伪造灰条
|
||||||
|
const senderUin = Number(msg.senderUin) || 0;
|
||||||
|
if (senderUin !== 0) {
|
||||||
|
const peer = { chatType: ChatType.KCHATTYPEGROUP, guildId: '', peerUid: msg.peerUid };
|
||||||
|
const messageId = MessageUnique.createUniqueMsgId(peer, msg.msgId);
|
||||||
|
return new OB11GroupGrayTipEvent(
|
||||||
|
this.core,
|
||||||
|
+msg.peerUin,
|
||||||
|
senderUin,
|
||||||
|
messageId,
|
||||||
|
jsonGrayTipElement.busiId,
|
||||||
|
jsonGrayTipElement.jsonStr,
|
||||||
|
{
|
||||||
|
msgSeq: msg.msgSeq,
|
||||||
|
msgTime: msg.msgTime,
|
||||||
|
msgId: msg.msgId,
|
||||||
|
json,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -376,7 +407,7 @@ export class OneBotGroupApi {
|
|||||||
return await this.parse51TypeEvent(msg, grayTipElement);
|
return await this.parse51TypeEvent(msg, grayTipElement);
|
||||||
} else {
|
} else {
|
||||||
console.log('Unknown JSON event:', grayTipElement.jsonGrayTipElement, JSON.stringify(grayTipElement));
|
console.log('Unknown JSON event:', grayTipElement.jsonGrayTipElement, JSON.stringify(grayTipElement));
|
||||||
return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context);
|
return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement, this.core.context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
35
packages/napcat-onebot/event/notice/OB11GroupGrayTipEvent.ts
Normal file
35
packages/napcat-onebot/event/notice/OB11GroupGrayTipEvent.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent';
|
||||||
|
import { NapCatCore } from 'napcat-core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群灰条消息事件
|
||||||
|
* 用于上报未知类型的灰条消息,便于下游检测和处理伪造灰条攻击
|
||||||
|
*/
|
||||||
|
export class OB11GroupGrayTipEvent extends OB11BaseNoticeEvent {
|
||||||
|
notice_type = 'notify';
|
||||||
|
sub_type = 'gray_tip';
|
||||||
|
group_id: number;
|
||||||
|
user_id: number; // 真实发送者QQ(如果是伪造的灰条,这就是攻击者)
|
||||||
|
message_id: number; // 消息ID,可用于撤回
|
||||||
|
busi_id: string; // 业务ID
|
||||||
|
content: string; // 灰条内容(JSON字符串)
|
||||||
|
raw_info: unknown; // 原始信息
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
core: NapCatCore,
|
||||||
|
groupId: number,
|
||||||
|
userId: number,
|
||||||
|
messageId: number,
|
||||||
|
busiId: string,
|
||||||
|
content: string,
|
||||||
|
rawInfo: unknown
|
||||||
|
) {
|
||||||
|
super(core);
|
||||||
|
this.group_id = groupId;
|
||||||
|
this.user_id = userId;
|
||||||
|
this.message_id = messageId;
|
||||||
|
this.busi_id = busiId;
|
||||||
|
this.content = content;
|
||||||
|
this.raw_info = rawInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user