#!/usr/bin/env python3 """ Security audit script - verifică zilnic: 1. Permisiuni fișiere sensibile (600) 2. Parole hardcoded în cod 3. Fișiere sensibile în git tracking 4. Porturi expuse neașteptat Exit codes: 0 = OK 1 = Warnings found 2 = Critical issues found """ import os import sys import subprocess from pathlib import Path CLAWD_DIR = Path(__file__).parent.parent SENSITIVE_FILES = [".env", "credentials"] REQUIRED_PERMS = 0o600 REQUIRED_DIR_PERMS = 0o700 issues = [] warnings = [] def check_permissions(): """Check sensitive files have 600 permissions""" env_file = CLAWD_DIR / ".env" if env_file.exists(): mode = env_file.stat().st_mode & 0o777 if mode != REQUIRED_PERMS: issues.append(f".env has {oct(mode)} permissions (should be 0o600)") creds_dir = CLAWD_DIR / "credentials" if creds_dir.exists(): for f in creds_dir.iterdir(): if f.is_file(): mode = f.stat().st_mode & 0o777 if mode != REQUIRED_PERMS: issues.append(f"credentials/{f.name} has {oct(mode)} (should be 0o600)") def check_hardcoded_secrets(): """Scan Python files for potential hardcoded secrets""" patterns = [ 'password.*=.*"[^"]{4,}"', 'api_key.*=.*"[^"]{8,}"', 'secret.*=.*"[^"]{8,}"', ] for py_file in CLAWD_DIR.rglob("*.py"): if "venv" in str(py_file) or "__pycache__" in str(py_file): continue try: content = py_file.read_text() for i, line in enumerate(content.split('\n'), 1): line_lower = line.lower() # Skip comments and env reads if line.strip().startswith('#') or 'os.getenv' in line or 'environ' in line: continue # Check for hardcoded passwords (excluding empty strings and placeholders) if ('password' in line_lower or 'api_pass' in line_lower) and '= "' in line and 'in line' not in line_lower: if '= ""' not in line and '= "***"' not in line: # Check if it's actually setting a value, not reading if 'getenv' not in line and 'environ' not in line: rel_path = py_file.relative_to(CLAWD_DIR) warnings.append(f"Potential hardcoded secret in {rel_path}:{i}") except Exception: pass def check_git_tracking(): """Check if sensitive files are tracked by git""" try: result = subprocess.run( ["git", "ls-files", ".env", "credentials/"], cwd=CLAWD_DIR, capture_output=True, text=True ) if result.stdout.strip(): for f in result.stdout.strip().split('\n'): issues.append(f"Sensitive file tracked by git: {f}") except Exception: pass def check_gitignore(): """Verify .gitignore contains sensitive patterns""" gitignore = CLAWD_DIR / ".gitignore" if gitignore.exists(): content = gitignore.read_text() required = [".env", "credentials/"] for pattern in required: if pattern not in content: warnings.append(f"Missing from .gitignore: {pattern}") def main(): print("🔒 Security Audit - Echo") print("=" * 40) check_permissions() check_hardcoded_secrets() check_git_tracking() check_gitignore() if issues: print("\n🔴 CRITICAL ISSUES:") for issue in issues: print(f" - {issue}") if warnings: print("\n🟠 WARNINGS:") for warning in warnings: print(f" - {warning}") if not issues and not warnings: print("\n✅ All checks passed!") return 0 print(f"\n📊 Summary: {len(issues)} critical, {len(warnings)} warnings") if issues: return 2 return 1 if __name__ == "__main__": sys.exit(main())