fix: display assistant content with finish tool call + block shell write redirects
Bug 1: Assistant text content was silently dropped when the LLM response included both content and tool calls (e.g. finish with a summary). Now content is displayed before tool call execution regardless. Bug 2: Shell redirect operators (>, >>, <<) allowed bypassing file-write permissions when the base command (e.g. cat) was in the allowed list. Redirects now require explicit user approval in permissions, and the shell tool itself blocks them as defense-in-depth. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
"""Shell tool: run_command."""
|
||||
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
from typing import Any
|
||||
@@ -11,6 +12,9 @@ from app.tools.base import BaseTool
|
||||
|
||||
_DEFAULT_TIMEOUT = 30
|
||||
|
||||
# Detect shell redirects that write to files (>, >>, heredocs)
|
||||
_WRITE_REDIRECT_PATTERN = re.compile(r"(?:>\s*\S|>>|<<)")
|
||||
|
||||
|
||||
class RunCommandParams(BaseModel):
|
||||
"""Parameters for the run_command tool."""
|
||||
@@ -43,6 +47,18 @@ class RunCommandTool(BaseTool):
|
||||
error=f"Command denied: matches blocked prefix '{denied}'",
|
||||
)
|
||||
|
||||
# Defense-in-depth: flag file-write redirects in tool result
|
||||
if _WRITE_REDIRECT_PATTERN.search(command):
|
||||
return ToolResult(
|
||||
tool_call_id=tool_call_id,
|
||||
tool_name=self.name,
|
||||
status=ToolResultStatus.ERROR,
|
||||
error=(
|
||||
f"Command contains file-write redirect (>, >>, or <<) "
|
||||
f"which bypasses file-write permissions. Use write_file instead."
|
||||
),
|
||||
)
|
||||
|
||||
# Allow check: first token must be in allowed_commands
|
||||
try:
|
||||
tokens = shlex.split(command)
|
||||
|
||||
Reference in New Issue
Block a user