diff --git a/zeroclaw/PLAN-control-relevance-filter.md b/zeroclaw/PLAN-control-relevance-filter.md index aa363bb..714e8c8 100644 --- a/zeroclaw/PLAN-control-relevance-filter.md +++ b/zeroclaw/PLAN-control-relevance-filter.md @@ -231,21 +231,129 @@ AI_INDICATORS = { r"profiling", r"personalisier", # Personalisierung ], - # Tracking-Dienste - "tracking_services": [ + # Tracking & Analytics (EU + non-EU) + "tracking_analytics": [ + # Google (USA) r"google.?analytics|gtag|UA-\d+|G-\w+", - r"facebook.?pixel|fbq\(", + r"googletagmanager|gtm\.js", + r"google.?ads|googleads|adwords", + r"doubleclick\.net", + # Meta (USA) + r"facebook.?pixel|fbq\(|connect\.facebook", r"meta.?pixel", - r"hotjar", - r"segment\.com", - r"mixpanel", - r"amplitude", - r"matomo|piwik", - r"plausible", + # Microsoft (USA) + r"clarity\.ms", # Microsoft Clarity + r"bing\.com/bat", # Bing Ads + r"linkedin\.com/insight", # LinkedIn Insight + # Analytics-Anbieter + r"hotjar", # Hotjar (Malta/EU — OK) + r"segment\.com", # Segment (USA) + r"mixpanel", # Mixpanel (USA) + r"amplitude", # Amplitude (USA) + r"heap\.io", # Heap (USA) + r"posthog", # PostHog (USA, self-host moeglich) + r"matomo|piwik", # Matomo (EU — self-host = OK, Cloud = pruefen) + r"plausible", # Plausible (EU — OK) + r"fathom", # Fathom (Kanada — Angemessenheitsbeschluss) + r"pirsch", # Pirsch (DE — OK) + r"umami", # Umami (self-host) + ], + # CDN und Drittanbieter-Dienste (Drittlandtransfer-Risiko) + "third_party_services": [ + # CDN (pruefen ob Drittland) + r"cdn\.cloudflare\.com", # Cloudflare (USA) + r"fastly\.net", # Fastly (USA) + r"akamai", # Akamai (USA) + r"cdn\.jsdelivr\.net", # jsDelivr (international) + r"unpkg\.com", # unpkg (USA) + r"cdnjs\.cloudflare\.com", # cdnjs (USA) + r"stackpath", # StackPath (USA) + r"bunny\.net|bunnycdn", # BunnyCDN (Slowenien/EU — OK) + r"keycdn", # KeyCDN (Schweiz — Angemessenheit) + # Fonts (IP-Uebermittlung!) + r"fonts\.googleapis\.com", # Google Fonts (USA — DSGVO-Verstoss!) + r"fonts\.gstatic\.com", # Google Fonts CDN + r"use\.typekit\.net", # Adobe Fonts (USA) + # Captcha + r"recaptcha|grecaptcha", # Google reCAPTCHA (USA) + r"hcaptcha", # hCaptcha (USA) + r"turnstile.*cloudflare", # Cloudflare Turnstile (USA) + # Maps + r"maps\.googleapis\.com", # Google Maps (USA) + r"maps\.google\.com", + r"openstreetmap", # OpenStreetMap (EU — OK) + r"mapbox", # Mapbox (USA) + # Video + r"youtube\.com|youtube-nocookie", # YouTube (USA) + r"vimeo\.com", # Vimeo (USA) + r"wistia", # Wistia (USA) + # Social Media Embeds + r"platform\.twitter\.com|x\.com/embed", # X/Twitter (USA) + r"instagram\.com/embed", # Instagram (USA) + r"linkedin\.com/embed", # LinkedIn (USA) + # Content Moderation + r"besedo", # Besedo (Schweden/EU — OK, aber pruefen) + # Payment (PCI-DSS relevant) + r"stripe\.com|js\.stripe", # Stripe (USA) + r"paypal\.com", # PayPal (USA) + r"adyen", # Adyen (NL/EU — OK) + r"mollie", # Mollie (NL/EU — OK) + # Andere + r"sentry\.io|sentry-cdn", # Sentry Error Tracking (USA) + r"intercom\.io", # Intercom (USA) — auch in chatbot_widgets + r"zendesk\.com", # Zendesk (USA) + r"freshdesk|freshworks", # Freshworks (USA/Indien) ], } ``` +### Drittland-Erkennung + +Fuer jeden erkannten externen Dienst wird geprueft ob er aus einem Drittland stammt +(kein EU/EWR-Staat, kein Angemessenheitsbeschluss). Dafuer wird eine Registry gepflegt: + +```python +# Statische Registry — ca. 80 Eintraege +THIRD_PARTY_REGISTRY = { + "google_analytics": {"provider": "Google LLC", "country": "US", "eu_adequate": False, "requires_consent": True, "legal_ref": "Art. 44-49 DSGVO, Schrems II"}, + "google_fonts": {"provider": "Google LLC", "country": "US", "eu_adequate": False, "requires_consent": True, "legal_ref": "LG Muenchen I, Az. 3 O 17493/20 (Google Fonts Urteil)"}, + "facebook_pixel": {"provider": "Meta Platforms", "country": "US", "eu_adequate": False, "requires_consent": True, "legal_ref": "Art. 44-49 DSGVO"}, + "cloudflare_cdn": {"provider": "Cloudflare Inc", "country": "US", "eu_adequate": False, "requires_consent": False, "legal_ref": "Art. 44-49 DSGVO, berechtigtes Interesse moeglich"}, + "matomo_cloud": {"provider": "Matomo (InnoCraft)", "country": "NZ", "eu_adequate": True, "requires_consent": True, "legal_ref": "Neuseeland hat Angemessenheitsbeschluss"}, + "matomo_selfhost": {"provider": "Self-hosted", "country": "depends", "eu_adequate": True, "requires_consent": False, "legal_ref": "Kein Drittlandtransfer bei Self-Hosting"}, + "plausible": {"provider": "Plausible Insights", "country": "EE", "eu_adequate": True, "requires_consent": False, "legal_ref": "EU-Anbieter, cookieless"}, + "bunnycdn": {"provider": "BunnyCDN d.o.o.", "country": "SI", "eu_adequate": True, "requires_consent": False, "legal_ref": "EU-Anbieter"}, + "stripe": {"provider": "Stripe Inc", "country": "US", "eu_adequate": False, "requires_consent": False, "legal_ref": "Art. 6(1)(b) Vertragserfuellung, SCCs"}, + "besedo": {"provider": "Besedo AB", "country": "SE", "eu_adequate": True, "requires_consent": False, "legal_ref": "EU-Anbieter"}, + # ... ~80 weitere Eintraege +} +``` + +### Generierte Findings + +**Beispiel: Opodo mit erweitertem Scan:** +``` +Externe Dienste erkannt: + - Google Analytics (G-03F834EHLM) — USA, kein Angemessenheitsbeschluss + → FINDING: Drittlandtransfer USA ohne Einwilligung (Art. 44 DSGVO) + - Google Fonts (fonts.googleapis.com) — USA + → FINDING: Google Fonts Einbindung (LG Muenchen I, Az. 3 O 17493/20) + - Didomi CMP — Frankreich (EU — OK) + - Bootstrap CDN (jsdelivr.net) — International, pruefen + → FOLLOW-UP: "Wird das CDN aus der EU oder einem Drittland geladen?" +``` + +### Controls die durch Drittland-Dienste ausgeloest werden + +| Erkannter Dienst | Control | +|-----------------|---------| +| Jeder US-Dienst ohne SCCs | C_THIRD_COUNTRY_TRANSFER: Drittlandtransfer absichern (Art. 44-49 DSGVO) | +| Google Fonts remote | C_GOOGLE_FONTS: Fonts lokal einbinden (LG Muenchen I Urteil) | +| Tracking ohne Consent-Banner | C_EXPLICIT_CONSENT: Einwilligung vor Tracking einholen | +| reCAPTCHA | C_CAPTCHA_PRIVACY: Datenschutzkonformen Captcha-Dienst nutzen | +| YouTube Embed | C_VIDEO_EMBED: 2-Klick-Loesung oder youtube-nocookie verwenden | +``` + **Schritt 3: Ergebnis aggregieren** ```python scan_result = {