Skip to content

fix(minimax-bot): 进入下一个 Bot 提示词的文本都先洗过,宿主标签和伪造标记进不去 - #94

Merged
MyPrototypeWhat merged 1 commit into
MiniMax-AI:mainfrom
Apageoflove:fix/minimax-bot-prompt-laundering
Oct 29, 2026
Merged

MyPrototypeWhat merged 1 commit into
MiniMax-AI:mainfrom
Apageoflove:fix/minimax-bot-prompt-laundering

Conversation

@Apageoflove

@Apageoflove Apageoflove commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

上一条 PR(#91)挡住了插件自己的协议标记,但还有四条路没堵:宿主自己写在提示词里的标签(system-reminder、agent-context 这一套)不在插件的标记表里,Bot 抄一句进回话,它就一路洗进下一个 Bot 的提示词;标记的两种写法能绕过——中间夹一个不占位的字符(零宽空格、方向标记、组合重音),或者闭标签带一个很长的属性;后台任务的简报里 Bot 的名字、角色和任务标题是原样拼进去的,名字里带一个闭标记,简报块就被提前关掉;子 Bot 的结果报告直接拼进父 Bot 的验收提示词,中间不洗,子 Bot 能在那里伪造一段像是插件写的上下文块。
四条都在未改的上游代码上用探针复现:宿主标签经群历史、交接块、记忆三条通道进下一个 Bot 的提示词,并且能活过三跳;零宽字符写法和 60 字符属性都能绕过;名字里带闭标记时简报块的闭合标签出现三次而不是一次;子 Bot 的报告里写一段上下文标记,就到了父 Bot 的提示词里。新增的四个测试文件在未改的上游代码上是红的,在这版上是绿的;插件自带套件 307 条全过,上游 npm run check 两半也过。
改法有四处。标记的属性段现在只由标签属性的字符组成,没有这种属性时只取标记名本身——这样 300 字符的属性照样拿掉,而 Bot 正文里一个 minimax-bot-context 不会把到下一个尖括号之间的内容一起吃掉(改之前实测吃掉几十个字符,基线是 0)。宿主标签用同一套规则处理。简报里 Bot 的名字和角色、任务标题、结果报告与出错信息,进提示词之前都先过一遍同样的清洗。插件自己的交付格式 media src 不动,报告里点名的文件照样交得出去。
真实对话里也验过:写手真的把宿主标签抄进了回话(回话第一行就是那个标签加一个独特载荷),下一个 Bot 的提示词里这一段对照版 2 条命中、这版 0 条;写手指令里那个带 60 字符属性的闭标记,对照版进了下一个 Bot 的提示词(1 条),这版没有;对照版还有一条提示词的上下文闭标签不止一个,这版每条都恰好一个。后台任务简报里那个闭标记,在这版的后台任务简报里只闭合了一次;对照那一次的后台任务没有跑起来,所以这条只留协议层的证据。这一版只处理插件自己拼进提示词的文本;宿主自己往提示词里塞的标签、以及模型在函数调用之外自己造出来的结构,不在这条的范围内,需要确认上游的期望。


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@MyPrototypeWhat MyPrototypeWhat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. Approving. I checked out c25e97e and ran the checks.

  • npm run check at the repo root: 87 pass, 0 fail (same as main).
  • node --test tests/*.test.mjs in plugins/minimax-ai/minimax-bot (node 22, jsdom installed): 307 tests, 303 pass, 4 fail. The 4 failures (1 reactions, 3 emoji picker) fail the same way on main at 45a5c6e, so this PR adds no new failures. The 28 new tests all pass.
  • Every change stays inside the plugin folder, and the new tests are in the plugin's own tests/ directory. No CI, .github or root test files are touched.

Nothing blocks merging. The sanitizing only removes the tag itself and leaves the text around it alone. Plain prose like a < b and c > d, CJK text and <media src="…" /> all come through unchanged in my checks. The offset mapping from the folded text back to the original is correct, so the original text is never rewritten. Running clean() / neutralizeMarks on text that has already been cleaned is harmless.

Optional follow-ups:

  1. Astral invisible characters are not skipped. foldMarks walks the string one UTF-16 code unit at a time, so \p{Cf}/\p{Mn} never match characters outside the BMP: tag characters (U+E0000 block) and the supplementary variation selectors (U+E0100 block). For example, </minimax-bot\u{E0020}-context> comes back unchanged, while the U+200B version is caught. Iterating by code point (for (const char of text) and recording the start index of each code point) would fix this.
  2. Lookalike angle brackets (for example U+FE64/U+FE65 ﹤﹥) and Cyrillic/Greek homoglyphs in the tag name are not folded. A model is less likely to read those as real tags, so this is defense in depth only.
  3. The README and the code comments name specific tag names that are not the plugin's own. Consider describing them generically ("reserved block tags that are not part of the plugin's format"), and keep the list in code only.
  4. Version: this bumps to 0.7.14, and #95 bumps straight to 0.7.15, so the two are already sequenced with this one first. If they merge in that order, #95 only needs a rebase for the version lines and the neighboring README sections.

@MyPrototypeWhat
MyPrototypeWhat merged commit 1aa1679 into MiniMax-AI:main Oct 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants