Coverage for src/alprina_cli/report_generator.py: 7%
255 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"""
2Alprina Report Generator - Creates markdown security reports in .alprina/ folder.
3Generates comprehensive, professional security documentation.
4"""
6import os
7from pathlib import Path
8from typing import Dict, List, Any
9from datetime import datetime
10from loguru import logger
13def generate_security_reports(scan_results: dict, target_path: str, agent_type: str = "generic"):
14 """
15 Generate comprehensive security reports in .alprina/ folder.
17 Creates:
18 - SECURITY-REPORT.md: Full vulnerability analysis
19 - FINDINGS.md: Detailed findings with code snippets
20 - REMEDIATION.md: Step-by-step fix instructions
21 - EXECUTIVE-SUMMARY.md: Non-technical overview
22 - Agent-specific specialized reports (if applicable)
24 Args:
25 scan_results: Results from security scan
26 target_path: Path where scan was performed
27 agent_type: Type of agent that performed scan (for specialized reports)
28 """
29 try:
30 # Determine report directory
31 if os.path.isdir(target_path):
32 report_dir = Path(target_path) / ".alprina"
33 else:
34 # If target is a file, use parent directory
35 report_dir = Path(target_path).parent / ".alprina"
37 # Create .alprina directory
38 report_dir.mkdir(exist_ok=True)
39 logger.info(f"Creating security reports in: {report_dir}")
41 # Generate standard report files
42 _generate_security_report(scan_results, report_dir)
43 _generate_findings_report(scan_results, report_dir)
44 _generate_remediation_report(scan_results, report_dir)
45 _generate_executive_summary(scan_results, report_dir)
47 # Generate agent-specific specialized reports
48 if agent_type in SPECIALIZED_REPORT_GENERATORS:
49 logger.info(f"Generating specialized {agent_type} report")
50 generator = SPECIALIZED_REPORT_GENERATORS[agent_type]
51 generator(scan_results, report_dir)
53 logger.info("✓ Security reports generated successfully")
54 return str(report_dir)
56 except Exception as e:
57 logger.error(f"Error generating reports: {e}")
58 raise
61def _generate_security_report(results: dict, output_dir: Path):
62 """Generate SECURITY-REPORT.md - Full vulnerability analysis."""
64 findings = results.get("findings", [])
65 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
67 # Count findings by severity
68 severity_counts = {
69 "CRITICAL": len([f for f in findings if f.get("severity") == "CRITICAL"]),
70 "HIGH": len([f for f in findings if f.get("severity") == "HIGH"]),
71 "MEDIUM": len([f for f in findings if f.get("severity") == "MEDIUM"]),
72 "LOW": len([f for f in findings if f.get("severity") == "LOW"]),
73 "INFO": len([f for f in findings if f.get("severity") == "INFO"]),
74 }
76 report = f"""# 🔒 Alprina Security Report
78**Generated:** {scan_date}
79**Target:** {results.get('target', 'N/A')}
80**Scan Mode:** {results.get('mode', 'N/A')}
81**Profile:** {results.get('profile', 'default')}
82**Files Scanned:** {results.get('files_scanned', 0)}
84---
86## 📊 Executive Summary
88Total security findings: **{len(findings)}**
90### Severity Distribution
92| Severity | Count |
93|----------|-------|
94| 🔴 CRITICAL | {severity_counts['CRITICAL']} |
95| 🟠 HIGH | {severity_counts['HIGH']} |
96| 🟡 MEDIUM | {severity_counts['MEDIUM']} |
97| 🔵 LOW | {severity_counts['LOW']} |
98| ⚪ INFO | {severity_counts['INFO']} |
100---
102## 🎯 Risk Assessment
104"""
106 # Risk level determination
107 if severity_counts['CRITICAL'] > 0:
108 risk_level = "🔴 **CRITICAL RISK**"
109 risk_desc = "Immediate action required. Critical vulnerabilities detected that could lead to system compromise."
110 elif severity_counts['HIGH'] > 0:
111 risk_level = "🟠 **HIGH RISK**"
112 risk_desc = "Urgent attention needed. High-severity vulnerabilities require prompt remediation."
113 elif severity_counts['MEDIUM'] > 0:
114 risk_level = "🟡 **MEDIUM RISK**"
115 risk_desc = "Moderate security concerns detected. Address these issues in your next development cycle."
116 elif severity_counts['LOW'] > 0:
117 risk_level = "🔵 **LOW RISK**"
118 risk_desc = "Minor security issues detected. Consider addressing these during regular maintenance."
119 else:
120 risk_level = "🟢 **NO ISSUES**"
121 risk_desc = "No security vulnerabilities detected. Your code follows security best practices!"
123 report += f"""**Overall Risk Level:** {risk_level}
125{risk_desc}
127---
129## 🔍 Detailed Findings
131"""
133 # Group findings by severity
134 for severity in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"]:
135 severity_findings = [f for f in findings if f.get("severity") == severity]
137 if severity_findings:
138 severity_icons = {
139 "CRITICAL": "🔴",
140 "HIGH": "🟠",
141 "MEDIUM": "🟡",
142 "LOW": "🔵",
143 "INFO": "⚪"
144 }
146 report += f"\n### {severity_icons[severity]} {severity} Severity ({len(severity_findings)} issues)\n\n"
148 for i, finding in enumerate(severity_findings, 1):
149 report += f"""#### {i}. {finding.get('type', 'Security Issue')}
151**Location:** `{finding.get('location', 'N/A')}`
152"""
153 if finding.get('line'):
154 report += f"**Line:** {finding.get('line')} \n"
156 report += f"""**Description:** {finding.get('description', 'N/A')}
158---
160"""
162 report += """
163## 📝 Next Steps
1651. Review all **CRITICAL** and **HIGH** severity findings immediately
1662. Consult the **REMEDIATION.md** file for detailed fix instructions
1673. Implement fixes and re-scan to verify resolution
1684. Review **FINDINGS.md** for detailed technical analysis
1695. Share **EXECUTIVE-SUMMARY.md** with stakeholders
171---
173## 🛡️ About Alprina
175Alprina is an AI-powered security scanning platform that helps you find and fix vulnerabilities in your code.
177**Need help?**
178- Documentation: https://alprina.ai/docs
179- Support: support@alprina.ai
180- Dashboard: https://dashboard.alprina.ai
182---
184*Generated by Alprina Security Scanner*
185*Report ID: {results.get('scan_id', 'local-scan')}*
186"""
188 # Write report
189 output_file = output_dir / "SECURITY-REPORT.md"
190 output_file.write_text(report)
191 logger.info(f"✓ Created: {output_file}")
194def _generate_findings_report(results: dict, output_dir: Path):
195 """Generate FINDINGS.md - All vulnerabilities with code context."""
197 findings = results.get("findings", [])
198 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
200 report = f"""# 🔍 Security Findings - Detailed Analysis
202**Generated:** {scan_date}
203**Total Findings:** {len(findings)}
205---
207"""
209 if not findings:
210 report += """## ✅ No Security Issues Found!
212Your code passed all security checks. Great work maintaining secure coding practices!
214### What We Checked:
215- SQL Injection vulnerabilities
216- Cross-Site Scripting (XSS)
217- Hardcoded secrets and credentials
218- Authentication/Authorization flaws
219- Insecure configurations
220- Input validation issues
221- Cryptographic weaknesses
222- Dependency vulnerabilities
224Keep up the good security practices!
225"""
226 else:
227 # Group by file
228 findings_by_file = {}
229 for finding in findings:
230 location = finding.get('location', 'unknown')
231 if location not in findings_by_file:
232 findings_by_file[location] = []
233 findings_by_file[location].append(finding)
235 for file_path, file_findings in findings_by_file.items():
236 report += f"## 📄 File: `{file_path}`\n\n"
237 report += f"**Issues Found:** {len(file_findings)}\n\n"
239 for i, finding in enumerate(file_findings, 1):
240 severity_icons = {
241 "CRITICAL": "🔴",
242 "HIGH": "🟠",
243 "MEDIUM": "🟡",
244 "LOW": "🔵",
245 "INFO": "⚪"
246 }
248 icon = severity_icons.get(finding.get("severity"), "⚪")
250 report += f"""### {icon} Finding #{i}: {finding.get('type', 'Security Issue')}
252**Severity:** {finding.get('severity', 'N/A')}
253"""
254 if finding.get('line'):
255 report += f"**Line Number:** {finding.get('line')} \n"
257 report += f"""
258**Description:**
259{finding.get('description', 'N/A')}
261**Risk:**
262{_get_risk_explanation(finding)}
264**CWE Reference:**
265{_get_cwe_reference(finding.get('type', ''))}
267---
269"""
271 report += """
272## 📚 Additional Resources
274### OWASP Top 10
275- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
276- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
278### Secure Coding Guidelines
279- [NIST Secure Software Development Framework](https://csrc.nist.gov/projects/ssdf)
280- [CWE/SANS Top 25](https://cwe.mitre.org/top25/)
282---
284*For remediation steps, see REMEDIATION.md*
285*For executive summary, see EXECUTIVE-SUMMARY.md*
286"""
288 output_file = output_dir / "FINDINGS.md"
289 output_file.write_text(report)
290 logger.info(f"✓ Created: {output_file}")
293def _generate_remediation_report(results: dict, output_dir: Path):
294 """Generate REMEDIATION.md - Step-by-step fix instructions."""
296 findings = results.get("findings", [])
297 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
299 report = f"""# 🛠️ Remediation Guide
301**Generated:** {scan_date}
302**Findings to Address:** {len(findings)}
304---
306## 📋 How to Use This Guide
308This guide provides step-by-step instructions to fix each security issue found in your code.
310**Priority Order:**
3111. 🔴 CRITICAL - Fix immediately (within 24 hours)
3122. 🟠 HIGH - Fix urgently (within 1 week)
3133. 🟡 MEDIUM - Fix soon (within 1 month)
3144. 🔵 LOW - Fix when convenient
3155. ⚪ INFO - Optional improvements
317---
319"""
321 if not findings:
322 report += "## ✅ No Issues to Remediate\n\nYour code is secure! No action needed.\n"
323 else:
324 # Group by severity for prioritization
325 for severity in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"]:
326 severity_findings = [f for f in findings if f.get("severity") == severity]
328 if severity_findings:
329 severity_icons = {
330 "CRITICAL": "🔴",
331 "HIGH": "🟠",
332 "MEDIUM": "🟡",
333 "LOW": "🔵",
334 "INFO": "⚪"
335 }
337 report += f"\n## {severity_icons[severity]} {severity} Priority Fixes\n\n"
339 for i, finding in enumerate(severity_findings, 1):
340 report += f"""### Fix #{i}: {finding.get('type', 'Security Issue')}
342**File:** `{finding.get('location', 'N/A')}`
343"""
344 if finding.get('line'):
345 report += f"**Line:** {finding.get('line')} \n"
347 report += f"""
348**Issue:**
349{finding.get('description', 'N/A')}
351**How to Fix:**
353{_get_remediation_steps(finding)}
355**Verification:**
3561. Apply the fix to your code
3572. Run Alprina scan again: `alprina scan {results.get('target', '.')}`
3583. Verify this issue is resolved
360---
362"""
364 report += """
365## 🔄 Re-scanning After Fixes
367After implementing fixes, run a new scan to verify:
369```bash
370alprina scan {target}
371```
373You can also view your scan history in the dashboard:
374https://dashboard.alprina.ai
376---
378## 💡 Best Practices
380### Preventive Measures
3821. **Use a Security Linter** - Integrate Alprina into your CI/CD pipeline
3832. **Code Reviews** - Have security-focused code reviews
3843. **Dependency Updates** - Keep dependencies up to date
3854. **Security Training** - Educate your team on secure coding
387### Recommended Tools
389- **Pre-commit Hooks** - Run Alprina before each commit
390- **CI/CD Integration** - Automated security scanning on PRs
391- **IDE Plugins** - Real-time security feedback while coding
393---
395## 📞 Need Help?
397**Alprina Support:**
398- Documentation: https://alprina.ai/docs
399- Email: support@alprina.ai
400- Dashboard: https://dashboard.alprina.ai
402**Security Resources:**
403- OWASP: https://owasp.org
404- CWE: https://cwe.mitre.org
405- NIST: https://csrc.nist.gov
407---
409*After fixing issues, re-run the scan to update this report*
410""".replace("{target}", results.get('target', '.'))
412 output_file = output_dir / "REMEDIATION.md"
413 output_file.write_text(report)
414 logger.info(f"✓ Created: {output_file}")
417def _generate_executive_summary(results: dict, output_dir: Path):
418 """Generate EXECUTIVE-SUMMARY.md - Non-technical overview."""
420 findings = results.get("findings", [])
421 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
423 # Count findings by severity
424 severity_counts = {
425 "CRITICAL": len([f for f in findings if f.get("severity") == "CRITICAL"]),
426 "HIGH": len([f for f in findings if f.get("severity") == "HIGH"]),
427 "MEDIUM": len([f for f in findings if f.get("severity") == "MEDIUM"]),
428 "LOW": len([f for f in findings if f.get("severity") == "LOW"]),
429 }
431 report = f"""# 📊 Executive Summary - Security Assessment
433**Report Date:** {scan_date}
434**Project:** {results.get('target', 'N/A')}
435**Scan Coverage:** {results.get('files_scanned', 0)} files analyzed
437---
439## 🎯 Overview
441This report provides a high-level summary of the security assessment performed on your codebase using Alprina's AI-powered security scanner.
443### What We Found
445**Total Security Findings:** {len(findings)}
447"""
449 # Risk assessment
450 if severity_counts['CRITICAL'] > 0:
451 risk_badge = "🔴 CRITICAL RISK"
452 recommendation = "**Immediate action required.** Critical vulnerabilities detected that could lead to data breaches or system compromise."
453 elif severity_counts['HIGH'] > 0:
454 risk_badge = "🟠 HIGH RISK"
455 recommendation = "**Urgent attention needed.** Significant security vulnerabilities require prompt remediation to protect your assets."
456 elif severity_counts['MEDIUM'] > 0:
457 risk_badge = "🟡 MEDIUM RISK"
458 recommendation = "**Action recommended.** Moderate security concerns should be addressed in your next development cycle."
459 elif severity_counts['LOW'] > 0:
460 risk_badge = "🔵 LOW RISK"
461 recommendation = "**Minor improvements suggested.** Address these issues during regular maintenance for enhanced security."
462 else:
463 risk_badge = "🟢 SECURE"
464 recommendation = "**No security issues detected.** Your codebase follows security best practices!"
466 report += f"""**Security Risk Level:** {risk_badge}
468{recommendation}
470---
472## 📈 Findings Breakdown
474| Priority Level | Count | Action Timeline |
475|---------------|-------|-----------------|
476| 🔴 Critical | {severity_counts['CRITICAL']} | Fix within 24 hours |
477| 🟠 High | {severity_counts['HIGH']} | Fix within 1 week |
478| 🟡 Medium | {severity_counts['MEDIUM']} | Fix within 1 month |
479| 🔵 Low | {severity_counts['LOW']} | Fix when convenient |
481---
483## 💼 Business Impact
485"""
487 if severity_counts['CRITICAL'] > 0:
488 report += """### Critical Security Risks
490**Potential Impact:**
491- Data breach or unauthorized access
492- System compromise
493- Regulatory compliance violations (GDPR, HIPAA, etc.)
494- Reputational damage
495- Financial losses
497**Recommended Action:**
498Allocate immediate resources to address critical vulnerabilities. Consider engaging security experts if internal capacity is limited.
500"""
501 elif severity_counts['HIGH'] > 0:
502 report += """### Significant Security Concerns
504**Potential Impact:**
505- Elevated risk of security incidents
506- Possible data exposure
507- Compliance audit findings
508- Customer trust erosion
510**Recommended Action:**
511Prioritize these fixes in the current sprint. Ensure development team has necessary security training and resources.
513"""
514 else:
515 report += """### Security Posture
517Your current security posture is good. Continue maintaining security best practices and regular scanning to ensure ongoing protection.
519"""
521 report += """---
523## 📋 Recommended Next Steps
525### Immediate Actions (This Week)
5261. ✅ Review this executive summary with stakeholders
5272. ✅ Share REMEDIATION.md with development team
5283. ✅ Prioritize fixes based on severity levels
5294. ✅ Allocate resources for remediation work
531### Short-term Actions (This Month)
5321. 🔨 Implement fixes for all HIGH and CRITICAL findings
5332. 🔄 Re-scan codebase after fixes
5343. 📚 Conduct security training for development team
5354. 🔍 Review security processes and policies
537### Long-term Actions (This Quarter)
5381. 🚀 Integrate Alprina into CI/CD pipeline
5392. 📊 Establish regular security scanning schedule
5403. 🎓 Ongoing security awareness training
5414. 📈 Track and report security metrics
543---
545## 🛡️ About This Assessment
547**Scanning Technology:**
548Alprina uses AI-powered security agents to detect vulnerabilities including:
549- SQL Injection
550- Cross-Site Scripting (XSS)
551- Authentication & Authorization flaws
552- Hardcoded secrets
553- Insecure configurations
554- And 100+ other vulnerability types
556**Coverage:**
557This scan analyzed {results.get('files_scanned', 0)} files in your codebase using industry-standard security frameworks (OWASP, CWE, NIST).
559**Limitations:**
560Automated scanning is highly effective but should be complemented with:
561- Manual security code reviews
562- Penetration testing for production systems
563- Ongoing security monitoring
565---
567## 📞 Questions or Concerns?
569**For Technical Details:**
570Review the SECURITY-REPORT.md and FINDINGS.md files for complete technical analysis.
572**For Remediation:**
573See REMEDIATION.md for step-by-step fix instructions.
575**For Support:**
576- Dashboard: https://dashboard.alprina.ai
577- Documentation: https://alprina.ai/docs
578- Email: support@alprina.ai
580---
582## 📊 Metrics & Tracking
584**Scan ID:** {results.get('scan_id', 'local-scan')}
585**View in Dashboard:** [https://dashboard.alprina.ai](https://dashboard.alprina.ai)
587Track your security progress over time:
588- Vulnerability trends
589- Fix rates
590- Security score
591- Compliance status
593---
595*This executive summary is intended for non-technical stakeholders. For technical details, refer to the complete security report.*
597**Generated by Alprina Security Platform**
598**Trusted by security-conscious development teams worldwide**
599"""
601 output_file = output_dir / "EXECUTIVE-SUMMARY.md"
602 output_file.write_text(report)
603 logger.info(f"✓ Created: {output_file}")
606def _get_risk_explanation(finding: dict) -> str:
607 """Get risk explanation based on finding type."""
609 risk_explanations = {
610 "SQL Injection": "Attackers could execute arbitrary database queries, leading to data theft, modification, or deletion.",
611 "XSS": "Malicious scripts could be injected and executed in users' browsers, stealing credentials or performing unauthorized actions.",
612 "Hardcoded Secret": "Exposed credentials could allow unauthorized access to systems, databases, or third-party services.",
613 "Authentication Bypass": "Attackers could gain unauthorized access without valid credentials.",
614 "Insecure Configuration": "System misconfiguration could expose sensitive data or create security vulnerabilities.",
615 "Debug Mode": "Debug information could reveal system internals and sensitive data to attackers.",
616 "Weak Cryptography": "Data encryption may be compromised, exposing sensitive information.",
617 }
619 finding_type = finding.get('type', '')
620 return risk_explanations.get(finding_type, "This vulnerability could be exploited by attackers to compromise system security.")
623def _get_cwe_reference(finding_type: str) -> str:
624 """Get CWE reference for finding type."""
626 cwe_mapping = {
627 "SQL Injection": "[CWE-89: SQL Injection](https://cwe.mitre.org/data/definitions/89.html)",
628 "XSS": "[CWE-79: Cross-site Scripting](https://cwe.mitre.org/data/definitions/79.html)",
629 "Hardcoded Secret": "[CWE-798: Use of Hard-coded Credentials](https://cwe.mitre.org/data/definitions/798.html)",
630 "Authentication Bypass": "[CWE-287: Improper Authentication](https://cwe.mitre.org/data/definitions/287.html)",
631 "Insecure Configuration": "[CWE-16: Configuration](https://cwe.mitre.org/data/definitions/16.html)",
632 "Debug Mode": "[CWE-489: Active Debug Code](https://cwe.mitre.org/data/definitions/489.html)",
633 }
635 return cwe_mapping.get(finding_type, "[CWE Database](https://cwe.mitre.org/)")
638def _get_remediation_steps(finding: dict) -> str:
639 """Get specific remediation steps based on finding type."""
641 remediation_guides = {
642 "SQL Injection": """
643**Step 1:** Use parameterized queries or prepared statements
645```python
646# ❌ Vulnerable Code
647query = f"SELECT * FROM users WHERE id = {user_id}"
648cursor.execute(query)
650# ✅ Secure Code
651query = "SELECT * FROM users WHERE id = %s"
652cursor.execute(query, (user_id,))
653```
655**Step 2:** Validate and sanitize all user input
656**Step 3:** Use an ORM (like SQLAlchemy) with built-in protections
657**Step 4:** Implement least privilege database access
658""",
660 "Hardcoded Secret": """
661**Step 1:** Move secrets to environment variables
663```python
664# ❌ Vulnerable Code
665API_KEY = "sk_live_abc123xyz"
667# ✅ Secure Code
668import os
669API_KEY = os.getenv("API_KEY")
670```
672**Step 2:** Use a `.env` file (add to `.gitignore`)
673**Step 3:** Use a secret management service (AWS Secrets Manager, HashiCorp Vault)
674**Step 4:** Rotate the exposed credential immediately
675**Step 5:** Scan git history and remove the secret
676""",
678 "XSS": """
679**Step 1:** Escape all user-generated content before rendering
681```python
682# ❌ Vulnerable Code
683return f"<div>{user_input}</div>"
685# ✅ Secure Code
686from html import escape
687return f"<div>{escape(user_input)}</div>"
688```
690**Step 2:** Use Content Security Policy (CSP) headers
691**Step 3:** Validate input on both client and server side
692**Step 4:** Use a template engine with auto-escaping
693""",
695 "Debug Mode": """
696**Step 1:** Disable debug mode in production
698```python
699# ❌ Vulnerable Code
700DEBUG = True
702# ✅ Secure Code
703DEBUG = os.getenv("DEBUG", "False") == "True"
704```
706**Step 2:** Set appropriate environment variables
707**Step 3:** Use different config files for dev/prod
708**Step 4:** Remove debug endpoints from production
709""",
710 }
712 finding_type = finding.get('type', '')
714 if finding_type in remediation_guides:
715 return remediation_guides[finding_type]
716 else:
717 return f"""
718**General Remediation Steps:**
7201. Review the code at `{finding.get('location', 'N/A')}`
7212. Understand the security risk described above
7223. Implement security best practices for this vulnerability type
7234. Test the fix in a development environment
7245. Deploy the fix to production
7256. Re-scan with Alprina to verify resolution
727**Need specific guidance?**
728Contact Alprina support at support@alprina.ai with your Scan ID.
729"""
732# ============================================================================
733# SPECIALIZED REPORT GENERATORS FOR DIFFERENT AGENT TYPES
734# ============================================================================
736def _generate_red_team_report(results: dict, output_dir: Path):
737 """Generate RED-TEAM-REPORT.md - Penetration testing findings."""
739 findings = results.get("findings", [])
740 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
742 report = f"""# ⚔️ Red Team Assessment Report
744**Assessment Date:** {scan_date}
745**Target:** {results.get('target', 'N/A')}
746**Engagement Type:** {results.get('engagement_type', 'Offensive Security Testing')}
748---
750## 📋 Executive Summary
752This report documents the findings from an offensive security assessment (red team) performed on the target system. The assessment simulates real-world attack scenarios to identify exploitable vulnerabilities.
754### Assessment Scope
756**Total Attack Vectors Tested:** {len(findings)}
757**Successful Exploits:** {len([f for f in findings if f.get('exploitable', False)])}
758**Attack Surface Coverage:** {results.get('coverage', 'Comprehensive')}
760---
762## 🎯 Attack Vectors Identified
764"""
766 # Group by attack type
767 attack_types = {}
768 for finding in findings:
769 attack_type = finding.get('attack_type', finding.get('type', 'Unknown'))
770 if attack_type not in attack_types:
771 attack_types[attack_type] = []
772 attack_types[attack_type].append(finding)
774 for attack_type, vectors in attack_types.items():
775 exploitable = len([v for v in vectors if v.get('exploitable', False)])
777 report += f"""### {attack_type}
779**Vectors Found:** {len(vectors)}
780**Exploitable:** {exploitable}
782"""
783 for i, vector in enumerate(vectors, 1):
784 exploit_status = "✅ EXPLOITABLE" if vector.get('exploitable') else "⚠️ POTENTIAL"
786 report += f"""#### {i}. {vector.get('title', 'Attack Vector')}
788**Status:** {exploit_status}
789**Severity:** {vector.get('severity', 'MEDIUM')}
790**Location:** `{vector.get('location', 'N/A')}`
792**Attack Description:**
793{vector.get('description', 'N/A')}
795**Exploitation Steps:**
796{vector.get('exploit_steps', 'Manual testing required')}
798**Impact:**
799{vector.get('impact', 'Could lead to system compromise')}
801---
803"""
805 report += """
806## 🛡️ Defense Recommendations
808### Immediate Actions
8091. Patch all exploitable vulnerabilities within 24 hours
8102. Implement WAF rules to block identified attack patterns
8113. Enable security monitoring for attempted exploits
8124. Review and harden authentication mechanisms
814### Strategic Improvements
8151. Implement defense-in-depth architecture
8162. Regular red team assessments (quarterly)
8173. Security awareness training for development team
8184. Incident response plan updates
820---
822## 📊 Attack Surface Analysis
824### High-Risk Areas
825"""
827 # Identify high-risk areas
828 high_risk = [f for f in findings if f.get('severity') in ['CRITICAL', 'HIGH']]
829 if high_risk:
830 for area in high_risk[:5]:
831 report += f"- `{area.get('location', 'N/A')}` - {area.get('type', 'Security Issue')}\n"
832 else:
833 report += "- No critical attack vectors identified\n"
835 report += f"""
837### Recommendations by Priority
839**P0 (Critical):** {len([f for f in findings if f.get('severity') == 'CRITICAL'])} items - Fix immediately
840**P1 (High):** {len([f for f in findings if f.get('severity') == 'HIGH'])} items - Fix within 1 week
841**P2 (Medium):** {len([f for f in findings if f.get('severity') == 'MEDIUM'])} items - Fix within 1 month
843---
845## 🔬 Methodology
847**Assessment Approach:**
848- Black-box testing from external attacker perspective
849- Exploit development and validation
850- Post-exploitation analysis
851- Privilege escalation testing
853**Tools Used:**
854- Alprina Red Team Agent
855- Industry-standard penetration testing tools
856- Custom exploit scripts
858---
860*This is a confidential security assessment. Distribution should be limited to authorized personnel only.*
862**Assessed by:** Alprina Red Team Agent
863**Report ID:** {results.get('scan_id', 'red-team-' + datetime.now().strftime('%Y%m%d'))}
864"""
866 output_file = output_dir / "RED-TEAM-REPORT.md"
867 output_file.write_text(report)
868 logger.info(f"✓ Created: {output_file}")
871def _generate_blue_team_report(results: dict, output_dir: Path):
872 """Generate BLUE-TEAM-REPORT.md - Defensive posture assessment."""
874 findings = results.get("findings", [])
875 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
877 report = f"""# 🛡️ Blue Team Defense Posture Report
879**Assessment Date:** {scan_date}
880**Target:** {results.get('target', 'N/A')}
881**Assessment Type:** Defensive Security Evaluation
883---
885## 📋 Executive Summary
887This report evaluates the current security posture and defensive capabilities of the target system. It identifies gaps in security controls, monitoring, and incident response readiness.
889### Security Posture Score
891**Overall Score:** {results.get('security_score', 'N/A')}/100
892**Control Coverage:** {len(findings)} security controls evaluated
893**Gaps Identified:** {len([f for f in findings if f.get('status') == 'missing' or f.get('severity') in ['HIGH', 'CRITICAL']])}
895---
897## 🔍 Security Controls Assessment
899"""
901 # Group by control category
902 categories = {}
903 for finding in findings:
904 category = finding.get('category', 'General')
905 if category not in categories:
906 categories[category] = []
907 categories[category].append(finding)
909 for category, controls in categories.items():
910 implemented = len([c for c in controls if c.get('status') == 'implemented'])
911 missing = len([c for c in controls if c.get('status') == 'missing'])
912 partial = len([c for c in controls if c.get('status') == 'partial'])
914 report += f"""### {category}
916**Total Controls:** {len(controls)}
917**✅ Implemented:** {implemented}
918**⚠️ Partial:** {partial}
919**❌ Missing:** {missing}
921"""
923 for i, control in enumerate(controls, 1):
924 status_icons = {
925 'implemented': '✅',
926 'partial': '⚠️',
927 'missing': '❌',
928 'weak': '🟡'
929 }
930 icon = status_icons.get(control.get('status', 'unknown'), '❓')
932 report += f"""#### {icon} {i}. {control.get('title', 'Security Control')}
934**Status:** {control.get('status', 'Unknown').upper()}
935**Impact:** {control.get('severity', 'MEDIUM')}
937**Assessment:**
938{control.get('description', 'N/A')}
940**Recommendation:**
941{control.get('recommendation', 'Implement this security control')}
943---
945"""
947 report += """
948## 🎯 Priority Improvements
950### Critical Gaps (Fix Immediately)
951"""
953 critical = [f for f in findings if f.get('severity') == 'CRITICAL']
954 if critical:
955 for gap in critical:
956 report += f"- {gap.get('title', 'Critical Gap')}: {gap.get('recommendation', 'Implement immediately')}\n"
957 else:
958 report += "- No critical gaps identified ✅\n"
960 report += """
962### High Priority (Fix This Month)
963"""
965 high = [f for f in findings if f.get('severity') == 'HIGH']
966 if high:
967 for gap in high[:5]:
968 report += f"- {gap.get('title', 'High Priority Gap')}\n"
969 else:
970 report += "- No high-priority gaps identified ✅\n"
972 report += f"""
974---
976## 📊 Defensive Metrics
978### Detection Capabilities
979- **Logging Coverage:** {results.get('logging_coverage', 'N/A')}
980- **SIEM Integration:** {results.get('siem_status', 'Not evaluated')}
981- **Alert Rules:** {results.get('alert_rules', 'N/A')} configured
983### Response Readiness
984- **Incident Response Plan:** {results.get('ir_plan_status', 'Not evaluated')}
985- **Backup Strategy:** {results.get('backup_status', 'Not evaluated')}
986- **Recovery Time Objective:** {results.get('rto', 'Not defined')}
988### Security Monitoring
989- **Real-time Monitoring:** {results.get('monitoring_status', 'Not evaluated')}
990- **Threat Intelligence:** {results.get('threat_intel', 'Not evaluated')}
991- **Vulnerability Scanning:** {results.get('vuln_scan_frequency', 'Not evaluated')}
993---
995## 🔐 Recommended Security Controls
997### Immediate Implementation
9981. Enable comprehensive logging and monitoring
9992. Implement SIEM or security analytics platform
10003. Deploy endpoint detection and response (EDR)
10014. Configure automated backup systems
10025. Establish incident response procedures
1004### Medium-term Goals
10051. Implement zero-trust architecture
10062. Deploy web application firewall (WAF)
10073. Establish security operations center (SOC)
10084. Implement security awareness training program
10095. Regular security assessments and audits
1011---
1013## 📈 Improvement Roadmap
1015### Month 1
1016- Address all critical security gaps
1017- Implement basic logging and monitoring
1018- Establish incident response team
1020### Quarter 1
1021- Deploy security tools (SIEM, EDR, WAF)
1022- Complete high-priority improvements
1023- Conduct tabletop exercises
1025### Year 1
1026- Achieve target security posture
1027- Establish continuous monitoring
1028- Regular security assessments
1029- Ongoing team training
1031---
1033*This assessment is intended for internal security team use. Treat as confidential.*
1035**Assessed by:** Alprina Blue Team Agent
1036**Report ID:** {results.get('scan_id', 'blue-team-' + datetime.now().strftime('%Y%m%d'))}
1037"""
1039 output_file = output_dir / "BLUE-TEAM-REPORT.md"
1040 output_file.write_text(report)
1041 logger.info(f"✓ Created: {output_file}")
1044def _generate_dfir_report(results: dict, output_dir: Path):
1045 """Generate DFIR-REPORT.md - Digital forensics and incident response findings."""
1047 findings = results.get("findings", [])
1048 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
1050 report = f"""# 🔬 Digital Forensics & Incident Response Report
1052**Analysis Date:** {scan_date}
1053**Target:** {results.get('target', 'N/A')}
1054**Analysis Type:** {results.get('analysis_type', 'Forensic Analysis')}
1055**Analyst:** Alprina DFIR Agent
1057---
1059## 📋 Executive Summary
1061This report documents the forensic analysis performed on the target system. The analysis aimed to identify indicators of compromise (IOCs), timeline of events, and preserve evidence for potential investigation.
1063### Key Findings
1065**Total Artifacts Analyzed:** {results.get('artifacts_analyzed', len(findings))}
1066**IOCs Identified:** {len([f for f in findings if f.get('ioc', False)])}
1067**Evidence Items:** {len([f for f in findings if f.get('evidence', False)])}
1069---
1071## 🕵️ Indicators of Compromise (IOCs)
1073"""
1075 iocs = [f for f in findings if f.get('ioc', False)]
1076 if iocs:
1077 for i, ioc in enumerate(iocs, 1):
1078 report += f"""### IOC #{i}: {ioc.get('title', 'Indicator of Compromise')}
1080**Type:** {ioc.get('ioc_type', 'Unknown')}
1081**Severity:** {ioc.get('severity', 'MEDIUM')}
1082**Location:** `{ioc.get('location', 'N/A')}`
1083**Timestamp:** {ioc.get('timestamp', 'Unknown')}
1085**Description:**
1086{ioc.get('description', 'N/A')}
1088**Hash Values:**
1089```
1090MD5: {ioc.get('md5', 'N/A')}
1091SHA256: {ioc.get('sha256', 'N/A')}
1092```
1094**Evidence Chain:**
1095{ioc.get('evidence_chain', 'See evidence log')}
1097---
1099"""
1100 else:
1101 report += "No indicators of compromise identified in this analysis.\n\n"
1103 report += """
1104## ⏱️ Timeline Reconstruction
1106"""
1108 # Create timeline from findings
1109 timeline_items = sorted([f for f in findings if f.get('timestamp')],
1110 key=lambda x: x.get('timestamp', ''))
1112 if timeline_items:
1113 report += "| Timestamp | Event | Description | Severity |\n"
1114 report += "|-----------|-------|-------------|----------|\n"
1116 for item in timeline_items[:20]: # Limit to first 20
1117 report += f"| {item.get('timestamp', 'Unknown')} | {item.get('title', 'Event')} | {item.get('description', 'N/A')[:50]}... | {item.get('severity', 'INFO')} |\n"
1118 else:
1119 report += "Timeline reconstruction not available (no timestamps in findings)\n"
1121 report += f"""
1123---
1125## 📁 Evidence Collection
1127### Artifacts Preserved
1128"""
1130 evidence_items = [f for f in findings if f.get('evidence', False)]
1131 if evidence_items:
1132 for item in evidence_items:
1133 report += f"- `{item.get('location', 'N/A')}` - {item.get('title', 'Evidence item')}\n"
1134 else:
1135 report += "- No specific evidence items flagged in this scan\n"
1137 report += f"""
1139### Chain of Custody
1140**Analysis Start:** {scan_date}
1141**Analysis End:** {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
1142**Analyst:** Alprina DFIR Agent
1143**Analysis Tools:** Alprina Security Platform v1.0
1144**Evidence Hash:** {results.get('evidence_hash', 'N/A')}
1146---
1148## 🔍 Analysis Findings
1150### System State
1151- **System Integrity:** {results.get('system_integrity', 'Not evaluated')}
1152- **Recent Modifications:** {len([f for f in findings if 'modified' in f.get('type', '').lower()])} items
1153- **Suspicious Activity:** {len([f for f in findings if f.get('suspicious', False)])} indicators
1155### Network Activity
1156- **Network Connections:** {results.get('network_connections', 'Not analyzed')}
1157- **Outbound Traffic:** {results.get('outbound_traffic', 'Not analyzed')}
1158- **DNS Queries:** {results.get('dns_queries', 'Not analyzed')}
1160### File System
1161- **Modified Files:** {len([f for f in findings if f.get('modified', False)])}
1162- **New Files:** {len([f for f in findings if f.get('new_file', False)])}
1163- **Deleted Files:** {len([f for f in findings if f.get('deleted', False)])}
1165---
1167## 🎯 Incident Analysis
1169### Attack Vector Assessment
1170"""
1172 attack_vectors = [f for f in findings if 'attack' in f.get('type', '').lower()]
1173 if attack_vectors:
1174 for vector in attack_vectors:
1175 report += f"- **{vector.get('title')}:** {vector.get('description', 'N/A')}\n"
1176 else:
1177 report += "- No clear attack vectors identified\n"
1179 report += """
1181### Lateral Movement Indicators
1182"""
1184 lateral = [f for f in findings if 'lateral' in f.get('description', '').lower()]
1185 if lateral:
1186 for item in lateral:
1187 report += f"- {item.get('title', 'Lateral movement detected')}\n"
1188 else:
1189 report += "- No lateral movement indicators detected\n"
1191 report += """
1193### Data Exfiltration Risk
1194"""
1196 exfiltration = [f for f in findings if 'exfiltration' in f.get('description', '').lower() or 'data transfer' in f.get('description', '').lower()]
1197 if exfiltration:
1198 report += "⚠️ **Potential data exfiltration detected**\n\n"
1199 for item in exfiltration:
1200 report += f"- {item.get('title')}: {item.get('description', 'N/A')}\n"
1201 else:
1202 report += "✅ No data exfiltration indicators identified\n"
1204 report += """
1206---
1208## 📋 Recommendations
1210### Immediate Actions
12111. Isolate affected systems if compromise confirmed
12122. Preserve all evidence for potential legal proceedings
12133. Reset credentials for potentially compromised accounts
12144. Conduct full system integrity check
12155. Review all timeline events with security team
1217### Investigation Next Steps
12181. Expand analysis to related systems
12192. Review logs for additional IOCs
12203. Conduct memory forensics if warranted
12214. Interview system administrators and users
12225. Engage law enforcement if criminal activity detected
1224### Long-term Improvements
12251. Implement enhanced logging and monitoring
12262. Deploy EDR solution for better visibility
12273. Establish incident response procedures
12284. Regular forensic readiness assessments
12295. Security awareness training for staff
1231---
1233## 📝 Analysis Notes
1235**Methodology:**
1236- Static file system analysis
1237- Log file review
1238- IOC matching against threat intelligence
1239- Timeline reconstruction from artifacts
1240- Evidence preservation procedures followed
1242**Limitations:**
1243- Analysis based on available artifacts at time of scan
1244- Memory forensics not performed
1245- Network capture not available
1246- Live system analysis not conducted
1248---
1250*This is a confidential forensic report. Handle according to evidence preservation procedures.*
1252**Report ID:** {results.get('scan_id', 'dfir-' + datetime.now().strftime('%Y%m%d'))}
1253**Analyst:** Alprina DFIR Agent
1254**Classification:** CONFIDENTIAL - LEGAL PRIVILEGE MAY APPLY
1255"""
1257 output_file = output_dir / "DFIR-REPORT.md"
1258 output_file.write_text(report)
1259 logger.info(f"✓ Created: {output_file}")
1262# Registry of specialized report generators
1263SPECIALIZED_REPORT_GENERATORS = {
1264 "red_teamer": _generate_red_team_report,
1265 "red-team": _generate_red_team_report,
1266 "offensive-security": _generate_red_team_report,
1268 "blue_teamer": _generate_blue_team_report,
1269 "blue-team": _generate_blue_team_report,
1270 "defensive-security": _generate_blue_team_report,
1272 "dfir": _generate_dfir_report,
1273 "forensics": _generate_dfir_report,
1274 "incident-response": _generate_dfir_report,
1275}