Download report for a specific scan
(scan_id)
| 17462 | # Use the first real finding for enrichment (or combine multiple findings) |
| 17463 | base_finding = actual_findings[0] |
| 17464 | |
| 17465 | # Create enriched finding object from actual scan data |
| 17466 | finding = { |
| 17467 | 'id': base_finding.get('id', hashlib.md5(target.encode()).hexdigest()[:12]), |
| 17468 | 'host': target, |
| 17469 | 'vulnerability': base_finding.get('vulnerability', base_finding.get('service', 'Unknown')), |
| 17470 | 'severity': base_finding.get('severity', 'medium'), |
| 17471 | 'port': base_finding.get('port'), |
| 17472 | 'service': base_finding.get('service'), |
| 17473 | 'details': base_finding.get('details', {}), |
| 17474 | 'scan_timestamp': base_finding.get('timestamp', datetime.now().isoformat()) |
| 17475 | } |
| 17476 | |
| 17477 | # Enrich the finding |
| 17478 | import asyncio |
| 17479 | enriched_finding = asyncio.run(threat_intelligence.enrich_finding_with_threat_intelligence(finding)) |
| 17480 | |
| 17481 | # Convert risk score from 0-10 scale to 0-100 scale for frontend |
| 17482 | risk_score_100 = min(int(enriched_finding.dynamic_risk_score * 10), 100) |
| 17483 | |
| 17484 | return jsonify({ |
| 17485 | 'success': True, |
| 17486 | 'target': target, |
| 17487 | 'risk_score': risk_score_100, |
| 17488 | 'dynamic_risk_score': enriched_finding.dynamic_risk_score, |
| 17489 | 'executive_summary': enriched_finding.executive_summary, |
| 17490 | 'recommended_actions': enriched_finding.recommended_actions, |
| 17491 | 'threat_contexts_count': len(enriched_finding.threat_contexts), |
| 17492 | 'attribution': { |
| 17493 | 'actor_name': enriched_finding.attribution.actor_name if enriched_finding.attribution else None, |
| 17494 | 'confidence': enriched_finding.attribution.confidence if enriched_finding.attribution else 0.0 |
| 17495 | }, |
| 17496 | 'enriched_finding_id': finding['id'] |
| 17497 | }) |
| 17498 | |
| 17499 | except Exception as e: |
| 17500 | logger.error(f"Error enriching target: {e}") |
| 17501 | return jsonify({'error': str(e)}), 500 |
| 17502 | |
| 17503 | @app.route('/api/threat-intelligence/dashboard') |
| 17504 | def get_threat_intelligence_dashboard(): |
| 17505 | """Get threat intelligence dashboard data""" |
| 17506 | with _network_context_from_request(): |
| 17507 | try: |
| 17508 | if not threat_intelligence: |
| 17509 | return jsonify({'error': 'Threat intelligence system not available'}), 503 |
| 17510 | |
| 17511 | dashboard_data = { |
| 17512 | 'summary': threat_intelligence.get_enriched_findings_summary(), |
| 17513 | 'recent_findings': [], |
| 17514 | 'risk_distribution': {'critical': 0, 'high': 0, 'medium': 0, 'low': 0}, |
| 17515 | 'threat_sources_status': [] |
| 17516 | } |
| 17517 | |
| 17518 | # Get recent enriched findings |
| 17519 | recent_findings = [] |
| 17520 | for finding_id, enriched_finding in list(threat_intelligence.enriched_findings.items())[-10:]: |
| 17521 | recent_findings.append({ |
nothing calls this directly
no test coverage detected