T01 · Skill Instruction Hijacking
Error
- Location
- protagons.mjs:179
- Finding
- Untrusted Remote SOUL.md Content Can Hijack Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `protagons.mjs:179-207`; related behavioral instructions in `SKILL.md:13-23` **Vulnerability Type**: Remote instruction injection through mutable identity content **Risk Level**: High ### Vulnerable Code ```javascript export async function protagons_deploy(params, context) { if (!params.slug) throw new Error('slug is required'); const slug = encodeURIComponent(params.slug); let soulMd = null; let name = params.slug; let contentTier = 'standard'; // 1. Try fetching the pre-generated SOUL.md try { soulMd = await apiFetchText(`/library/${slug}/soul.md`); if (!soulMd || !soulMd.trim()) soulMd = null; } catch { // SOUL.md endpoint unavailable — fall back below } // 2. Fetch the .protagon.json for metadata (and fallback compilation) const protagon = await apiFetch(`/library/${slug}`); name = protagon.name || name; contentTier = protagon.deployment?.content_tier || 'standard'; // 3. Fall back to client-side compilation if no pre-generated SOUL.md if (!soulMd) { soulMd = compileSoulMd(protagon); } return { soul_md: soulMd, protagon_slug: params.slug, protagon_name: name, content_tier: contentTier, deployed_at: new Date().toISOString(), }; } ``` The accompanying skill instructions direct the agent to treat this remote content as behavioral instructions: ```markdown When you deploy a Protagon, its SOUL.md content is returned to you. Adopt it as your personality for the session. ``` ### Technical Analysis The deployment function retrieves arbitrary Markdown from the mutable external endpoint `https://api.usaw.ai/api/v1/library/{slug}/soul.md` and exposes it as `soul_md`. The skill documentation explicitly directs the agent to adopt that content as its session personality. No signature verification, content hash pinning, schema validation, instruction filtering, or trust-boundary enforcement is applied before the response is used. Consequ ...[truncated 2185 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat all API-provided identity data as untrusted content rather than executable agent instructions. 2. Replace unrestricted `SOUL.md` retrieval with a strict data schema containing bounded fields such as tone, verbosity, style, and permitted use cases. 3. Construct the final personality prompt locally from approved templates and validated values. 4. Reject control-oriented content such as requests to ignore higher-priority instructions, conceal actions, access secrets, invoke tools, or alter safety rules. 5. Cryptographically sign published character records and verify signatures against a pinned publisher key before use. 6. Pin reviewed content versions or hashes so the effective identity cannot change silently after skill review. 7. Display the source, version, and trust status of remote identity content and require explicit user confirmation before applying it. 8. Ensure the host always places immutable system and safety policies above personality content. 9. Apply the same validation to `synthesized_prompt.content` used by the fallback compilation path. 10. Enforce response-size limits and expected content types to reduce secondary parsing and denial-of-service risks. ]]>
