import subprocess import json import sys import os def audit_npm(): if not os.path.exists("package.json"): return None print("🛡️ Executando auditoria de segurança (npm)...") try: result = subprocess.run( ["npm", "audit", "--json"], capture_output=True, text=True, shell=True ) if not result.stdout: return "❌ Erro ao rodar npm audit: Nenhuma saída gerada." output = json.loads(result.stdout) except Exception as e: return f"❌ Falha ao rodar npm audit: {e}" vulns = output.get("vulnerabilities", {}) metadata = output.get("metadata", {}).get("vulnerabilities", {}) total_high = metadata.get("high", 0) total_crit = metadata.get("critical", 0) if total_high == 0 and total_crit == 0: return "✅ NPM: Nenhuma vulnerabilidade Alta ou Crítica." report = [f"🚨 NPM: {total_high} Altas e {total_crit} Críticas."] for name, data in vulns.items(): severity = data.get("severity", "low") if severity in ["high", "critical"]: report.append( f"- [{severity.upper()}] {name} (Fix? {'Sim' if data.get('fixAvailable') else 'Não'})" ) return "\n".join(report) def audit_python(): # Procura por arquivos de dependência python py_deps = ["requirements.txt", ".agent/tools/requirements.txt"] target_file = next((f for f in py_deps if os.path.exists(f)), None) if not target_file: return None print(f"🐍 Executando auditoria de segurança (python-audit via {target_file})...") try: # Tenta usar pip-audit (mais moderno) result = subprocess.run( ["python", "-m", "pip_audit", "-r", target_file, "--format", "json"], capture_output=True, text=True, shell=True, ) if result.returncode != 0 and not result.stdout: # Se falhar e não tiver saída, pode ser que o pip-audit não esteja instalado return "⚠️ pip-audit não instalado. Instale com: pip install pip-audit" # pip-audit retorna 0 se não houver vulns, >0 se houver output = json.loads(result.stdout) vulns_found = [] # A saída pode ser um dicionário com uma lista ou uma lista dependendo da versão/formato packages = ( output if isinstance(output, list) else output.get("dependencies", []) ) for package in packages: if not isinstance(package, dict): continue for vuln in package.get("vulnerabilities", []): vulns_found.append( { "name": package["name"], "version": package["version"], "id": vuln["id"], "fix": vuln.get("fix_versions", ["N/A"]), } ) if not vulns_found: return "✅ Python: Nenhuma vulnerabilidade encontrada." report = [f"🚨 PYTHON: {len(vulns_found)} vulnerabilidades encontradas."] for v in vulns_found: report.append( f"- {v['name']} ({v['version']}) -> ID: {v['id']} (Fix: {', '.join(v['fix'])})" ) return "\n".join(report) except Exception as e: # Fallback se pip-audit falhar por não existir ou erro de parse print(f"⚠️ Erro ao executar auditoria Python: {e}") return "⚠️ pip-audit falhou ou não foi inicializado corretamente." def audit_security(): reports = [] npm_report = audit_npm() if npm_report: reports.append(npm_report) py_report = audit_python() if py_report: reports.append(py_report) if not reports: return "ℹ️ Nenhum arquivo de dependência encontrado (package.json ou requirements.txt)." return "\n\n".join(reports) if __name__ == "__main__": print(audit_security())