313ee5073b
Detailed plan for upgrading the 22 existing Playwright-based banner checks to the same quality level as the document checks: - 6 L1 + 30 L2 hierarchical checks - Expert hints with EuGH/CNIL/DSK/EDPB references - 3-phase evidence (before consent, after reject, after accept) - Dark pattern detection (button size, color, click asymmetry) - Estimated 3-4h implementation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
165 lines
7.0 KiB
Markdown
165 lines
7.0 KiB
Markdown
# Plan: Banner-Check auf Dokumentenpruefungs-Qualitaet upgraden
|
|
|
|
## Ziel
|
|
|
|
Die 22 bestehenden Banner-Checks auf das gleiche Qualitaetsniveau bringen
|
|
wie die 138 Dokumenten-Checks: L1/L2-Hierarchie, Expert-Level Hints mit
|
|
EuGH/CNIL/DSK-Referenzen, strukturiertes CheckItem-Format.
|
|
|
|
## Bestehende 22 Checks (Inventar)
|
|
|
|
### Banner Text & Verhalten (1-11)
|
|
1. `impressum_link` — Impressum aus Banner erreichbar
|
|
2. `dse_link` — DSE-Link im Banner
|
|
3. `wrong_dse_consent` — Falsche Formulierung ("Zustimmung zur DSE")
|
|
4. `reject_button_visible` — Ablehnen-Button sichtbar
|
|
5. `pre_ticked_checkboxes` — Vorausgewaehlte Checkboxen (EuGH Planet49)
|
|
6. `dark_pattern_button_size` — Akzeptieren groesser als Ablehnen
|
|
7. `cookie_wall` — Seite nach Ablehnung nutzbar
|
|
8. `re_access_settings` — Einstellungen erneut zugaenglich
|
|
9. `third_party_dse_link` — DSE zeigt auf eigene Seite
|
|
10. `dark_pattern_language` — Manipulative Sprache
|
|
11. `non_modal_dismiss` — Klick ausserhalb = keine Einwilligung
|
|
|
|
### Advanced Compliance (12-20)
|
|
12. `click_count_asymmetry` — Gleiche Klickanzahl fuer Accept/Reject
|
|
13. `color_contrast_dark_pattern` — Ablehnen-Button nicht unsichtbar
|
|
14. `google_consent_mode_defaults` — GCM Default = denied
|
|
15. `cookies_before_consent` — Keine Cookies vor Consent
|
|
16. `registration_consent_coupling` — Koppelungsverbot Art. 7(4)
|
|
17. `banner_language_mismatch` — Sprache = Seitensprache
|
|
18. `consent_cookie_expiry_13m` — Max 13 Monate (CNIL)
|
|
19. `nudging_reject_hidden` — Ablehnen nicht versteckt
|
|
20. `stirring_emotional_language` — Emotionale Manipulation
|
|
|
|
### Phasen-basiert (21-22)
|
|
21. `tracking_before_consent` — Tracking vor Einwilligung
|
|
22. `tracking_after_reject` — Tracking nach Ablehnung
|
|
|
|
## Geplante L1/L2-Struktur
|
|
|
|
### L1: Banner-Grundanforderungen (6 Checks)
|
|
|
|
| ID | Label | Prueft |
|
|
|----|-------|--------|
|
|
| banner_present | Banner vorhanden | Wird ein Cookie-Banner angezeigt? |
|
|
| banner_choices | Wahlmoeglichkeit | Akzeptieren UND Ablehnen moeglich? |
|
|
| banner_legal_links | Rechtliche Links | Impressum + DSE erreichbar? |
|
|
| banner_consent_valid | Gueltige Einwilligung | Keine Pre-Ticked Boxes, kein Auto-Consent? |
|
|
| banner_pre_consent | Keine Vorab-Cookies | Keine Tracking-Cookies vor Consent? |
|
|
| banner_post_reject | Ablehnung respektiert | Tracking stoppt nach Ablehnung? |
|
|
|
|
### L2: Detail-Checks pro L1 (30+ Checks)
|
|
|
|
#### Unter "banner_choices" (Wahlmoeglichkeit):
|
|
- reject_visible — Ablehnen-Button sichtbar auf erster Ebene
|
|
- reject_same_clicks — Gleiche Klickanzahl wie Akzeptieren
|
|
- reject_same_size — Gleiche Buttongroesse (kein Dark Pattern)
|
|
- reject_same_prominence — Gleiche Farbgebung/Kontrast
|
|
- reject_no_scroll — Ablehnen ohne Scrollen erreichbar
|
|
- reject_no_nudging — Kein Nudging/Stirring
|
|
|
|
#### Unter "banner_legal_links":
|
|
- impressum_accessible — Impressum trotz Overlay erreichbar
|
|
- dse_link_present — DSE-Link im Banner vorhanden
|
|
- dse_link_own — DSE zeigt auf eigene Seite (nicht Drittanbieter)
|
|
- dse_readable — DSE ist vor Einwilligung einsehbar
|
|
|
|
#### Unter "banner_consent_valid":
|
|
- no_pre_ticked — Keine vorausgewaehlten Checkboxen
|
|
- no_wrong_wording — Keine "Zustimmung zur DSE"
|
|
- no_modal_dismiss — Klick ausserhalb != Einwilligung
|
|
- no_coupling — Kein Koppelungsverbot-Verstoss
|
|
- no_emotional_language — Keine manipulative Sprache
|
|
- consent_revocable — Einstellungen erneut zugaenglich (Art. 7(3))
|
|
- consent_expiry — Consent-Cookie max 13 Monate (CNIL)
|
|
|
|
#### Unter "banner_pre_consent":
|
|
- no_tracking_scripts — Keine Tracking-Scripts vor Consent
|
|
- no_tracking_cookies — Keine Tracking-Cookies vor Consent
|
|
- gcm_default_denied — Google Consent Mode Default = denied
|
|
- no_facebook_pixel — Kein Meta Pixel vor Consent
|
|
- no_google_analytics — Kein GA vor Consent
|
|
|
|
#### Unter "banner_post_reject":
|
|
- tracking_stops — Tracking-Scripts entfernt nach Ablehnung
|
|
- cookies_removed — Tracking-Cookies entfernt nach Ablehnung
|
|
- no_new_tracking — Keine neuen Tracker nach Ablehnung
|
|
- site_functional — Seite bleibt nutzbar (kein Cookie-Wall)
|
|
|
|
#### Unter "banner_present":
|
|
- banner_language — Sprache = Seitensprache
|
|
- banner_provider_named — CMP-Anbieter identifizierbar
|
|
|
|
## Expert-Level Hints (Beispiele)
|
|
|
|
### Dark Pattern Button-Groesse:
|
|
"EDPB Guidelines 3/2022 (Deceptive Design Patterns), Rn. 62: Akzeptieren
|
|
und Ablehnen muessen 'gleichwertig praesentiert' werden. Konkret: Gleiche
|
|
Schriftgroesse, Buttongroesse und Farbprominenz. Die CNIL hat Google
|
|
(150 Mio. EUR) und Facebook (60 Mio. EUR) u.a. wegen Klick-Asymmetrie
|
|
bestraft."
|
|
|
|
### Pre-Consent Tracking:
|
|
"§25 Abs. 1 TDDDG: Zugriff auf Endgeraet (Cookie setzen, Script laden)
|
|
erst NACH informierter Einwilligung. Tracking vor Banner-Interaktion ist
|
|
ein Verstoss. Haeufig: Google Tag Manager laedt GA4 bereits beim
|
|
Seitenaufruf — GTM selbst ist erlaubt, die darin konfigurierten Tags
|
|
muessen aber consent-gesteuert sein."
|
|
|
|
### Cookie-Wall:
|
|
"EDPB Guidelines 05/2020, Rn. 39: Verweigerung der Einwilligung darf
|
|
nicht dazu fuehren, dass die Website nicht mehr nutzbar ist (sog.
|
|
'Cookie Wall'). Ausnahme: Paywall-Modelle ('Consent or Pay') sind
|
|
nach EDPB Opinion 08/2024 unter engen Bedingungen zulaessig."
|
|
|
|
### Consent-Cookie Laufzeit:
|
|
"CNIL-Leitlinie (Dez. 2020): Consent-Entscheidung darf max. 13 Monate
|
|
gespeichert werden. Danach muss erneut gefragt werden. Viele CMPs
|
|
setzen Default auf 365 Tage — das ist noch im Rahmen. Ueber 395 Tage
|
|
ist ein Verstoss."
|
|
|
|
## Technische Umsetzung
|
|
|
|
### Phase 1: Banner-Check Datenmodell (Backend)
|
|
- Neues Package `consent-tester/checks/` mit L1/L2-Struktur
|
|
- Jeder Check bekommt: id, label, level, parent, severity, hint
|
|
- Runner aggregiert Checks und berechnet Scores
|
|
- Response-Format analog zu DocCheckResult (completeness_pct, correctness_pct)
|
|
|
|
### Phase 2: Consent-Tester Integration
|
|
- Bestehende Checks (banner_text_checker, banner_advanced_checks) mappen
|
|
auf neue L1/L2-Struktur
|
|
- Phasen-Violations als L2-Checks unter banner_pre_consent / banner_post_reject
|
|
- Tracking-Services als Evidence (matched_text)
|
|
|
|
### Phase 3: Frontend
|
|
- BannerCheckTab zeigt L1/L2 hierarchisch (wie ChecklistView)
|
|
- 3-Phasen-Zusammenfassung oben
|
|
- Fortschrittsbalken (gruen/blau)
|
|
- Hints unter fehlgeschlagenen Checks
|
|
|
|
### Phase 4: Email-Report
|
|
- Gleiche HTML-Formatierung wie Dokumentenpruefung
|
|
- Hints + Evidence + Phase-Zuordnung
|
|
|
|
## Dateien
|
|
|
|
| Datei | Aktion |
|
|
|-------|--------|
|
|
| consent-tester/checks/__init__.py | Neu: L1/L2 Check-Definitionen |
|
|
| consent-tester/checks/banner_checks.py | Neu: 6 L1 + 30 L2 Checks mit Hints |
|
|
| consent-tester/checks/runner.py | Neu: Aggregation + Scoring |
|
|
| consent-tester/services/consent_scanner.py | Anpassen: Neues Response-Format |
|
|
| backend-compliance/compliance/api/agent_doc_check_routes.py | Erweitern: Banner-Result-Mapping |
|
|
| admin-compliance/app/sdk/agent/_components/BannerCheckTab.tsx | Erweitern: ChecklistView-Integration |
|
|
|
|
## Geschaetzter Aufwand
|
|
|
|
~3-4 Stunden:
|
|
- 1h: L1/L2 Check-Definitionen + 36 Expert-Level Hints
|
|
- 1h: Consent-Tester Mapping + Runner
|
|
- 0.5h: Backend Response-Mapping
|
|
- 0.5h: Frontend Integration
|
|
- 0.5h: Test + Deploy + Ground Truth
|