Tool description text is interpolated into the model prompt without provenance separation
- Synthetic scenario
- Synthetic scenario — invented for illustration. A fictional team runs an MCP server exposing four tools to a desktop assistant client. One tool's description field is assembled at runtime from a record in a third-party catalogue the team does not control.
- Observation
- Tool descriptions are passed to the model verbatim, in the same block as system guidance, with no delimiter or provenance marker distinguishing operator-authored text from text supplied by an external source. A description sourced from the third-party catalogue is therefore presented to the model with the same apparent authority as the server's own instructions.
- Evidence location
- Illustrative locations only: server/tools/registry.ts (description assembly), server/prompt/compose.ts (prompt block construction), and the capability listing captured during the initialize handshake. In a real pack each is cited with the exact line range and a captured request/response transcript with secrets redacted.
- Impact
- A party able to edit the upstream catalogue entry can introduce instruction-shaped text into the model's context. Depending on the client and the permissions granted to the session, that can influence which tools the model chooses to call and with what arguments — without any change to the server's own code or configuration.
- Severity rationale
- Rated high rather than critical: exploitation requires write access to the upstream catalogue, which is a meaningful barrier, and no tool in this synthetic scenario performs an irreversible action without a confirmation step. It is not medium, because the path requires no compromise of the server itself and would leave no trace in the server's own change history.
- Recommended action
- Separate provenance in the composed prompt: render externally sourced description text inside an explicitly delimited, clearly labelled block, and state in the operator-authored guidance that content in that block is untrusted data rather than instruction. Constrain description fields to a documented length and character set at ingest, and record the source of each description in the capability listing so it can be audited.
- Acceptance test
- With a catalogue entry whose description contains instruction-shaped text, the composed prompt places that text inside the untrusted-content delimiter, and the delimiter cannot be closed by any input accepted at ingest. Re-run the client interoperability suite against the named clients in scope; tool-selection behaviour is unchanged for all benign descriptions.
- Residual risk
- Provenance separation reduces the model's tendency to treat external text as instruction; it does not make prompt injection impossible, and no vendor can honestly claim that it does. The residual risk is recorded, owned by the platform team, and revisited when the client set or the tool permission model changes.
A real pack contains every finding in this format, ordered by severity, plus the scope statement, client verification record, residual-risk register, security and access record, and the methodology and limitations note. Nothing in a real pack is published anywhere: it goes to you.