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

1""" 

2Alprina Report Generator - Creates markdown security reports in .alprina/ folder. 

3Generates comprehensive, professional security documentation. 

4""" 

5 

6import os 

7from pathlib import Path 

8from typing import Dict, List, Any 

9from datetime import datetime 

10from loguru import logger 

11 

12 

13def generate_security_reports(scan_results: dict, target_path: str, agent_type: str = "generic"): 

14 """ 

15 Generate comprehensive security reports in .alprina/ folder. 

16 

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) 

23 

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" 

36 

37 # Create .alprina directory 

38 report_dir.mkdir(exist_ok=True) 

39 logger.info(f"Creating security reports in: {report_dir}") 

40 

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) 

46 

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) 

52 

53 logger.info("✓ Security reports generated successfully") 

54 return str(report_dir) 

55 

56 except Exception as e: 

57 logger.error(f"Error generating reports: {e}") 

58 raise 

59 

60 

61def _generate_security_report(results: dict, output_dir: Path): 

62 """Generate SECURITY-REPORT.md - Full vulnerability analysis.""" 

63 

64 findings = results.get("findings", []) 

65 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

66 

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 } 

75 

76 report = f"""# 🔒 Alprina Security Report 

77 

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)} 

83 

84--- 

85 

86## 📊 Executive Summary 

87 

88Total security findings: **{len(findings)}** 

89 

90### Severity Distribution 

91 

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']} | 

99 

100--- 

101 

102## 🎯 Risk Assessment 

103 

104""" 

105 

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!" 

122 

123 report += f"""**Overall Risk Level:** {risk_level} 

124 

125{risk_desc} 

126 

127--- 

128 

129## 🔍 Detailed Findings 

130 

131""" 

132 

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] 

136 

137 if severity_findings: 

138 severity_icons = { 

139 "CRITICAL": "🔴", 

140 "HIGH": "🟠", 

141 "MEDIUM": "🟡", 

142 "LOW": "🔵", 

143 "INFO": "⚪" 

144 } 

145 

146 report += f"\n### {severity_icons[severity]} {severity} Severity ({len(severity_findings)} issues)\n\n" 

147 

148 for i, finding in enumerate(severity_findings, 1): 

149 report += f"""#### {i}. {finding.get('type', 'Security Issue')} 

150 

151**Location:** `{finding.get('location', 'N/A')}` 

152""" 

153 if finding.get('line'): 

154 report += f"**Line:** {finding.get('line')} \n" 

155 

156 report += f"""**Description:** {finding.get('description', 'N/A')} 

157 

158--- 

159 

160""" 

161 

162 report += """ 

163## 📝 Next Steps 

164 

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 

170 

171--- 

172 

173## 🛡️ About Alprina 

174 

175Alprina is an AI-powered security scanning platform that helps you find and fix vulnerabilities in your code. 

176 

177**Need help?** 

178- Documentation: https://alprina.ai/docs 

179- Support: support@alprina.ai 

180- Dashboard: https://dashboard.alprina.ai 

181 

182--- 

183 

184*Generated by Alprina Security Scanner* 

185*Report ID: {results.get('scan_id', 'local-scan')}* 

186""" 

187 

188 # Write report 

189 output_file = output_dir / "SECURITY-REPORT.md" 

190 output_file.write_text(report) 

191 logger.info(f"✓ Created: {output_file}") 

192 

193 

194def _generate_findings_report(results: dict, output_dir: Path): 

195 """Generate FINDINGS.md - All vulnerabilities with code context.""" 

196 

197 findings = results.get("findings", []) 

198 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

199 

200 report = f"""# 🔍 Security Findings - Detailed Analysis 

201 

202**Generated:** {scan_date} 

203**Total Findings:** {len(findings)} 

204 

205--- 

206 

207""" 

208 

209 if not findings: 

210 report += """## ✅ No Security Issues Found! 

211 

212Your code passed all security checks. Great work maintaining secure coding practices! 

213 

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 

223 

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) 

234 

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" 

238 

