Initial commit: a0_software_orchestrator v1.0
- Auto-Registration-Bug behoben (register_project/get_project_id/resolve_project Trennung) - 25 Tests gruen (Pytest) - block_compactor-Tool refactored (Option B: Soft-Check statt Hard-Block) - 4 Restbaustellen gefixt - DB-Schema: plugin_settings-Tabelle hinzugefuegt - 3 Schattenprojekte aus DB geloescht - Plan v3 + Refactor-Plan + Worklog dokumentiert
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""Safety rules: Plan Mode, permissions, dangerous actions."""
|
||||
import re
|
||||
|
||||
# Patterns for potentially dangerous terminal commands
|
||||
DANGEROUS_PATTERNS = [
|
||||
r"rm\s+-rf\s+/.*",
|
||||
r"sudo\s+rm",
|
||||
r"mkfs\.",
|
||||
r"dd\s+if=",
|
||||
r">\s*/dev/sd",
|
||||
r"chmod\s+777",
|
||||
r"git\s+push\s+.*\s+main",
|
||||
r"git\s+push\s+.*\s+master",
|
||||
r"docker\s+rm\s+-f",
|
||||
r"docker\s+volume\s+rm",
|
||||
]
|
||||
|
||||
# Pattern to detect Base64-like values that may be secrets
|
||||
# Matches: api_key=XXXX, token:XXXX, secret="XXXX", etc.
|
||||
_SECRET_VALUE = re.compile(
|
||||
r'(?:api|access|secret|token|key|password|auth)'
|
||||
r'[-_]?'
|
||||
r'(?:key|token|secret)?'
|
||||
r'\s*[=:]\s*'
|
||||
r'[\'"]?'
|
||||
r'[A-Za-z0-9+/=_-]{20,}'
|
||||
r'[\'"]?'
|
||||
)
|
||||
|
||||
def is_dangerous_command(command: str) -> bool:
|
||||
"""Check if a terminal command matches known dangerous patterns."""
|
||||
for pattern in DANGEROUS_PATTERNS:
|
||||
if re.search(pattern, command, re.IGNORECASE):
|
||||
return True
|
||||
return False
|
||||
|
||||
def contains_secret(text: str) -> bool:
|
||||
"""Check if text likely contains a hardcoded secret."""
|
||||
return bool(_SECRET_VALUE.search(text))
|
||||
|
||||
|
||||
def redact_secrets(text: str) -> str:
|
||||
"""Return text with obvious credential-looking assignments redacted.
|
||||
|
||||
This is defensive output hygiene, not a credential scanner. It must only be
|
||||
applied to data already produced by approved checks.
|
||||
"""
|
||||
return _SECRET_VALUE.sub(lambda m: m.group(0).split('=')[0] + '=<REDACTED>' if '=' in m.group(0) else '<REDACTED_SECRET_LIKE_VALUE>', text)
|
||||
|
||||
|
||||
# Credential-discovery commands are never legitimate for this plugin.
|
||||
# This is not a scanner for collecting credentials; it is a pre-execution guard
|
||||
# for commands/plans that attempt credential discovery.
|
||||
CREDENTIAL_DISCOVERY_PATTERNS = [
|
||||
r"\b(grep|rg|ripgrep|find|cat|sed|awk|python|python3|node|perl)\b.*\b(password|passwd|pwd|token|secret|api[_-]?key|access[_-]?key|private[_-]?key|credential|auth|cookie|session)\b",
|
||||
r"\b(password|passwd|pwd|token|secret|api[_-]?key|access[_-]?key|private[_-]?key|credential|auth|cookie|session)\b.*\b(grep|rg|ripgrep|find|cat|sed|awk|python|python3|node|perl)\b",
|
||||
r"\b(env|printenv|set)\b.*\b(password|token|secret|key|credential|auth)\b",
|
||||
r"\b\.env(\.|\b|$)",
|
||||
r"\b(config|settings|application|appsettings).*\b(password|token|secret|credential|auth)\b",
|
||||
r"\b(browser|chrome|firefox|localstorage|sessionstorage|cookie|cookies)\b.*\b(password|token|secret|credential|auth|session)\b",
|
||||
r"\bfind\b.*\b(login|credential|credentials|password|token|secret)\b",
|
||||
r"\b(read|open|dump|extract|list|locate|recover|discover|search)\b.*\b(login|credential|credentials|password|token|secret|cookie|session)\b",
|
||||
]
|
||||
|
||||
|
||||
def is_credential_discovery_command(command: str) -> bool:
|
||||
"""Return True if a command/plan appears to look for credential material."""
|
||||
c = str(command or "").lower()
|
||||
return any(re.search(pattern, c, re.IGNORECASE) for pattern in CREDENTIAL_DISCOVERY_PATTERNS)
|
||||
Reference in New Issue
Block a user