Coverage for src/alprina_cli/mitigation.py: 0%
58 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
1"""
2Mitigation suggestion module for Alprina CLI.
3Provides AI-powered remediation guidance for security findings.
4"""
6from pathlib import Path
7from typing import Optional
8from rich.console import Console
9from rich.panel import Panel
10from rich.markdown import Markdown
12from .reporting import load_events
13from .security_engine import run_agent
15console = Console()
18def mitigate_command(finding_id: Optional[str] = None, report_file: Optional[Path] = None):
19 """
20 Provide AI-powered mitigation suggestions for security findings.
22 Args:
23 finding_id: Specific finding ID to get mitigation for
24 report_file: Path to report file to analyze
25 """
26 console.print(Panel("🛠️ Generating mitigation suggestions...", title="Alprina Mitigation"))
28 # Load findings
29 if report_file:
30 findings = _load_findings_from_report(report_file)
31 else:
32 findings = _load_findings_from_events()
34 if not findings:
35 console.print("[yellow]No findings to mitigate[/yellow]")
36 return
38 # Filter to specific finding if requested
39 if finding_id:
40 findings = [f for f in findings if f.get("id") == finding_id]
41 if not findings:
42 console.print(f"[red]Finding {finding_id} not found[/red]")
43 return
45 # Generate mitigations for each finding
46 for i, finding in enumerate(findings, 1):
47 console.print(f"\n[bold cyan]Finding {i}/{len(findings)}[/bold cyan]")
48 _generate_mitigation(finding)
51def _load_findings_from_events() -> list:
52 """Load findings from event log."""
53 events = load_events()
54 findings = []
56 for event in events:
57 if event.get("type") in ["scan", "recon"]:
58 event_findings = event.get("findings", [])
59 if isinstance(event_findings, list):
60 findings.extend(event_findings)
62 return findings
65def _load_findings_from_report(report_path: Path) -> list:
66 """Load findings from a report file."""
67 import json
69 try:
70 with open(report_path, "r") as f:
71 report = json.load(f)
72 return report.get("findings", [])
73 except Exception as e:
74 console.print(f"[red]Error loading report: {e}[/red]")
75 return []
78def _generate_mitigation(finding: dict):
79 """
80 Generate AI-powered mitigation suggestion for a single finding.
82 Args:
83 finding: Finding dictionary with severity, type, description, location
84 """
85 # Display finding info
86 console.print(Panel(
87 f"[bold]Severity:[/bold] {finding.get('severity', 'UNKNOWN')}\n"
88 f"[bold]Type:[/bold] {finding.get('type', 'Unknown')}\n"
89 f"[bold]Description:[/bold] {finding.get('description', 'N/A')}\n"
90 f"[bold]Location:[/bold] {finding.get('location', 'N/A')}",
91 title="Finding Details"
92 ))
94 # Use Alprina security agent to generate mitigation
95 mitigation_prompt = f"""
96 Security Finding:
97 - Severity: {finding.get('severity')}
98 - Type: {finding.get('type')}
99 - Description: {finding.get('description')}
100 - Location: {finding.get('location')}
102 Provide:
103 1. Risk explanation
104 2. Step-by-step mitigation instructions
105 3. Code examples if applicable
106 4. Prevention best practices
107 """
109 try:
110 result = run_agent(
111 task="mitigation",
112 input_data=mitigation_prompt,
113 metadata=finding
114 )
116 mitigation_text = result.get("mitigation", "No specific mitigation available")
118 # Display mitigation as markdown
119 console.print("\n[bold green]Mitigation Guidance:[/bold green]")
120 console.print(Markdown(mitigation_text))
122 except Exception as e:
123 console.print(f"[red]Error generating mitigation: {e}[/red]")
125 # Provide fallback generic guidance
126 _provide_generic_mitigation(finding)
129def _provide_generic_mitigation(finding: dict):
130 """Provide generic mitigation guidance based on finding type."""
131 finding_type = finding.get("type", "").lower()
133 generic_mitigations = {
134 "hardcoded secret": """
135 ### Mitigation Steps:
136 1. **Remove** the hardcoded secret from the code immediately
137 2. **Rotate** the exposed credentials/keys
138 3. **Use environment variables** or a secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault)
139 4. **Add** sensitive files to `.gitignore`
140 5. **Audit** git history to ensure secret is not in past commits
142 ### Prevention:
143 - Use pre-commit hooks to scan for secrets
144 - Implement automated secret scanning in CI/CD
145 - Use tools like `git-secrets` or `trufflehog`
146 """,
148 "debug mode": """
149 ### Mitigation Steps:
150 1. **Disable** debug mode in production environments
151 2. **Use** environment-based configuration (e.g., `DEBUG=False` in production)
152 3. **Review** all debug-related settings
154 ### Prevention:
155 - Use separate config files for dev/staging/production
156 - Implement configuration validation in deployment pipeline
157 """,
159 "environment file": """
160 ### Mitigation Steps:
161 1. **Ensure** `.env` files are in `.gitignore`
162 2. **Remove** `.env` from git history if committed
163 3. **Use** `.env.example` template without actual secrets
165 ### Prevention:
166 - Never commit `.env` files
167 - Use environment-specific files (`.env.production`, `.env.development`)
168 - Document required environment variables
169 """,
170 }
172 mitigation = generic_mitigations.get(finding_type, """
173 ### General Security Best Practices:
174 1. Follow the principle of least privilege
175 2. Keep dependencies up to date
176 3. Implement proper input validation
177 4. Use security linters and scanners
178 5. Conduct regular security audits
179 """)
181 console.print(Markdown(mitigation))