feat(consent-tester): 4 weitere Edge-Cases — Consent-or-Pay, Consent Mode, CNAME-Cloaking, Returning-User

#4 Consent-or-Pay (EDPB Opinion 08/2024): Banner-Text-Signatur (Pur-Abo/
   "zustimmen oder bezahlen" + Consent-Kontext) → MEDIUM-Befund "rechtlich
   umstritten, gesondert prüfen".
#5 Google Consent Mode v2: page.evaluate (dataLayer-consent-Events / inline
   gtag('consent')) → MEDIUM "ist KEINE gültige Einwilligung".
#6 CNAME-Cloaking: First-Party-Subdomains per socket.gethostbyname_ex auflösen,
   CNAME-Kette gegen bekannte Tracker-Infra (Eulerian/Adobe/Webtrekk/…) → HIGH
   "faktisch Drittanbieter trotz First-Party-Optik". Best-effort, kurze Timeouts.
#7 Returning-User: Scanner nutzt by-design frische Browser-Contexts → Hinweis im
   Kein-Banner-Befund (fehlendes Banner liegt nicht an erinnertem Consent).

Tests + py_compile grün.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-12 20:45:20 +02:00
parent 2b928dcb33
commit 11740bd2f9
3 changed files with 170 additions and 10 deletions
+16 -7
View File
@@ -83,25 +83,34 @@ class ConsentTestResult:
banner_screenshot_b64: str = ""
def _apply_edge_case_findings(result) -> None:
def _apply_edge_case_findings(result, url: str = "") -> None:
"""Edge-Case-Befunde nach dem Scan — an ALLEN Return-Pfaden aufrufen (auch
im no-banner-Fruehreturn): #1/#2 kein-Banner-affirmativ (statisch / nur
technisch notwendig → konform, inkl. Geo-Caveat) + #3 Non-Cookie-Tracking
(Pixel/Fingerprinting; §25 gilt auch ohne Cookies)."""
im no-banner-Fruehreturn): #1/#2 kein-Banner-affirmativ (konform, Geo-/
Returning-User-Caveat), #3 Non-Cookie-Tracking (Pixel/Fingerprinting),
#6 CNAME-Cloaking (First-Party-Subdomain → Tracker-Infra)."""
try:
from services.banner_text_checker import (
build_no_banner_finding, detect_non_cookie_tracking,
build_non_cookie_tracking_finding,
detect_cname_cloaking, build_cname_cloaking_finding,
)
all_scripts = (result.before_scripts or []) + (result.accept_scripts or [])
if (not result.banner_detected and not result.before_violations
and not result.before_tracking):
result.banner_text_violations.append(
build_no_banner_finding(result.banner_has_dse_link))
nct = detect_non_cookie_tracking(
(result.before_scripts or []) + (result.accept_scripts or []))
nct = detect_non_cookie_tracking(all_scripts)
if nct:
result.banner_text_violations.append(
build_non_cookie_tracking_finding(nct))
if url:
from urllib.parse import urlparse
dom = (urlparse(url).hostname or "").lower()
dom = dom[4:] if dom.startswith("www.") else dom
cc = detect_cname_cloaking(all_scripts, dom)
if cc:
result.banner_text_violations.append(
build_cname_cloaking_finding(cc))
except Exception as e:
logger.warning("Edge-case findings skipped: %s", e)
@@ -240,7 +249,7 @@ async def run_consent_test(
if not banner.detected:
logger.info("No consent banner detected — skipping Phase B/C")
await browser.close()
_apply_edge_case_findings(result)
_apply_edge_case_findings(result, url)
return result
# ── Phase B: After rejecting ─────────────────────────