feat(ttp): add Ipv6LinkLocalLeakEvidence TypedDict + EVIDENCE_SCHEMA entry
Pins the evidence shape for IPv6 link-local leakage findings. All fields optional (total=False) so partial observation (passive sniffer vs active solicitation) fills whatever the vector provides. Lifter lands in a subsequent commit.
This commit is contained in:
@@ -125,6 +125,16 @@ class HttpFingerprintEvidence(TypedDict):
|
|||||||
raw: Optional[dict] # raw settings dict for h2_settings / h3_settings
|
raw: Optional[dict] # raw settings dict for h2_settings / h3_settings
|
||||||
|
|
||||||
|
|
||||||
|
class Ipv6LinkLocalLeakEvidence(TypedDict, total=False):
|
||||||
|
addr: str # the fe80:: address observed
|
||||||
|
mac_oui: str # first 3 octets if EUI-64-derived ("aa:bb:cc"), else ""
|
||||||
|
iid_kind: str # "eui64" | "stable_privacy" | "temporary" | "unknown"
|
||||||
|
vector: str # "passive_ndp" | "passive_mdns" | "passive_tcp" | "active_ns" | "active_echo"
|
||||||
|
on_iface: str # local iface that observed it
|
||||||
|
attacker_v4: str # v4 address we have for this attacker (correlation key)
|
||||||
|
observed_at: str # ISO8601 UTC
|
||||||
|
|
||||||
|
|
||||||
# Maps source_kind → its evidence TypedDict. Used by TolerantTagger to
|
# Maps source_kind → its evidence TypedDict. Used by TolerantTagger to
|
||||||
# validate that lifters do not emit undeclared keys (programmer error →
|
# validate that lifters do not emit undeclared keys (programmer error →
|
||||||
# TypeError, not the swallowed absence-of-data case).
|
# TypeError, not the swallowed absence-of-data case).
|
||||||
@@ -134,6 +144,7 @@ EVIDENCE_SCHEMA: dict[str, type] = {
|
|||||||
"email": EmailEvidence,
|
"email": EmailEvidence,
|
||||||
"canary_fingerprint": CanaryFingerprintEvidence,
|
"canary_fingerprint": CanaryFingerprintEvidence,
|
||||||
"http_fingerprint": HttpFingerprintEvidence,
|
"http_fingerprint": HttpFingerprintEvidence,
|
||||||
|
"ipv6_leak": Ipv6LinkLocalLeakEvidence,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from decnet.web.db.models.ttp import (
|
|||||||
EmailEvidence,
|
EmailEvidence,
|
||||||
HttpFingerprintEvidence,
|
HttpFingerprintEvidence,
|
||||||
IntelEvidence,
|
IntelEvidence,
|
||||||
|
Ipv6LinkLocalLeakEvidence,
|
||||||
TTPTag,
|
TTPTag,
|
||||||
compute_tag_uuid,
|
compute_tag_uuid,
|
||||||
)
|
)
|
||||||
@@ -96,6 +97,17 @@ def test_http_fingerprint_evidence_keys() -> None:
|
|||||||
assert keys == {"kind", "hash", "protocol", "client_ip", "seen_at", "raw"}
|
assert keys == {"kind", "hash", "protocol", "client_ip", "seen_at", "raw"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_ipv6_link_local_leak_evidence_keys() -> None:
|
||||||
|
keys = (
|
||||||
|
Ipv6LinkLocalLeakEvidence.__required_keys__
|
||||||
|
| Ipv6LinkLocalLeakEvidence.__optional_keys__
|
||||||
|
)
|
||||||
|
assert keys == {
|
||||||
|
"addr", "mac_oui", "iid_kind", "vector",
|
||||||
|
"on_iface", "attacker_v4", "observed_at",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# ── Per-lifter parametrized positive case ───────────────────────────
|
# ── Per-lifter parametrized positive case ───────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user