fix(security): 人格檔案不能逸出注入區塊、room 台詞不能偽造成系統訊息(S6)
注入到上下文的東西夾在 persona-runtime / persona-context / persona-ops 三種區塊 中間,而夾進去的內容有**不可信來源**:persona-anime 從 Fandom 抓設定寫進 IDENTITY/AGENTS、`sync pull` 從另一台機器拉、`import` 吃外部 bundle、 guest 的 room 台詞是別的人格寫的。原本這些地方**沒有任何跳脫**: - AGENTS.md 裡放一行結束標記 → opsBrief 的區塊提早關閉,後面的內容跑到區塊外, 連外層的 runtime 區塊都能一起關掉。 - IDENTITY.md 的 `Vibe:` 欄位值同理,經 identityBrief 進 turnContext。 - room 台詞塞換行 → roomScript 是一行一句「emoji 名字(情緒):內容」, 於是可以偽造成別人的台詞或系統訊息。 修法: - 新增 `stripInjectionMarkers()`:把 `<persona-…` 的 `<` 換成全形。內容還讀得懂 (人格自己寫的說明不會被吃掉),但它不再是一個標籤。 - 新增 `injectSafeLine()`:中和標記 + 換行壓成空白(比照短期記憶的作法)。 - 一個收口勝過十幾個防點:`turnContext()` 與 SessionStart 的 runtime 區塊都改成 **組完之後對整個內文**做一次,再補上真正的標記;只有 turnContext/opsBrief 這種自己已處理過、帶合法巢狀標記的整塊原樣保留。 - 讀出來就中和的:`opsBrief()` 的 AGENTS.md 全文(先截斷再中和,長度上限才算得準)、 `identityFields()` 的欄位值(identityBrief/roomScript/roomDisplayName 全吃這一份)、 `relationsBrief()` 的人名與備註。 - room:`roomPost()` 在**寫入端**就把 text/emotion/barge_in 壓成一行, `roomScript()` 與 `room read` 在**顯示端**再壓一次(舊逐字稿是原文寫進去的)。 測試:新增 14 項——AGENTS.md 與 IDENTITY 欄位的逸出、turnContext 與 SessionStart 的區塊只被關閉一次、短期記憶與關係圖人名走同一個收口、room 台詞的換行偽造與 標記逸出、舊逐字稿的顯示端防線、顯示名不夾帶標記。 反向驗證:把兩個中和函式改成 identity,這 14 項全數失敗。 368 → 383 項全過。
This commit is contained in:
+4
-1
@@ -1436,9 +1436,12 @@ commands.room = ({ flags, positional }) => {
|
||||
const rows = pl.roomRead(room, num(flags.limit, 30));
|
||||
const meta = pl.readJson(pl.roomMembersPath(room), {}) ?? {};
|
||||
const lines = [`聊天室 \`${room}\`|成員 ${(meta.members || []).join(", ")}|主題 ${meta.topic || "-"}`];
|
||||
// 一行一句的排版:台詞是別的人格寫的,換行與注入標記在這裡也要壓掉
|
||||
// (`roomPost` 已在寫入端處理,這是給舊逐字稿的第二道)。
|
||||
for (const row of rows) {
|
||||
const arrow = row.to && row.to !== pl.ROOM_ALL && row.to !== row.speaker ? ` → ${row.to}` : "";
|
||||
lines.push(`[${row.ts}] ${row.speaker}${row.emotion ? `(${row.emotion})` : ""}${arrow}:${row.text}`);
|
||||
const emotion = pl.injectSafeLine(row.emotion);
|
||||
lines.push(`[${row.ts}] ${row.speaker}${emotion ? `(${emotion})` : ""}${arrow}:${pl.injectSafeLine(row.text)}`);
|
||||
}
|
||||
emit({ room, meta, messages: rows }, flags.json, lines);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user