mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-02-02 15:23:37 +00:00
security: prevent bare wildcard '*' from matching all commands
Add validation to reject bare wildcards for security: - matches_pattern(): return False if pattern == '*' - validate_project_command(): reject name == '*' with clear error - Added 4 new tests for bare wildcard rejection This prevents a config with from matching every command, which would be a major security risk. Tests: 140 unit tests passing (added 4 bare wildcard tests)
This commit is contained in:
11
security.py
11
security.py
@@ -371,6 +371,10 @@ def matches_pattern(command: str, pattern: str) -> bool:
|
|||||||
Returns:
|
Returns:
|
||||||
True if command matches pattern
|
True if command matches pattern
|
||||||
"""
|
"""
|
||||||
|
# Reject bare wildcards - security measure to prevent matching everything
|
||||||
|
if pattern == "*":
|
||||||
|
return False
|
||||||
|
|
||||||
# Exact match
|
# Exact match
|
||||||
if command == pattern:
|
if command == pattern:
|
||||||
return True
|
return True
|
||||||
@@ -378,6 +382,9 @@ def matches_pattern(command: str, pattern: str) -> bool:
|
|||||||
# Prefix wildcard (e.g., "swift*" matches "swiftc", "swiftlint")
|
# Prefix wildcard (e.g., "swift*" matches "swiftc", "swiftlint")
|
||||||
if pattern.endswith("*"):
|
if pattern.endswith("*"):
|
||||||
prefix = pattern[:-1]
|
prefix = pattern[:-1]
|
||||||
|
# Also reject if prefix is empty (would be bare "*")
|
||||||
|
if not prefix:
|
||||||
|
return False
|
||||||
return command.startswith(prefix)
|
return command.startswith(prefix)
|
||||||
|
|
||||||
# Local script paths (./scripts/build.sh matches build.sh)
|
# Local script paths (./scripts/build.sh matches build.sh)
|
||||||
@@ -524,6 +531,10 @@ def validate_project_command(cmd_config: dict) -> tuple[bool, str]:
|
|||||||
if not isinstance(name, str) or not name:
|
if not isinstance(name, str) or not name:
|
||||||
return False, "Command name must be a non-empty string"
|
return False, "Command name must be a non-empty string"
|
||||||
|
|
||||||
|
# Reject bare wildcard - security measure to prevent matching all commands
|
||||||
|
if name == "*":
|
||||||
|
return False, "Bare wildcard '*' is not allowed (security risk: matches all commands)"
|
||||||
|
|
||||||
# Check if command is in the blocklist or dangerous commands
|
# Check if command is in the blocklist or dangerous commands
|
||||||
base_cmd = os.path.basename(name.rstrip("*"))
|
base_cmd = os.path.basename(name.rstrip("*"))
|
||||||
if base_cmd in BLOCKED_COMMANDS:
|
if base_cmd in BLOCKED_COMMANDS:
|
||||||
|
|||||||
@@ -178,6 +178,11 @@ def test_pattern_matching():
|
|||||||
("swift", "swift*", True, "swift matches swift*"),
|
("swift", "swift*", True, "swift matches swift*"),
|
||||||
("npm", "swift*", False, "npm doesn't match swift*"),
|
("npm", "swift*", False, "npm doesn't match swift*"),
|
||||||
|
|
||||||
|
# Bare wildcard (security: should NOT match anything)
|
||||||
|
("npm", "*", False, "bare wildcard doesn't match npm"),
|
||||||
|
("sudo", "*", False, "bare wildcard doesn't match sudo"),
|
||||||
|
("anything", "*", False, "bare wildcard doesn't match anything"),
|
||||||
|
|
||||||
# Local script paths
|
# Local script paths
|
||||||
("build.sh", "./scripts/build.sh", True, "script name matches path"),
|
("build.sh", "./scripts/build.sh", True, "script name matches path"),
|
||||||
("./scripts/build.sh", "./scripts/build.sh", True, "exact script path"),
|
("./scripts/build.sh", "./scripts/build.sh", True, "exact script path"),
|
||||||
@@ -293,6 +298,9 @@ def test_command_validation():
|
|||||||
({"name": ""}, False, "empty name"),
|
({"name": ""}, False, "empty name"),
|
||||||
({"name": 123}, False, "non-string name"),
|
({"name": 123}, False, "non-string name"),
|
||||||
|
|
||||||
|
# Security: Bare wildcard not allowed
|
||||||
|
({"name": "*"}, False, "bare wildcard rejected"),
|
||||||
|
|
||||||
# Blocklisted commands
|
# Blocklisted commands
|
||||||
({"name": "sudo"}, False, "blocklisted sudo"),
|
({"name": "sudo"}, False, "blocklisted sudo"),
|
||||||
({"name": "shutdown"}, False, "blocklisted shutdown"),
|
({"name": "shutdown"}, False, "blocklisted shutdown"),
|
||||||
|
|||||||
Reference in New Issue
Block a user