239 for i, finding in enumerate(file_findings, 1): 

240 severity_icons = { 

241 "CRITICAL": "🔴", 

242 "HIGH": "🟠", 

243 "MEDIUM": "🟡", 

244 "LOW": "🔵", 

245 "INFO": "⚪" 

246 } 

247 

248 icon = severity_icons.get(finding.get("severity"), "⚪") 

249 

250 report += f"""### {icon} Finding #{i}: {finding.get('type', 'Security Issue')} 

251 

252**Severity:** {finding.get('severity', 'N/A')} 

253""" 

254 if finding.get('line'): 

255 report += f"**Line Number:** {finding.get('line')} \n" 

256 

257 report += f""" 

258**Description:** 

259{finding.get('description', 'N/A')} 

260 

261**Risk:** 

262{_get_risk_explanation(finding)} 

263 

264**CWE Reference:** 

265{_get_cwe_reference(finding.get('type', ''))} 

266 

267--- 

268 

269""" 

270 

271 report += """ 

272## 📚 Additional Resources 

273 

274### OWASP Top 10 

275- [OWASP Top 10](https://owasp.org/www-project-top-ten/) 

276- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/) 

277 

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/) 

281 

282--- 

283 

284*For remediation steps, see REMEDIATION.md* 

285*For executive summary, see EXECUTIVE-SUMMARY.md* 

286""" 

287 

288 output_file = output_dir / "FINDINGS.md" 

289 output_file.write_text(report) 

290 logger.info(f"✓ Created: {output_file}") 

291 

292 

293def _generate_remediation_report(results: dict, output_dir: Path): 

294 """Generate REMEDIATION.md - Step-by-step fix instructions.""" 

295 

296 findings = results.get("findings", []) 

297 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

298 

299 report = f"""# 🛠️ Remediation Guide 

300 

301**Generated:** {scan_date} 

302**Findings to Address:** {len(findings)} 

303 

304--- 

305 

306## 📋 How to Use This Guide 

307 

308This guide provides step-by-step instructions to fix each security issue found in your code. 

309 

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 

316 

317--- 

318 

319""" 

320 

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] 

327 

328 if severity_findings: 

329 severity_icons = { 

330 "CRITICAL": "🔴", 

331 "HIGH": "🟠", 

332 "MEDIUM": "🟡", 

333 "LOW": "🔵", 

334 "INFO": "⚪" 

335 } 

336 

337 report += f"\n## {severity_icons[severity]} {severity} Priority Fixes\n\n" 

338 

339 for i, finding in enumerate(severity_findings, 1): 

340 report += f"""### Fix #{i}: {finding.get('type', 'Security Issue')} 

341 

342**File:** `{finding.get('location', 'N/A')}` 

343""" 

344 if finding.get('line'): 

345 report += f"**Line:** {finding.get('line')} \n" 

346 

347 report += f""" 

348**Issue:** 

349{finding.get('description', 'N/A')} 

350 

351**How to Fix:** 

352 

353{_get_remediation_steps(finding)} 

354 

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 

359 

360--- 

361 

362""" 

363 

364 report += """ 

365## 🔄 Re-scanning After Fixes 

366 

367After implementing fixes, run a new scan to verify: 

368 

369```bash 

370alprina scan {target} 

371``` 

372 

373You can also view your scan history in the dashboard: 

374https://dashboard.alprina.ai 

375 

376--- 

377 

378## 💡 Best Practices 

379 

380### Preventive Measures 

381 

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 

386 

387### Recommended Tools 

388 

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 

392 

393--- 

394 

395## 📞 Need Help? 

396 

397**Alprina Support:** 

398- Documentation: https://alprina.ai/docs 

399- Email: support@alprina.ai 

400- Dashboard: https://dashboard.alprina.ai 

401 

402**Security Resources:** 

403- OWASP: https://owasp.org 

404- CWE: https://cwe.mitre.org 

405- NIST: https://csrc.nist.gov 

406 

407--- 

408 

409*After fixing issues, re-run the scan to update this report* 

410""".replace("{target}", results.get('target', '.')) 

