mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-02-04 16:03:08 +00:00
fix: revert unsafe permission changes from PR #78
Security fixes to restore defense-in-depth after merging PR #78: **client.py:** - Revert permission mode from "bypassPermissions" to "acceptEdits" - Remove redundant web_tools_auto_approve_hook from PreToolUse hooks - Remove unused import of web_tools_auto_approve_hook **security.py:** - Remove web_tools_auto_approve_hook function (was redundant and returned {} for ALL tools, not just WebFetch/WebSearch) **server/services/spec_chat_session.py:** - Restore allowed_tools restriction: [Read, Write, Edit, Glob, WebFetch, WebSearch] - Revert permission mode from "bypassPermissions" to "acceptEdits" - Keeps setting_sources=["project", "user"] for global skills access **ui/src/components/AgentAvatar.tsx:** - Remove unused getMascotName export to fix React Fast Refresh warning - File now only exports AgentAvatar component as expected The bypassPermissions mode combined with unrestricted tool access in spec_chat_session.py created a security gap where Bash commands could execute without validation (sandbox disabled, no bash_security_hook). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,7 @@ from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
|
|||||||
from claude_agent_sdk.types import HookMatcher
|
from claude_agent_sdk.types import HookMatcher
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from security import bash_security_hook, web_tools_auto_approve_hook
|
from security import bash_security_hook
|
||||||
|
|
||||||
# Load environment variables from .env file if present
|
# Load environment variables from .env file if present
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -181,7 +181,7 @@ def create_client(
|
|||||||
security_settings = {
|
security_settings = {
|
||||||
"sandbox": {"enabled": True, "autoAllowBashIfSandboxed": True},
|
"sandbox": {"enabled": True, "autoAllowBashIfSandboxed": True},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"defaultMode": "bypassPermissions", # Auto-approve all tools
|
"defaultMode": "acceptEdits", # Auto-approve edits within allowed directories
|
||||||
"allow": permissions_list,
|
"allow": permissions_list,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,6 @@ def create_client(
|
|||||||
hooks={
|
hooks={
|
||||||
"PreToolUse": [
|
"PreToolUse": [
|
||||||
HookMatcher(matcher="Bash", hooks=[bash_security_hook]),
|
HookMatcher(matcher="Bash", hooks=[bash_security_hook]),
|
||||||
HookMatcher(matcher="WebFetch|WebSearch", hooks=[web_tools_auto_approve_hook]),
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
max_turns=1000,
|
max_turns=1000,
|
||||||
|
|||||||
22
security.py
22
security.py
@@ -309,28 +309,6 @@ def get_command_for_validation(cmd: str, segments: list[str]) -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
async def web_tools_auto_approve_hook(input_data, tool_use_id=None, context=None):
|
|
||||||
"""
|
|
||||||
Pre-tool-use hook that auto-approves WebFetch and WebSearch tools.
|
|
||||||
|
|
||||||
Workaround for Claude Code bug where these tools are auto-denied in dontAsk mode.
|
|
||||||
See: https://github.com/anthropics/claude-code/issues/11881
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_data: Dict containing tool_name and tool_input
|
|
||||||
tool_use_id: Optional tool use ID
|
|
||||||
context: Optional context
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Empty dict to allow (auto-approve)
|
|
||||||
"""
|
|
||||||
tool_name = input_data.get("tool_name", "")
|
|
||||||
if tool_name in ("WebFetch", "WebSearch"):
|
|
||||||
# Return empty dict = allow/approve the tool
|
|
||||||
return {}
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
async def bash_security_hook(input_data, tool_use_id=None, context=None):
|
async def bash_security_hook(input_data, tool_use_id=None, context=None):
|
||||||
"""
|
"""
|
||||||
Pre-tool-use hook that validates bash commands using an allowlist.
|
Pre-tool-use hook that validates bash commands using an allowlist.
|
||||||
|
|||||||
@@ -181,8 +181,15 @@ class SpecChatSession:
|
|||||||
# System prompt loaded from CLAUDE.md via setting_sources
|
# System prompt loaded from CLAUDE.md via setting_sources
|
||||||
# Include "user" for global skills and subagents from ~/.claude/
|
# Include "user" for global skills and subagents from ~/.claude/
|
||||||
setting_sources=["project", "user"],
|
setting_sources=["project", "user"],
|
||||||
# No allowed_tools restriction - full access to all tools, skills, subagents
|
allowed_tools=[
|
||||||
permission_mode="bypassPermissions", # Auto-approve all tools
|
"Read",
|
||||||
|
"Write",
|
||||||
|
"Edit",
|
||||||
|
"Glob",
|
||||||
|
"WebFetch",
|
||||||
|
"WebSearch",
|
||||||
|
],
|
||||||
|
permission_mode="acceptEdits", # Auto-approve file writes for spec creation
|
||||||
max_turns=100,
|
max_turns=100,
|
||||||
cwd=str(self.project_dir.resolve()),
|
cwd=str(self.project_dir.resolve()),
|
||||||
settings=str(settings_file.resolve()),
|
settings=str(settings_file.resolve()),
|
||||||
|
|||||||
@@ -595,9 +595,3 @@ export function AgentAvatar({ name, state, size = 'md', showName = false }: Agen
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get mascot name by index (cycles through available mascots)
|
|
||||||
export function getMascotName(index: number): AgentMascot {
|
|
||||||
const mascots = Object.keys(MASCOT_SVGS) as AgentMascot[]
|
|
||||||
return mascots[index % mascots.length]
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user