Repository navigation
Unauthenticated schema disclosure + XPath injection in iTopSchemaTools (follow-up to #19) #20
Description
Following up on the TLS-verification report in #19 — found a second, separate issue while reviewing the MCP tool set, this time in the schema tools.
Summary: iTopSchemaTools (the iTop-list-all-classes and iTop-get-class-schema tools) is built only on DatamodelService, which just parses the local data/datamodel-production.xml file. Unlike every other tool in this server, it never goes through iTopClientInterface / Security::getUser(). Combined with config/packages/security.yaml having an empty access_control and a lazy/stateless main firewall, and McpController::handle() performing no authorization check of its own, these two tools fully execute for a POST /_mcp request that carries no Authorization header at all — meaning anyone who can reach the /_mcp endpoint gets the target instance's complete class list, custom fields, enum values, and workflow/life-cycle state machines, with zero credentials.
Where:
src/Tools/schema/iTopSchemaTools.php:10-91— no Security/iTopClientInterface dependency anywhere in the classconfig/packages/security.yaml— emptyaccess_controlvendor/symfony/mcp-bundle/src/Controller/McpController.php:36-48— noIsGranted/security check before the MCP server runs
This is a clean, complete bypass of the "every tool call needs the caller's iTop credentials" model for these 2 of 16 tools — every other tool (get/create/update/apply-stimulus/get-related/natural-language-search) does correctly require a Bearer token, so this looks like an oversight specific to the schema tools rather than an intentional design choice.
Second, related issue: DatamodelService::getClassSchemaFromXml() (src/Service/DatamodelService.php:86,98) builds its XPath lookup by directly concatenating the caller-supplied className argument (from get-class-schema) into the query string with no escaping. I confirmed locally (against the repo's own test fixture, no live instance touched) that a crafted className value containing a single quote breaks out of the intended class[@id='...'] predicate and changes which nodes match — going from matching exactly 1 class to matching all 139 classes in the test datamodel. That's a textbook XPath injection (CWE-643); I'm keeping the exact payload out of this public issue since it's a real working primitive, but happy to share it privately if useful — feel free to open a private security advisory (I noticed GHSA private reporting isn't enabled on this repo yet, might be worth turning on) or ping me and I'll send the PoC directly.
Suggested fix direction: route iTopSchemaTools through the same iTopClientInterface/Security check as the other 14 tools (or add an explicit access_control entry for /_mcp requiring authentication), and parameterize/escape $className before building the XPath query rather than string-concatenating it.
Happy to provide more detail or help verify a fix.
— Syed Anas Mohiuddin
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsOpen
Activity
dflaven commentedon Sep 22, 2026
This version is still a prototype. The authentication will be addressed in the final version.