411 

412 output_file = output_dir / "REMEDIATION.md" 

413 output_file.write_text(report) 

414 logger.info(f"✓ Created: {output_file}") 

415 

416 

417def _generate_executive_summary(results: dict, output_dir: Path): 

418 """Generate EXECUTIVE-SUMMARY.md - Non-technical overview.""" 

419 

420 findings = results.get("findings", []) 

421 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

422 

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 } 

430 

431 report = f"""# 📊 Executive Summary - Security Assessment 

432 

433**Report Date:** {scan_date} 

434**Project:** {results.get('target', 'N/A')} 

435**Scan Coverage:** {results.get('files_scanned', 0)} files analyzed 

436 

437--- 

438 

439## 🎯 Overview 

440 

441This report provides a high-level summary of the security assessment performed on your codebase using Alprina's AI-powered security scanner. 

442 

443### What We Found 

444 

445**Total Security Findings:** {len(findings)} 

446 

447""" 

448 

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!" 

465 

466 report += f"""**Security Risk Level:** {risk_badge} 

467 

468{recommendation} 

469 

470--- 

471 

472## 📈 Findings Breakdown 

473 

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 | 

480 

481--- 

482 

483## 💼 Business Impact 

484 

485""" 

486 

487 if severity_counts['CRITICAL'] > 0: 

488 report += """### Critical Security Risks 

489 

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 

496 

497**Recommended Action:** 

498Allocate immediate resources to address critical vulnerabilities. Consider engaging security experts if internal capacity is limited. 

499 

500""" 

501 elif severity_counts['HIGH'] > 0: 

502 report += """### Significant Security Concerns 

503 

504**Potential Impact:** 

505- Elevated risk of security incidents 

506- Possible data exposure 

507- Compliance audit findings 

508- Customer trust erosion 

509 

510**Recommended Action:** 

511Prioritize these fixes in the current sprint. Ensure development team has necessary security training and resources. 

512 

513""" 

514 else: 

515 report += """### Security Posture 

516 

517Your current security posture is good. Continue maintaining security best practices and regular scanning to ensure ongoing protection. 

518 

519""" 

520 

521 report += """--- 

522 

523## 📋 Recommended Next Steps 

524 

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 

530 

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 

536 

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 

542 

543--- 

544 

545## 🛡️ About This Assessment 

546 

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 

555 

556**Coverage:** 

557This scan analyzed {results.get('files_scanned', 0)} files in your codebase using industry-standard security frameworks (OWASP, CWE, NIST). 

558 

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 

564 

565--- 

566 

567## 📞 Questions or Concerns? 

568 

569**For Technical Details:** 

570Review the SECURITY-REPORT.md and FINDINGS.md files for complete technical analysis. 

571 

572**For Remediation:** 

573See REMEDIATION.md for step-by-step fix instructions. 

574 

575**For Support:** 

576- Dashboard: https://dashboard.alprina.ai 

577- Documentation: https://alprina.ai/docs 

578- Email: support@alprina.ai 

579 

580--- 

581 

582## 📊 Metrics & Tracking 

583 

584**Scan ID:** {results.get('scan_id', 'local-scan')} 

585**View in Dashboard:** [https://dashboard.alprina.ai](https://dashboard.alprina.ai) 

586 

587Track your security progress over time: 

588- Vulnerability trends 

589- Fix rates 

590- Security score 

591- Compliance status 

592 

593--- 

594 

595*This executive summary is intended for non-technical stakeholders. For technical details, refer to the complete security report.* 

596 

597**Generated by Alprina Security Platform** 

598**Trusted by security-conscious development teams worldwide** 

599""" 

600 

601 output_file = output_dir / "EXECUTIVE-SUMMARY.md" 

602 output_file.write_text(report) 

603 logger.info(f"✓ Created: {output_file}") 

604 

605 

606def _get_risk_explanation(finding: dict) -> str: 

607 """Get risk explanation based on finding type.""" 

