feat(banner): Consent-Historie/Widerruf live erkennen (Borlabs-Stil, #62)

consent_history.detect_consent_history: erkennt CMP-Anbieter (Borlabs/
Usercentrics/OneTrust/Cookiebot/…) aus Storage+Cookies, versionierten Consent
(historie-fähig) + dauerhaftes Widerruf-/Einstellungs-Widget. consent_scanner
ruft es in Phase A; scan_matrix_summary surft summary.consent_history;
browser_cross_finding: positiver Befund wenn vorhanden, sonst Best-Practice-LOW
(„Nutzer sehen, wann sie welcher Version zugestimmt haben"); BrowserBehaviorView
zeigt es im Engine-Detail. Tests: 7 (classify/versioned) + 2 Cross-Finding.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-13 16:38:38 +02:00
parent 8d0da710d5
commit d92dd3b5fc
7 changed files with 208 additions and 4 deletions
@@ -131,6 +131,38 @@ def build_cross_findings(matrix: dict | None) -> list[dict]:
# bewusst: ist der Footer-Link trotz Banner erreichbar → LOW/Best Practice
# statt Verstoss. Doppel-/Falsch-Flag hier vermieden.
# ── Consent-Historie / Widerruf (Best Practice, #62) ─────────────────
ch_rows = [(_s(r).get("consent_history") or {}) for r in data]
any_history = any(c.get("history_capable") for c in ch_rows)
any_withdraw = any(c.get("withdraw_ui") for c in ch_rows)
provider = next((c.get("provider") for c in ch_rows if c.get("provider")), "")
if any_history or any_withdraw:
bits = []
if provider:
bits.append(f"Anbieter: {provider}")
if any_history:
bits.append("versionierte Einwilligung (nachvollziehbar)")
if any_withdraw:
bits.append("Widerruf-/Einstellungs-Widget vorhanden")
out.append({
"title": "Einwilligungs-Historie / Widerruf vorhanden",
"detail": "Positiv: " + ", ".join(bits) + ". Nutzer können "
"nachvollziehen bzw. ändern, welcher Version sie zugestimmt "
"haben.",
"severity": "LOW", "affected": _labels(data),
"measure": "Beibehalten.",
})
else:
out.append({
"title": "Keine sichtbare Einwilligungs-Historie",
"detail": "Weder eine versionierte Consent-Historie noch ein "
"dauerhaftes Widerruf-Widget erkannt.",
"severity": "LOW", "affected": _labels(data),
"measure": "Best Practice: Consent-Historie + jederzeit erreichbares "
"Widerruf-/Einstellungs-Widget anbieten (Borlabs-Stil) — "
"Nutzer sehen, wann sie welcher Version zugestimmt haben.",
})
# ── Coverage-Hinweis: nicht getestete Browser ────────────────────────
if missing:
out.append({