A single vulnerability finding
| 80 | |
| 81 | |
| 82 | @dataclass |
| 83 | class VulnerabilityFinding: |
| 84 | """A single vulnerability finding""" |
| 85 | finding_id: str |
| 86 | scanner: str |
| 87 | host: str |
| 88 | port: Optional[int] |
| 89 | severity: VulnSeverity |
| 90 | title: str |
| 91 | description: str |
| 92 | cve_ids: List[str] = field(default_factory=list) |
| 93 | cwe_ids: List[str] = field(default_factory=list) |
| 94 | cvss_score: Optional[float] = None |
| 95 | evidence: str = "" |
| 96 | remediation: str = "" |
| 97 | references: List[str] = field(default_factory=list) |
| 98 | tags: List[str] = field(default_factory=list) |
| 99 | matched_at: str = "" |
| 100 | template_id: str = "" |
| 101 | raw_output: str = "" |
| 102 | details: Dict[str, Any] = field(default_factory=dict) # Additional scanner-specific details |
| 103 | timestamp: datetime = field(default_factory=datetime.now) |
| 104 | |
| 105 | def to_dict(self) -> Dict[str, Any]: |
| 106 | return { |
| 107 | 'finding_id': self.finding_id, |
| 108 | 'scanner': self.scanner, |
| 109 | 'host': self.host, |
| 110 | 'port': self.port, |
| 111 | 'severity': self.severity.value, |
| 112 | 'title': self.title, |
| 113 | 'description': self.description, |
| 114 | 'cve_ids': self.cve_ids, |
| 115 | 'cwe_ids': self.cwe_ids, |
| 116 | 'cvss_score': self.cvss_score, |
| 117 | 'evidence': self.evidence[:1000], # Limit size |
| 118 | 'remediation': self.remediation, |
| 119 | 'references': self.references[:10], |
| 120 | 'tags': self.tags, |
| 121 | 'matched_at': self.matched_at, |
| 122 | 'template_id': self.template_id, |
| 123 | 'details': self.details, |
| 124 | 'timestamp': self.timestamp.isoformat() |
| 125 | } |
| 126 | |
| 127 |
no outgoing calls
no test coverage detected