mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-25 09:32:20 +02:00
fix(security): block all bare email tool names for non-admins; harden fence-tag regex
Review follow-up on #3681 (thanks @vgalin): 1. Routing bare email names made 10 of the 14 email tools executable by non-admin owners — is_public_blocked_tool() runs on the bare name before dispatch, and NON_ADMIN_BLOCKED_TOOLS only listed 4. Define the full email tool set once (BUILTIN_EMAIL_TOOLS in tool_security.py) and derive the blocklist, the fence tags (TOOL_TAGS), the bare-name dispatch, and the native-call mapping from it so they can't drift. This also fixes 4 tools (search_emails, draft_email, draft_email_reply, ai_draft_email_reply) that were missing from the old tool_schemas copy and therefore unreachable even for native function-calling models. 2. The relaxed fence regex from the previous commit could prefix-match longer fence tags: ```python3 parsed as tool "python" with content "3\nprint(...)" and executed as code. Add a (?![\w-]) boundary after the tag. Tests: test_public_agent_policy_blocks_sensitive_tools now covers all 14 bare email names + the mcp__email__ form; new tests/test_fenced_inline_args.py pins inline-args parsing, the python3/hyphenated-tag non-matches, and strip/parse display mirroring. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f24dbadab3
commit
544a664766
+28
-6
@@ -8,10 +8,36 @@ from typing import Optional, Set
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Every tool exposed by the built-in email MCP server
|
||||
# (mcp_servers/email_server.py). Single source of truth: the fence tags
|
||||
# (TOOL_TAGS), bare-name dispatch (tool_execution), native-call mapping
|
||||
# (tool_schemas), and the non-admin blocklist below all derive from this set,
|
||||
# so a tool added to the email server can't become reachable under its bare
|
||||
# name without also being blocked for non-admins.
|
||||
BUILTIN_EMAIL_TOOLS = frozenset({
|
||||
"list_email_accounts",
|
||||
"list_emails",
|
||||
"read_email",
|
||||
"search_emails",
|
||||
"send_email",
|
||||
"reply_to_email",
|
||||
"draft_email",
|
||||
"draft_email_reply",
|
||||
"ai_draft_email_reply",
|
||||
"archive_email",
|
||||
"delete_email",
|
||||
"mark_email_read",
|
||||
"bulk_email",
|
||||
"download_attachment",
|
||||
})
|
||||
|
||||
|
||||
# Tools regular/public users must not execute directly. These either expose
|
||||
# server/runtime access, sensitive user data, external messaging, persistent
|
||||
# state changes, or generic loopback/integration surfaces.
|
||||
NON_ADMIN_BLOCKED_TOOLS = {
|
||||
# state changes, or generic loopback/integration surfaces. All email tools are
|
||||
# included (SECURITY.md: email/MCP capabilities are privileged admin
|
||||
# functionality).
|
||||
NON_ADMIN_BLOCKED_TOOLS = BUILTIN_EMAIL_TOOLS | {
|
||||
"bash",
|
||||
"python",
|
||||
"read_file",
|
||||
@@ -32,10 +58,6 @@ NON_ADMIN_BLOCKED_TOOLS = {
|
||||
"manage_settings",
|
||||
"api_call",
|
||||
"app_api",
|
||||
"send_email",
|
||||
"reply_to_email",
|
||||
"list_emails",
|
||||
"read_email",
|
||||
"resolve_contact",
|
||||
"manage_contact",
|
||||
"manage_calendar",
|
||||
|
||||
Reference in New Issue
Block a user