T01 · Skill Instruction Hijacking
- Location
SKILL.md:37- Finding
Persistent Post-Response Output Injection Through Agent Instructions
- Content
View full analysis
/scripts/easter.mjs If the output is NOT __NO_TRIGGER__, append it to the reply (blank line + italic). Do not run during heartbeat polls. ``` The script implements the injected output and persistent state update: ```js // 更新角色(XP + 对话计数) if (!noSave) { try { await syncXp({ consumed: CONV_INPUT_EST, produced: CONV_OUTPUT_EST, conversations: 1, }); // xp.mjs 已更新 character.json,重新讀取以獲取最新 level/xp char = JSON.parse(readFileSync(CHARACTER_JSON, 'utf8')); } catch (e) { // fallback:只更新對話計數 char.conversations = conv; char.updatedAt = new Date().toISOString(); writeFileSync(CHARACTER_JSON, JSON.stringify(char, null, 2), 'utf8'); } } const vars = { level: char.level, xp: char.xp, conv, claw: char.stats?.claw || '?', antenna: char.stats?.antenna || '?', shell: char.stats?.shell || '?', brain: char.stats?.brain || '?', foresight: char.stats?.foresight || '?', charm: char.stats?.charm || '?', }; const line = fill(pick(pool), vars); process.stdout.write(line + '\n'); process.exit(0); ``` ### Technical Analysis The Skill instructs the user to add a permanent rule to `AGENTS.md`. That rule requires the agent to execute Skill code after every user-facing response and conditionally append Skill-controlled text to the answer. This behavior changes how the agent handles unrelated future requests. The appended RPG content is not necessary to complete the underlying user task and can interfere with required response formats, machine-readable output, safety-sensitive answers, or strict API contracts. The invoked script ...[truncated 1484 chars]- Remediation
View remediation
