MCPcopy Create free account
hub / github.com/AutoForgeAI/autoforge / bash_security_hook

Function bash_security_hook

security.py:863–959  ·  view source on GitHub ↗

Pre-tool-use hook that validates bash commands using an allowlist. Only commands in ALLOWED_COMMANDS and project-specific commands are permitted. Args: input_data: Dict containing tool_name and tool_input tool_use_id: Optional tool use ID context: Optional cont

(input_data, tool_use_id=None, context=None)

Source from the content-addressed store, hash-verified

861
862
863async def bash_security_hook(input_data, tool_use_id=None, context=None):
864 """
865 Pre-tool-use hook that validates bash commands using an allowlist.
866
867 Only commands in ALLOWED_COMMANDS and project-specific commands are permitted.
868
869 Args:
870 input_data: Dict containing tool_name and tool_input
871 tool_use_id: Optional tool use ID
872 context: Optional context dict with 'project_dir' key
873
874 Returns:
875 Empty dict to allow, or {"decision": "block", "reason": "..."} to block
876 """
877 if input_data.get("tool_name") != "Bash":
878 return {}
879
880 command = input_data.get("tool_input", {}).get("command", "")
881 if not command:
882 return {}
883
884 # Extract all commands from the command string
885 commands = extract_commands(command)
886
887 if not commands:
888 # Could not parse - fail safe by blocking
889 return {
890 "decision": "block",
891 "reason": f"Could not parse command for security validation: {command}",
892 }
893
894 # Get project directory from context
895 project_dir = None
896 if context and isinstance(context, dict):
897 project_dir_str = context.get("project_dir")
898 if project_dir_str:
899 project_dir = Path(project_dir_str)
900
901 # Get effective commands using hierarchy resolution
902 allowed_commands, blocked_commands = get_effective_commands(project_dir)
903
904 # Get effective pkill processes (includes org/project config)
905 pkill_processes = get_effective_pkill_processes(project_dir)
906
907 # Split into segments for per-command validation
908 segments = split_command_segments(command)
909
910 # Check each command against the blocklist and allowlist
911 for cmd in commands:
912 # Check blocklist first (highest priority)
913 if cmd in blocked_commands:
914 return {
915 "decision": "block",
916 "reason": f"Command '{cmd}' is blocked at organization level and cannot be approved.",
917 }
918
919 # Check allowlist (with pattern matching)
920 if not is_command_allowed(cmd, allowed_commands):

Calls 8

extract_commandsFunction · 0.85
get_effective_commandsFunction · 0.85
split_command_segmentsFunction · 0.85
is_command_allowedFunction · 0.85
validate_pkill_commandFunction · 0.85
validate_chmod_commandFunction · 0.85
validate_init_scriptFunction · 0.85