fix(security): block read-only cookbook tools for non-admin owners (#6353)

* fix(security): block read-only cookbook tools for non-admin owners

list_cached_models, list_served_models, tail_serve_output, list_downloads,
search_hf_models, list_serve_presets and list_cookbook_servers were in the
plan-mode read-only allowlist but in neither NON_ADMIN_BLOCKED_TOOLS nor the
dispatcher's _ADMIN_TOOLS. Each implementation calls a require_admin route
over the internal loopback with the process-wide INTERNAL_TOOL_TOKEN and
never checks the owner, so a non-admin user's agent inherited admin reach
through them. list_cached_models is the worst case: a caller-chosen `host`
is forwarded to /api/model/cached, which SSHes to that host with the app
user's keys and walks caller-chosen model_dirs. THREAT_MODEL.md lists model
serving as admin-only, so gate the read side the same way as serve/download.

Adding the names to NON_ADMIN_BLOCKED_TOOLS also hides them from non-admin
tool schemas and caps bearer-token agent runs; _ADMIN_TOOLS blocks them at
dispatch. Regression test covers both lists, schema hiding, and that the
loopback is never reached for a non-admin owner.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwcwfY2uQMxNRsK3y6xBAp

* fix(cookbook): bind request authority in admin gate regressions

Keep all seven read-only Cookbook tools in the admin prompt inventory. Grant request authority in dispatch tests so the admin gate itself is exercised, and verify administrators still reach each handler. Validation: 359 focused authorization, tool-policy and schema tests passed. Against the running app with real auth accounts, all seven tools reject a non-admin and an admin reaches the authenticated Cookbook HTTP API.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Afonso Junior <chatgpt@yack.com.br>
This commit is contained in:
Afonso Coutinho
2026-10-26 09:46:57 -06:00
committed by GitHub
co-authored by Claude Fable 5.1 Afonso Junior
parent 1000b6582c
commit be9f575b59
4 changed files with 163 additions and 1 deletions
+10
View File
@@ -1288,6 +1288,16 @@ _ADMIN_TOOLS = {
"serve_preset",
"stop_served_model",
"cancel_download",
# Read-only Cookbook tools reach require_admin routes over the internal
# loopback without an owner check (see NON_ADMIN_BLOCKED_TOOLS in
# src/tool_security.py), so they are admin-only at dispatch as well.
"list_served_models",
"tail_serve_output",
"list_downloads",
"search_hf_models",
"list_cached_models",
"list_serve_presets",
"list_cookbook_servers",
}