72 lines
1.9 KiB
Python
72 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass, field
|
|
from datetime import datetime, timezone
|
|
from hashlib import sha256
|
|
import json
|
|
from typing import Any
|
|
|
|
|
|
def utc_now() -> str:
|
|
return datetime.now(timezone.utc).isoformat()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Target:
|
|
url: str
|
|
host: str
|
|
scheme: str
|
|
port: int
|
|
|
|
@property
|
|
def authority(self) -> str:
|
|
default = (self.scheme == "http" and self.port == 80) or (
|
|
self.scheme == "https" and self.port == 443
|
|
)
|
|
return self.host if default else f"{self.host}:{self.port}"
|
|
|
|
|
|
@dataclass
|
|
class Finding:
|
|
run_id: str
|
|
target: str
|
|
module: str
|
|
category: str
|
|
title: str
|
|
severity: str
|
|
confidence: float
|
|
description: str
|
|
evidence: dict[str, Any] = field(default_factory=dict)
|
|
tags: list[str] = field(default_factory=list)
|
|
timestamp: str = field(default_factory=utc_now)
|
|
id: str = ""
|
|
test_id: str = ""
|
|
standards: dict[str, list[dict[str, str]]] = field(default_factory=dict)
|
|
remediation: str = ""
|
|
|
|
def __post_init__(self) -> None:
|
|
if not self.id:
|
|
evidence = json.dumps(self.evidence, sort_keys=True, default=str)
|
|
material = "\x00".join([self.target, self.module, self.category, self.title, evidence])
|
|
self.id = sha256(material.encode()).hexdigest()[:16]
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return asdict(self)
|
|
|
|
|
|
@dataclass
|
|
class ModuleResult:
|
|
module: str
|
|
target: str
|
|
status: str = "completed"
|
|
findings: list[Finding] = field(default_factory=list)
|
|
observations: dict[str, Any] = field(default_factory=dict)
|
|
artifacts: list[str] = field(default_factory=list)
|
|
errors: list[str] = field(default_factory=list)
|
|
duration_seconds: float = 0.0
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
value = asdict(self)
|
|
value["findings"] = [finding.to_dict() for finding in self.findings]
|
|
return value
|