Skip to main content
Glama
test_shell_quoting.py4.91 kB
#!/usr/bin/env python3 """ Test script to demonstrate potential security issues with parameter substitution approach. """ import tempfile from pathlib import Path from hooks_mcp.config import Action, ActionParameter, ParameterType from hooks_mcp.executor import CommandExecutor def test_parameter_name_collision(): """Test what happens when parameter names collide (one is substring of another).""" # Create a temporary directory for testing temp_dir = tempfile.TemporaryDirectory() project_root = Path(temp_dir.name) executor = CommandExecutor() executor.project_root = project_root # Create action with parameters where one name is substring of another action = Action( name="collision_test", description="Test parameter name collision", command="echo $A and $AB", # $A is substring of $AB parameters=[ ActionParameter("A", ParameterType.INSECURE_STRING, "Parameter 1"), ActionParameter("AB", ParameterType.INSECURE_STRING, "Parameter 2"), ], ) try: result = executor.execute_action( action, {"A": "First Value", "AB": "Second Value"} ) # Check if substitution worked correctly assert "First Value and Second Value" == result["stdout"] finally: temp_dir.cleanup() def test_parameter_order_dependency(): """Test if parameter substitution order matters.""" temp_dir = tempfile.TemporaryDirectory() project_root = Path(temp_dir.name) executor = CommandExecutor() executor.project_root = project_root # Test with parameters in different orders action = Action( name="order_test", description="Test parameter order", command="echo $PREFIX $PREFIX_SUFFIX", parameters=[ ActionParameter( "PREFIX_SUFFIX", ParameterType.INSECURE_STRING, "Full parameter" ), ActionParameter( "PREFIX", ParameterType.INSECURE_STRING, "Prefix parameter" ), ], ) try: result = executor.execute_action( action, {"PREFIX": "Hello", "PREFIX_SUFFIX": "Hello World"} ) # Parameter order should be handled correctly assert "Hello Hello World" == result["stdout"], ( f"Expected 'Hello Hello World' in output, got: {result['stdout']}" ) finally: temp_dir.cleanup() def test_special_characters_in_values(): """Test how special shell characters are handled.""" temp_dir = tempfile.TemporaryDirectory() project_root = Path(temp_dir.name) executor = CommandExecutor() executor.project_root = project_root action = Action( name="special_chars_test", description="Test special characters", command="echo $MESSAGE", parameters=[ ActionParameter( "MESSAGE", ParameterType.INSECURE_STRING, "Message with special chars" ), ], ) test_cases = [ ("Simple", "Hello World"), ("Quotes", 'Hello "quoted" world'), ("Single quotes", "Hello 'quoted' world"), ("Backticks", "Hello `backticked` world"), ("Dollar signs", "Hello $USER world"), ("Semicolon", "Hello; echo injected"), ("Ampersand", "Hello && echo injected"), ("Pipe", "Hello | echo injected"), ] try: for test_name, message in test_cases: result = executor.execute_action(action, {"MESSAGE": message}) assert message == result["stdout"], ( f"Expected '{message}' in output, got: {result['stdout']} for test {test_name}" ) finally: temp_dir.cleanup() def test_parameter_name_collision_substring(): """Test what happens when parameter names collide (one is substring of another).""" # Create a temporary directory for testing temp_dir = tempfile.TemporaryDirectory() project_root = Path(temp_dir.name) executor = CommandExecutor() executor.project_root = project_root # Create action with parameters where one name is substring of another action = Action( name="collision_test", description="Test parameter name collision", command='echo "$A and $AB"', # $A is substring of $AB parameters=[ ActionParameter("A", ParameterType.INSECURE_STRING, "Parameter 1"), ActionParameter("AB", ParameterType.INSECURE_STRING, "Parameter 2"), ], ) try: result = executor.execute_action( action, {"A": "First Value", "AB": "Second Value"} ) # Check if substitution worked correctly # a bad example would be "'First Value' and 'Second Value'" with additional quoting changing the output assert "First Value and Second Value" == result["stdout"] finally: temp_dir.cleanup()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/scosman/actions_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server