608 

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 } 

618 

619 finding_type = finding.get('type', '') 

620 return risk_explanations.get(finding_type, "This vulnerability could be exploited by attackers to compromise system security.") 

621 

622 

623def _get_cwe_reference(finding_type: str) -> str: 

624 """Get CWE reference for finding type.""" 

625 

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 } 

634 

635 return cwe_mapping.get(finding_type, "[CWE Database](https://cwe.mitre.org/)") 

636 

637 

638def _get_remediation_steps(finding: dict) -> str: 

639 """Get specific remediation steps based on finding type.""" 

640 

641 remediation_guides = { 

642 "SQL Injection": """ 

643**Step 1:** Use parameterized queries or prepared statements 

644 

645```python 

646# ❌ Vulnerable Code 

647query = f"SELECT * FROM users WHERE id = {user_id}" 

648cursor.execute(query) 

649 

650# ✅ Secure Code 

651query = "SELECT * FROM users WHERE id = %s" 

652cursor.execute(query, (user_id,)) 

653``` 

654 

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""", 

659 

660 "Hardcoded Secret": """ 

661**Step 1:** Move secrets to environment variables 

662 

663```python 

664# ❌ Vulnerable Code 

665API_KEY = "sk_live_abc123xyz" 

666 

667# ✅ Secure Code 

668import os 

669API_KEY = os.getenv("API_KEY") 

670``` 

671 

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""", 

677 

678 "XSS": """ 

679**Step 1:** Escape all user-generated content before rendering 

680 

681```python 

682# ❌ Vulnerable Code 

683return f"<div>{user_input}</div>" 

684 

685# ✅ Secure Code 

686from html import escape 

687return f"<div>{escape(user_input)}</div>" 

688``` 

689 

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""", 

694 

695 "Debug Mode": """ 

696**Step 1:** Disable debug mode in production 

697 

698```python 

699# ❌ Vulnerable Code 

700DEBUG = True 

701 

702# ✅ Secure Code 

703DEBUG = os.getenv("DEBUG", "False") == "True" 

704``` 

705 

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 } 

711 

712 finding_type = finding.get('type', '') 

713 

714 if finding_type in remediation_guides: 

715 return remediation_guides[finding_type] 

716 else: 

717 return f""" 

718**General Remediation Steps:** 

719 

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 

726 

727**Need specific guidance?** 

728Contact Alprina support at support@alprina.ai with your Scan ID. 

729""" 

730 

731 

732# ============================================================================ 

733# SPECIALIZED REPORT GENERATORS FOR DIFFERENT AGENT TYPES 

734# ============================================================================ 

735 

736def _generate_red_team_report(results: dict, output_dir: Path): 

737 """Generate RED-TEAM-REPORT.md - Penetration testing findings.""" 

738 

739 findings = results.get("findings", []) 

740 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

741 

742 report = f"""# ⚔️ Red Team Assessment Report 

743 

744**Assessment Date:** {scan_date} 

745**Target:** {results.get('target', 'N/A')} 

746**Engagement Type:** {results.get('engagement_type', 'Offensive Security Testing')} 

747 

748--- 

749 

750## 📋 Executive Summary 

751 

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. 

753 

754### Assessment Scope 

755 

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')} 

759 

760--- 

761 

762## 🎯 Attack Vectors Identified 

763 

764""" 

765 

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) 

773 

774 for attack_type, vectors in attack_types.items(): 

775 exploitable = len([v for v in vectors if v.get('exploitable', False)]) 

776 

777 report += f"""### {attack_type} 

778 

779**Vectors Found:** {len(vectors)} 

780**Exploitable:** {exploitable} 

781 

782""" 

783 for i, vector in enumerate(vectors, 1): 

784 exploit_status = "✅ EXPLOITABLE" if vector.get('exploitable') else "⚠️ POTENTIAL" 

785 

786 report += f"""#### {i}. {vector.get('title', 'Attack Vector')} 

787 

788**Status:** {exploit_status} 

789**Severity:** {vector.get('severity', 'MEDIUM')} 

790**Location:** `{vector.get('location', 'N/A')}` 

791 

792**Attack Description:** 

793{vector.get('description', 'N/A')} 

794 

795**Exploitation Steps:** 

796{vector.get('exploit_steps', 'Manual testing required')} 

797 

798**Impact:** 

799{vector.get('impact', 'Could lead to system compromise')} 

800 

801--- 

802 

803""" 

804 

805 report += """ 

806## 🛡️ Defense Recommendations 

807 

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 

813 

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 

819 

820--- 

821 

822## 📊 Attack Surface Analysis 

823 

824### High-Risk Areas 

825""" 

826 

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" 

834 

835 report += f""" 

836 

837### Recommendations by Priority 

838 

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 

842 

843--- 

844 

845## 🔬 Methodology 

846 

847**Assessment Approach:** 

848- Black-box testing from external attacker perspective 

849- Exploit development and validation 

850- Post-exploitation analysis 

851- Privilege escalation testing 

852 

853**Tools Used:** 

854- Alprina Red Team Agent 

855- Industry-standard penetration testing tools 

856- Custom exploit scripts 

857 

858--- 

859 

860*This is a confidential security assessment. Distribution should be limited to authorized personnel only.* 

861 

862**Assessed by:** Alprina Red Team Agent 

863**Report ID:** {results.get('scan_id', 'red-team-' + datetime.now().strftime('%Y%m%d'))} 

864""" 

865 

866 output_file = output_dir / "RED-TEAM-REPORT.md" 

867 output_file.write_text(report) 

868 logger.info(f"✓ Created: {output_file}") 

869 

870 

871def _generate_blue_team_report(results: dict, output_dir: Path): 

872 """Generate BLUE-TEAM-REPORT.md - Defensive posture assessment.""" 

873 

874 findings = results.get("findings", []) 

875 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

876 

877 report = f"""# 🛡️ Blue Team Defense Posture Report 

878 

879**Assessment Date:** {scan_date} 

880**Target:** {results.get('target', 'N/A')} 

881**Assessment Type:** Defensive Security Evaluation 

882 

883--- 

884 

885## 📋 Executive Summary 

886 

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. 

888 

889### Security Posture Score 

890 

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']])} 

894 

895--- 

896 

897## 🔍 Security Controls Assessment 

898 

899""" 

900 

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) 

908 

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']) 

913 

914 report += f"""### {category} 

915 

916**Total Controls:** {len(controls)} 

917**✅ Implemented:** {implemented} 

918**⚠️ Partial:** {partial} 

919**❌ Missing:** {missing} 

920 

921""" 

922 

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'), '❓') 

931 

932 report += f"""#### {icon} {i}. {control.get('title', 'Security Control')} 

933 

934**Status:** {control.get('status', 'Unknown').upper()} 

935**Impact:** {control.get('severity', 'MEDIUM')} 

936 

937**Assessment:** 

938{control.get('description', 'N/A')} 

939 

940**Recommendation:** 

941{control.get('recommendation', 'Implement this security control')} 

942 

943--- 

944 

945""" 

946 

947 report += """ 

948## 🎯 Priority Improvements 

949 

950### Critical Gaps (Fix Immediately) 

951""" 

952 

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" 

959 

960 report += """ 

961 

962### High Priority (Fix This Month) 

963""" 

964 

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" 

971 

972 report += f""" 

973 

974--- 

975 

976## 📊 Defensive Metrics 

977 

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 

982 

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')} 

987 

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')} 

992 

993--- 

994 

995## 🔐 Recommended Security Controls 

996 

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 

1003 

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 

1010 

1011--- 

1012 

1013## 📈 Improvement Roadmap 

1014 

1015### Month 1 

1016- Address all critical security gaps 

1017- Implement basic logging and monitoring 

1018- Establish incident response team 

1019 

1020### Quarter 1 

1021- Deploy security tools (SIEM, EDR, WAF) 

1022- Complete high-priority improvements 

1023- Conduct tabletop exercises 

1024 

1025### Year 1 

1026- Achieve target security posture 

1027- Establish continuous monitoring 

1028- Regular security assessments 

1029- Ongoing team training 

1030 

1031--- 

1032 

1033*This assessment is intended for internal security team use. Treat as confidential.* 

1034 

1035**Assessed by:** Alprina Blue Team Agent 

1036**Report ID:** {results.get('scan_id', 'blue-team-' + datetime.now().strftime('%Y%m%d'))} 

1037""" 

1038 

1039 output_file = output_dir / "BLUE-TEAM-REPORT.md" 

1040 output_file.write_text(report) 

1041 logger.info(f"✓ Created: {output_file}") 

1042 

1043 

1044def _generate_dfir_report(results: dict, output_dir: Path): 

1045 """Generate DFIR-REPORT.md - Digital forensics and incident response findings.""" 

1046 

1047 findings = results.get("findings", []) 

1048 scan_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 

1049 

1050 report = f"""# 🔬 Digital Forensics & Incident Response Report 

1051 

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 

1056 

1057--- 

1058 

1059## 📋 Executive Summary 

1060 

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. 

1062 

1063### Key Findings 

1064 

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)])} 

