Summary
GITLAB_TOOL_POLICY_HIDDEN is meant to remove tools from tools/list while leaving them callable. The call-time check skips every hidden tool, without checking that the tool is enabled at all. Hiding a tool whose toolset is off therefore turns it on.
The documented example (GITLAB_TOOL_POLICY_HIDDEN=delete_issue,delete_wiki_page) makes delete_wiki_page callable under the default toolsets, where the wiki toolset is off. Hiding gitlab_api_request or execute_graphql enables them even though the docs say only GITLAB_TOOLSETS=api (or an explicit GITLAB_TOOLS entry) can.
Affected Component
index.ts CallTool handler, list-time filter enforcement for direct calls
Affected configuration:
GITLAB_TOOL_POLICY_HIDDEN lists a tool outside the enabled toolsets / GITLAB_TOOLS
Call-time enforcement of the list filters arrived in 2.1.69 with this exemption already in it. Earlier releases did not check list filters at call time at all, so a hidden tool outside the enabled toolsets has been callable since tool policies were added in 2.1.0.
Vulnerability Type
CWE-863 - Incorrect Authorization
Technical Details
const hiddenAndNotDenied =
hiddenToolSet.has(toolName) && !GITLAB_DENIED_TOOLS_REGEX?.test(toolName);
if (
isToolAllowedByPermissionMode(toolName) &&
!hiddenAndNotDenied && // any hidden name passes
!filteredTools.some(t => t.name === toolName)
) throw ...
GITLAB_TOOLSETS unset (core only)
GITLAB_TOOL_POLICY_HIDDEN=delete_issue,delete_wiki_page
tools/call delete_wiki_page -> runs (wiki toolset is off)
GITLAB_TOOL_POLICY_HIDDEN=gitlab_api_request
tools/call gitlab_api_request -> runs (api toolset never enabled)
Permission mode and GITLAB_DENIED_TOOLS_REGEX still apply.
Proof of Concept
test/test-permission-mode.ts in the fix ("call-time enforcement of hidden-policy tools"): on 2.2.6, 5 of 32 tests fail. A hidden delete_wiki_page, gitlab_api_request and execute_graphql are all callable with their toolsets off.
Expected
Hiding a tool never makes it callable when the toolset, GITLAB_TOOLS, feature flag, permission mode and denylist filters would not expose it.
Actual
Any hidden tool is callable, subject only to permission mode and the denylist.
Security Impact
Tools the operator did not enable become available to a client that knows their names, or to an agent driven by prompt injection. The effect is limited to what the token and permission mode allow, and needs a configuration that hides a tool outside the enabled toolsets. That configuration is the one shown in the docs.
Fix
Hidden tools are callable only if they would be listed with the hidden policy ignored. When discover_tools activates a toolset, its hidden tools become callable with the rest of it.
Summary
GITLAB_TOOL_POLICY_HIDDENis meant to remove tools fromtools/listwhile leaving them callable. The call-time check skips every hidden tool, without checking that the tool is enabled at all. Hiding a tool whose toolset is off therefore turns it on.The documented example (
GITLAB_TOOL_POLICY_HIDDEN=delete_issue,delete_wiki_page) makesdelete_wiki_pagecallable under the default toolsets, where the wiki toolset is off. Hidinggitlab_api_requestorexecute_graphqlenables them even though the docs say onlyGITLAB_TOOLSETS=api(or an explicitGITLAB_TOOLSentry) can.Affected Component
Affected configuration:
Call-time enforcement of the list filters arrived in 2.1.69 with this exemption already in it. Earlier releases did not check list filters at call time at all, so a hidden tool outside the enabled toolsets has been callable since tool policies were added in 2.1.0.
Vulnerability Type
CWE-863 - Incorrect Authorization
Technical Details
Permission mode and
GITLAB_DENIED_TOOLS_REGEXstill apply.Proof of Concept
test/test-permission-mode.tsin the fix ("call-time enforcement of hidden-policy tools"): on 2.2.6, 5 of 32 tests fail. A hiddendelete_wiki_page,gitlab_api_requestandexecute_graphqlare all callable with their toolsets off.Expected
Hiding a tool never makes it callable when the toolset,
GITLAB_TOOLS, feature flag, permission mode and denylist filters would not expose it.Actual
Any hidden tool is callable, subject only to permission mode and the denylist.
Security Impact
Tools the operator did not enable become available to a client that knows their names, or to an agent driven by prompt injection. The effect is limited to what the token and permission mode allow, and needs a configuration that hides a tool outside the enabled toolsets. That configuration is the one shown in the docs.
Fix
Hidden tools are callable only if they would be listed with the hidden policy ignored. When
discover_toolsactivates a toolset, its hidden tools become callable with the rest of it.