Wiki source code of Write Tools Risk

Last modified by superadmin on 2026/10/14 18:44

Show last authors
1 Detailed explanation of the security implications of enabling the MCP server's write tools. Eight tools are write tools: ##edit_document##, ##write_document##, ##delete_document##, ##write_attachment##, ##delete_attachment##, ##write_object##, ##delete_object## and ##write_schema##.
2
3 == Script execution risk ==
4
5 Content an agent saves has the user of the MCP Server as its content author. If that content contains {{code language="none"}}{{groovy}}{{/code}} or {{code language="none"}}{{velocity}}{{/code}} script macros, those macros execute with the MCP user's rights when the page is viewed.
6
7 This is not an MCP-specific vulnerability: it is XWiki's normal edit semantics. MCP widens who can trigger it: any content the agent ingests (a web page, a file, another wiki page) could carry a prompt injection that causes the agent to write a page containing a script macro.
8
9 == Prompt injection amplification ==
10
11 The MCP server's design makes the agent read content from the wiki and from external sources, then potentially write that content back. A malicious actor who can place content the agent will read (by editing any page the agent searches, for example) can inject instructions into the agent's context that tell it to craft a page containing a script macro.
12
13 If the MCP user holds ##script## rights, this is already a code-execution vector: {{code language="none"}}{{velocity}}{{/code}} executes with that right alone, when any user views the page. {{code language="none"}}{{groovy}}{{/code}} additionally requires programming rights. Admin and programming rights both imply ##script##, so withholding those two is not enough on a wiki that grants ##script## separately - and many do, to all registered users.
14
15 == Destructive and structural operations ==
16
17 Script execution is not the only risk. The write set also lets an agent remove and restructure content:
18
19 * ##delete_document## moves a page to the recycle bin, from which an administrator can restore it.
20 * ##delete_attachment## moves the attachment, with its own version history, to the attachment recycle bin, from where it can be restored. On a wiki with no attachment recycle bin the tool refuses the deletion rather than performing an unrecoverable one.
21 * ##delete_object## removes one object from a page. It does not pass through any recycle bin; the object is recoverable only by reverting the page to an earlier revision.
22 * ##write_schema## creates or changes an XClass definition. Removing or retyping a field affects every existing object of that class, and undoing a page revision does not undo it.
23
24 The prompt-injection path above applies to these just as it does to script macros: content the agent reads can instruct it to delete or restructure rather than to write a script.
25
26 == Mitigations ==
27
28 |=Mitigation |=Effectiveness
29 |Withhold ##script##, programming and admin rights from the MCP user |Prevents script macro execution
30 |Enable only the write tools the use case needs |Removes the delete and schema surface
31 |Keep write tools off (default) |Eliminates the write surface unless explicitly needed
32 |Use space filters to restrict agent edits |Contains agent writes to a controlled area
33 |Audit through ##[AI]## history stamps |Enables detection and rollback
34 |Run agents as a dedicated, scoped user |Limits potential damage to that user's rights
35
36 == Built-in protections ==
37
38 * ##write_document## requires ##base_version## for overwrites: the agent must have read the page first and supply the version it read. Omitting it is refused without disclosing the current version, so an agent cannot overwrite a page it never opened; supplying a stale one is refused with a version conflict that does name the current version, so the agent can re-read and retry.
39 * ##edit_document## uses exact string matching for edits. If the page changed between reading and editing, the edit fails cleanly with "re-read and retry".
40 * Every save is a single version in the history, stamped ##[AI]##, allowing for easy version comparison.

Get Connected