1068 

1069--- 

1070 

1071## 🕵️ Indicators of Compromise (IOCs) 

1072 

1073""" 

1074 

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')} 

1079 

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')} 

1084 

1085**Description:** 

1086{ioc.get('description', 'N/A')} 

1087 

1088**Hash Values:** 

1089``` 

1090MD5: {ioc.get('md5', 'N/A')} 

1091SHA256: {ioc.get('sha256', 'N/A')} 

1092``` 

1093 

1094**Evidence Chain:** 

1095{ioc.get('evidence_chain', 'See evidence log')} 

1096 

1097--- 

1098 

1099""" 

1100 else: 

1101 report += "No indicators of compromise identified in this analysis.\n\n" 

1102 

1103 report += """ 

1104## ⏱️ Timeline Reconstruction 

1105 

1106""" 

1107 

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', '')) 

1111 

1112 if timeline_items: 

1113 report += "| Timestamp | Event | Description | Severity |\n" 

1114 report += "|-----------|-------|-------------|----------|\n" 

1115 

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" 

1120 

1121 report += f""" 

1122 

1123--- 

1124 

1125## 📁 Evidence Collection 

1126 

1127### Artifacts Preserved 

1128""" 

1129 

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" 

1136 

1137 report += f""" 

1138 

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')} 

1145 

1146--- 

1147 

1148## 🔍 Analysis Findings 

1149 

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 

1154 

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')} 

1159 

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)])} 

1164 

1165--- 

1166 

1167## 🎯 Incident Analysis 

1168 

1169### Attack Vector Assessment 

1170""" 

1171 

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" 

1178 

1179 report += """ 

1180 

1181### Lateral Movement Indicators 

1182""" 

1183 

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" 

1190 

1191 report += """ 

1192 

1193### Data Exfiltration Risk 

1194""" 

1195 

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" 

1203 

1204 report += """ 

1205 

1206--- 

1207 

1208## 📋 Recommendations 

1209 

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 

1216 

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 

1223 

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 

1230 

1231--- 

1232 

1233## 📝 Analysis Notes 

1234 

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 

1241 

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 

1247 

1248--- 

1249 

1250*This is a confidential forensic report. Handle according to evidence preservation procedures.* 

1251 

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""" 

1256 

1257 output_file = output_dir / "DFIR-REPORT.md" 

1258 output_file.write_text(report) 

1259 logger.info(f"✓ Created: {output_file}") 

1260 

1261 

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, 

1267 

1268 "blue_teamer": _generate_blue_team_report, 

1269 "blue-team": _generate_blue_team_report, 

1270 "defensive-security": _generate_blue_team_report, 

1271 

1272 "dfir": _generate_dfir_report, 

1273 "forensics": _generate_dfir_report, 

1274 "incident-response": _generate_dfir_report, 

1275}