5c5d676f01
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / loc-budget (push) Failing after 11s
CI / python-lint (push) Has been skipped
CI / test-python-backend (push) Successful in 28s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / validate-canonical-controls (push) Successful in 10s
CI / go-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
Drei verwandte Mechanismen für DSE-Beweisbarkeit + URL-Hygiene.
Plan B + PDF — Versions-Beweisbarkeit-MCs (dse_checks.py):
- mc-dse_version_date (HIGH) — sichtbares Stand/Versionsdatum
Pflicht. 12 Regex-Pattern: "Stand: April 2024", ISO-Datum,
"Letzte Aktualisierung", "Version 3.2", englische
Varianten ("Last updated", "Effective date as of …").
Norm: Art. 7 Abs. 1 DSGVO (Nachweisbarkeit Einwilligung).
- mc-dse_version_proof (MED) — PDF-Download oder
versionierte Archiv-URL. Reine HTML-DSE ohne Snapshot ist
juristisch fragil. 8 Pattern: .pdf, Download-Hinweis,
web.archive.org, /dse-vNNN.html.
Norm: DSK-Orientierungshilfe 2024.
Plan A — Legacy-URL-Discovery (legacy_url_discovery.py + B20):
Vier komplementäre Quellen:
A.1 /sitemap.xml + Sub-Sitemaps parsen, auf compliance-
relevante Slugs filtern
A.2 archive.org/wayback/available pro Slug — wenn Wayback
zeigt ≥18 Monate alten Snapshot UND Seite heute noch
200 liefert UND nicht im Footer → Legacy-Verdacht
A.3 Slug-Permutations: 6 doc_types × 6 Slug-Varianten ×
5 Lang-Prefixe × 4 Brand-Parameter
A.4 Banner-Modal-Links (über consent-tester Stufe 4 Tour)
Mail-Block "🗂️ Legacy-URL-Inventar" mit Tabelle: URL · HTTP ·
Wayback-Alter · Footer · Empfehlung (301/Offline/Behalten).
Engine entscheidet NICHT was Legacy ist — präsentiert das
Inventar, Kunde wählt.
Real-World-Smoke Elli:
/en/cookies → HTTP 200, Wayback 69 Mo alt, nicht im Footer
→ "Legacy-Verdacht, 301 setzen"
/en/impressum → HTTP 302, redirected → "behalten"
Plan C — Multi-Version-DSE-Analyse (multi_version_dse.py):
Wenn ≥2 DSE-URLs reachable: pro Variante DSB-Name + Datum +
Wortzahl + SHA-256 extrahieren, Inkonsistenzen flaggen
(date_divergent, dsb_divergent, no_date_count).
Mail-Block "📑 Mehrere DSE-Versionen erkannt" mit
Vergleichstabelle + rotem Hinweis "Nur eine Version kann
gültig sein". Beispiel Elli: /de/datenschutz (Mollstr-DSB,
2022) vs /de/datenschutzerklaerung?brand=elli (Proliance,
ohne Datum).
API-Response erweitert um legacy_url_inventory +
html_blocks.legacy_urls + multi_version_dse_html im V2-Layout.
ENV-Override: LEGACY_URL_DISABLED=1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
486 lines
27 KiB
Python
486 lines
27 KiB
Python
"""
|
|
DSE (Datenschutzinformation) checks — Art. 13/14 DSGVO.
|
|
|
|
Level 1: Pflichtangabe erwaehnt?
|
|
Level 2: Pflichtangabe korrekt/vollstaendig?
|
|
"""
|
|
|
|
ART13_CHECKLIST = [
|
|
# ── L1: Verantwortlicher ──────────────────────────────────────────
|
|
{
|
|
"id": "controller",
|
|
"label": "Verantwortlicher (Art. 13(1)(a))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"verantwortlich\w*\s+(?:ist|im sinne|fuer|f(?:ue|ü)r)",
|
|
r"kontaktdaten\s+des\s+verantwortlichen",
|
|
r"name\s+(?:und|&)\s+kontaktdaten\s+des",
|
|
r"controller", r"verantwortliche\s+stelle",
|
|
r"responsible\s+(?:party|for)",
|
|
# P39: Heading-style "## 1. Verantwortlicher", "## Verantwortlicher",
|
|
# "1. Verantwortlicher" — common template structure that wasn't matched.
|
|
r"(?:^|\n)\s*#+\s*\d*\.?\s*verantwortlich\w*",
|
|
r"(?:^|\n)\s*\d+\.\s+verantwortlich\w*",
|
|
r"\bverantwortlich\w*\s*[:\n]",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "Art. 13(1)(a) DSGVO verlangt vollstaendige Identifizierung: Firmenname mit Rechtsform (z.B. 'Muster GmbH'), ladungsfaehige Anschrift, E-Mail und Telefon. Haeufiger Fehler: Nur Markenname ohne Rechtsform — das genuegt nicht zur Zustellung.",
|
|
},
|
|
{
|
|
"id": "controller_address",
|
|
"label": "Vollstaendige Anschrift (PLZ + Ort)",
|
|
"level": 2, "parent": "controller",
|
|
"patterns": [
|
|
r"(?:d[\-\s]?)?\d{5}\s+[a-z\u00c0-\u017e]\w{2,}",
|
|
r"[a-z\u00c0-\u017e]\w+(?:str|stra(?:ss|ß)e|weg|platz|allee|gasse|ring|damm)\s*\.?\s*\d",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Erforderlich ist eine ladungsfaehige Anschrift (Strasse, Hausnummer, PLZ, Ort). Haeufiger Fehler: Postfach oder c/o-Adresse — beides genuegt laut BGH (I ZR 228/03) nicht fuer die Zustellung.",
|
|
},
|
|
{
|
|
"id": "controller_email",
|
|
"label": "E-Mail-Adresse des Verantwortlichen",
|
|
"level": 2, "parent": "controller",
|
|
"patterns": [
|
|
r"[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Ohne E-Mail-Adresse koennen Betroffene ihre Rechte (Art. 15-21 DSGVO) nicht niedrigschwellig ausueben. Haeufiger Fehler: Nur Kontaktformular statt E-Mail — ein Formular allein genuegt nicht als unmittelbarer Kommunikationskanal.",
|
|
},
|
|
{
|
|
"id": "controller_phone",
|
|
"label": "Telefonnummer des Verantwortlichen",
|
|
"level": 2, "parent": "controller",
|
|
"patterns": [
|
|
r"(?:tel(?:efon)?|phone|fon)\s*[.:]\s*[\+\d][\d\s/\-\(\)]{6,}",
|
|
r"\+49\s*[\d\s/\-\(\)]{8,}",
|
|
r"0\d{2,4}\s*[\(/\-\s]\s*\d{3,}",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "EuGH (C-298/17, 'Verein fuer Konsumenteninformation') verlangt effektive Kontaktmoeglichkeit. Telefon ist nicht zwingend, aber empfohlen — fehlt sie, muss ein gleichwertiger Kanal (z.B. Chat, Rueckruf) angeboten werden.",
|
|
},
|
|
|
|
# ── L1: Datenschutzbeauftragter ───────────────────────────────────
|
|
{
|
|
"id": "dpo",
|
|
"label": "Datenschutzbeauftragter (Art. 13(1)(b))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"datenschutzbeauftragt", r"data\s+protection\s+officer",
|
|
r"kontaktdaten\s+de[rs]\s+(?:beh(?:oe|ö)rdlichen\s+)?datenschutz",
|
|
r"dsb", r"dpo",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "DSB-Benennungspflicht besteht ab 20 Personen regelmaessig mit automatisierter Datenverarbeitung (§38 BDSG) oder bei Kerntaetigkeit in Ueberwachung/sensiblen Daten (Art. 37 DSGVO). Haeufiger Fehler: DSB bestellt, aber nicht in der DSE erwaehnt.",
|
|
},
|
|
{
|
|
"id": "dpo_contact",
|
|
"label": "Kontaktdaten des DSB (E-Mail oder Telefon)",
|
|
"level": 2, "parent": "dpo",
|
|
"patterns": [
|
|
r"datenschutz(?:beauftragter?|beauftragte)[\s\S]{0,300}[a-z0-9._%+\-]+@",
|
|
r"dsb[\s\S]{0,100}@|dpo[\s\S]{0,100}@",
|
|
r"datenschutz@",
|
|
r"datenschutzbeauftragt[\s\S]{0,200}(?:e-?mail|telefon|fon)",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Art. 37(7) DSGVO verlangt Veroeffentlichung der Kontaktdaten des DSB. Mindestens eine E-Mail ist noetig — den Namen muessen Sie nicht nennen. Haeufiger Fehler: DSB wird erwaehnt, aber ohne jede Kontaktmoeglichkeit.",
|
|
},
|
|
|
|
# ── L1: Zwecke der Verarbeitung ───────────────────────────────────
|
|
{
|
|
"id": "purposes",
|
|
"label": "Zwecke der Verarbeitung (Art. 13(1)(c))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"zweck\w*\s+(?:der|und|die)\s+(?:verarbeitung|datenerhebung|datenverarbeitung|rechtsgrundlage)",
|
|
r"purpose\w*\s+(?:of|for)\s+(?:processing|data)",
|
|
r"zu\s+welch\w+\s+zweck",
|
|
r"welche\s+daten\s+werden.*verarbeitet",
|
|
r"daten\s+werden\s+(?:zu|fuer|für)\s+(?:folgende|diese)",
|
|
# P39: heading variants
|
|
r"(?:^|\n)\s*#+\s*\d*\.?\s*zwecke?\b",
|
|
r"\*\*zwecke?:?\*\*",
|
|
r"purposes?\s+and\s+(?:legal|legal\s+bases?)",
|
|
r"purposes?\s*[:\n]",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "Art. 13(1)(c) verlangt konkrete Zweckangaben — nicht nur 'Wir verarbeiten Ihre Daten'. Jeder Dienst braucht einen eigenen Zweck: z.B. 'Webanalyse via Matomo', 'Newsletter-Versand', 'Kontaktanfragen'. Pauschalformulierungen verstiessen laut DSK gegen den Transparenzgrundsatz (Art. 5(1)(a)).",
|
|
},
|
|
{
|
|
"id": "purposes_specific",
|
|
"label": "Konkrete Zwecke benannt (min. 2)",
|
|
"level": 2, "parent": "purposes",
|
|
"patterns": [
|
|
r"(?:kontaktaufnahme|vertragserfuellung|vertragserf(?:ue|ü)llung|newsletter|analyse|statistik|werbung|marketing|bewerbung|bestellabwicklung|kundenkonto)",
|
|
r"(?:bereitstellung|betrieb|sicherheit|optimierung)\s+(?:der|des|unserer|unseres)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Mindestens 2 konkrete Zwecke benennen, jeweils mit zugehoeriger Rechtsgrundlage. Beispiel: 'Vertragsabwicklung (Art. 6(1)(b))', 'Website-Analyse (Art. 6(1)(f))'. Einzelne Pauschalangabe genuegt nicht dem Bestimmtheitsgrundsatz.",
|
|
},
|
|
|
|
# ── L1: Rechtsgrundlage ───────────────────────────────────────────
|
|
{
|
|
"id": "legal_basis",
|
|
"label": "Rechtsgrundlage (Art. 13(1)(c))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"rechtsgrundlage", r"art\.\s*6\s*(?:abs|absatz)?\s*\.?\s*1",
|
|
r"legal\s+basis", r"berechtigtes\s+interesse",
|
|
r"auf\s+grundlage\s+(?:von|des|der)\s+(?:art|§)",
|
|
r"lit\.\s*[a-f][\s\)]",
|
|
r"gem(?:ae|ä)(?:ss|ß)\s+art",
|
|
r"§\s*\d+\s+(?:abs|ihkg|bdsg|ldsg|bbig|tdddg)",
|
|
r"einwilligung\s+gem",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "Jeder Verarbeitungszweck braucht eine eigene Rechtsgrundlage aus Art. 6(1) DSGVO (lit. a-f). Haeufiger Fehler: 'berechtigtes Interesse' als Auffangtatbestand fuer alles — das ist unzulaessig. Cookies/Tracking erfordern i.d.R. Einwilligung (lit. a), nicht lit. f.",
|
|
},
|
|
{
|
|
"id": "legal_basis_consent_6a",
|
|
"label": "Art. 6(1)(a) — Einwilligung",
|
|
"level": 2, "parent": "legal_basis",
|
|
"patterns": [
|
|
r"art\.\s*6\s*(?:abs\.\s*)?1\s*(?:s\.\s*1\s*)?(?:lit\.\s*)?a",
|
|
r"einwilligung\s+(?:gem|nach|i\.?\s*s\.?\s*d\.?)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Bei Einwilligung (Art. 6(1)(a)) muss zwingend auf das jederzeitige Widerrufsrecht hingewiesen werden (Art. 7(3) DSGVO). Haeufiger Fehler: Widerruf wird erwaehnt, aber ohne konkreten Weg (z.B. Link, E-Mail-Adresse, Abmeldelink).",
|
|
},
|
|
{
|
|
"id": "legal_basis_contract_6b",
|
|
"label": "Art. 6(1)(b) — Vertragserfullung",
|
|
"level": 2, "parent": "legal_basis",
|
|
"patterns": [
|
|
r"art\.\s*6\s*(?:abs\.\s*)?1\s*(?:s\.\s*1\s*)?(?:lit\.\s*)?b",
|
|
r"vertragserf(?:ue|ü)llung",
|
|
r"durchf(?:ue|ü)hrung\s+(?:eines|des|vorvertragliche)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Art. 6(1)(b) gilt nur fuer Daten, die zur Vertragsdurchfuehrung objektiv erforderlich sind. Haeufiger Fehler: Tracking/Werbung auf lit. b stuetzen — laut EDSA (Guidelines 2/2019) ist das unzulaessig. Solche Zwecke erfordern lit. a oder lit. f.",
|
|
},
|
|
{
|
|
"id": "legal_basis_interest_6f",
|
|
"label": "Art. 6(1)(f) — Berechtigtes Interesse",
|
|
"level": 2, "parent": "legal_basis",
|
|
"patterns": [
|
|
r"art\.\s*6\s*(?:abs\.\s*)?1\s*(?:s\.\s*1\s*)?(?:lit\.\s*)?f",
|
|
r"berechtigte[sn]?\s+interesse",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Bei Art. 6(1)(f) muss das konkrete Interesse benannt werden — 'berechtigtes Interesse' allein genuegt nicht. Beispiele: 'IT-Sicherheit', 'Betrugspraevention', 'Direktwerbung (ErwGr. 47)'. Ohne Benennung ist die Angabe intransparent.",
|
|
},
|
|
{
|
|
"id": "legal_basis_balancing",
|
|
"label": "Interessenabwaegung dokumentiert",
|
|
"level": 2, "parent": "legal_basis",
|
|
"patterns": [
|
|
r"interessenabw(?:ae|ä)gung",
|
|
r"(?:ueberwiegen|überwiegen).*interesse",
|
|
r"abw(?:ae|ä)gung.*(?:recht|interesse|freiheit)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Art. 6(1)(f) erfordert eine dokumentierte Interessenabwaegung. Beschreiben Sie: (1) das konkrete Interesse, (2) warum es die Grundrechte der Betroffenen ueberwiegt, (3) welche Schutzmassnahmen bestehen. Fehlende Abwaegung ist ein haeufiger Bussgeldgrund.",
|
|
},
|
|
|
|
# ── L1: Empfaenger ────────────────────────────────────────────────
|
|
{
|
|
"id": "recipients",
|
|
"label": "Empfaenger (Art. 13(1)(e))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"empf(?:ae|ä)nger", r"(?:ueber|über|weiter)mitt(?:el|l)ung",
|
|
r"recipient", r"weitergabe\s+(?:an|von)\s+daten",
|
|
r"dritte", r"third\s+part",
|
|
r"auftragsverarbeit",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Art. 13(1)(e) verlangt Benennung der Empfaenger oder Empfaenger-Kategorien. Haeufiger Fehler: Google Analytics, Meta Pixel o.ae. werden eingebunden, aber nicht als Empfaenger genannt. Jeder Drittdienst mit Datenzugang muss erwaehnt werden.",
|
|
},
|
|
{
|
|
"id": "recipients_categories",
|
|
"label": "Konkrete Empfaenger-Kategorien benannt",
|
|
"level": 2, "parent": "recipients",
|
|
"patterns": [
|
|
r"(?:hosting|server|cloud|payment|zahlungs|versand|logistik|steuerberater|buchhalter|newsletter|crm|erp)",
|
|
r"(?:dienstleister|auftragnehmer|subunternehmer).*(?:fuer|für|im bereich)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "'An Dritte' oder 'an Dienstleister' ist zu unbestimmt. Nennen Sie Kategorien: z.B. 'Hosting (Hetzner)', 'Zahlungsabwicklung (Stripe)', 'E-Mail-Versand (Mailchimp)'. EuGH (C-154/21, 'RW') fordert moeglichst konkrete Benennung.",
|
|
},
|
|
{
|
|
"id": "recipients_processor",
|
|
"label": "Auftragsverarbeiter erwaehnt",
|
|
"level": 2, "parent": "recipients",
|
|
"patterns": [
|
|
r"auftragsverarbeit(?:er|ung)",
|
|
r"art\.\s*28",
|
|
r"avv|av-vertrag|auftragsverarbeitungsvertrag",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Jeder Auftragsverarbeiter (Cloud-Hosting, Newsletter-Tool, CRM) erfordert einen AVV nach Art. 28 DSGVO. Erwaehnen Sie, dass AVVs abgeschlossen sind. Haeufiger Fehler: SaaS-Dienste (Mailchimp, HubSpot) ohne AVV einsetzen — das ist ein eigener DSGVO-Verstoss.",
|
|
},
|
|
|
|
# ── L1: Drittlandtransfer ─────────────────────────────────────────
|
|
{
|
|
"id": "third_country",
|
|
"label": "Drittlandtransfer (Art. 13(1)(f))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"drittland", r"dritt\s*staat", r"drittl(?:ae|ä)nder",
|
|
r"third\s+countr", r"angemessenheitsbeschluss",
|
|
r"standard\s*vertragsklausel", r"scc",
|
|
r"(?:ueber|über)mittlung.*(?:ausserhalb|außerhalb)",
|
|
r"(?:europ(?:ae|ä)ischen\s+wirtschaftsraum|ewr|eea)",
|
|
r"privacy\s+shield", r"data\s+privacy\s+framework",
|
|
# P39: Art. 13(1)(f) verlangt nur Erwaehnung — "keine
|
|
# Uebermittlung in Drittlaender" / "kein Drittlandtransfer"
|
|
# / "alle Verarbeitung innerhalb der EU" sind explizite,
|
|
# konforme Negations-Aussagen.
|
|
r"(?:kein|keine)\s+(?:uebermittlung|übermittlung|transfer|drittland)",
|
|
r"verarbeitung\s+(?:erfolgt\s+)?(?:ausschliesslich|ausschließlich|nur)\s+(?:in|innerhalb)\s+(?:der\s+)?(?:eu|europ(?:ae|ä)ischen\s+union|ewr)",
|
|
r"alle\s+daten\s+(?:bleiben|verbleiben)\s+(?:in|innerhalb)\s+(?:der\s+)?(?:eu|deutschland)",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Art. 13(1)(f) DSGVO: Bei jedem Drittlandtransfer muessen Empfaengerland und Schutzgarantien genannt werden. Pruefen Sie: Google Fonts, reCAPTCHA, YouTube-Embeds, CDNs — all das sind USA-Transfers. Fehlende Angabe war Grundlage zahlreicher DSGVO-Bussgelder.",
|
|
},
|
|
{
|
|
"id": "third_country_mechanism",
|
|
"label": "Transfermechanismus benannt (SCC/DPF/Angemessenheit)",
|
|
"level": 2, "parent": "third_country",
|
|
"patterns": [
|
|
r"standard\s*vertragsklausel|scc|standard\s+contractual",
|
|
r"data\s+privacy\s+framework|dpf",
|
|
r"angemessenheitsbeschluss|adequacy\s+decision",
|
|
r"art\.\s*4[5-9]",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Bei Drittlandtransfers muss der konkrete Schutzmechanismus benannt werden. Hinweis: Das EU-US Privacy Shield ist seit dem EuGH-Urteil 'Schrems II' (Juli 2020) ungueltig. Aktualisieren Sie auf: EU-US Data Privacy Framework/DPF (Angemessenheitsbeschluss seit Juli 2023) oder Standardvertragsklauseln/SCC (Art. 46(2)(c) DSGVO).",
|
|
},
|
|
|
|
# ── L1: Speicherdauer ─────────────────────────────────────────────
|
|
{
|
|
"id": "retention",
|
|
"label": "Speicherdauer (Art. 13(2)(a))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"speicherdauer", r"aufbewahrungsfrist",
|
|
r"(?:wie\s+lange|dauer)\s+(?:der\s+)?(?:werden|gespeicher|speicherung)",
|
|
r"retention\s+period", r"l(?:oe|ö)sch(?:ung|frist|konzept)",
|
|
r"daten\s+werden\s+gel(?:oe|ö)scht",
|
|
r"(?:\d+\s+(?:tage|monate|jahre)|nach\s+\d+\s+(?:tag|monat|jahr))",
|
|
r"dauer\s+der\s+speicherung",
|
|
r"aufbewahrung(?:sdauer|spflicht|szeit)",
|
|
r"gesetzliche.*aufbewahrung",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "Art. 13(2)(a) verlangt Speicherdauer ODER Kriterien zur Festlegung. 'So lange wie noetig' genuegt nicht. Nennen Sie gesetzliche Fristen: 6 Jahre Handelsrecht (§257 HGB), 10 Jahre Steuerrecht (§147 AO), oder eigene Fristen pro Zweck.",
|
|
},
|
|
{
|
|
"id": "retention_periods",
|
|
"label": "Konkrete Zeitangaben (Tage/Monate/Jahre)",
|
|
"level": 2, "parent": "retention",
|
|
"patterns": [
|
|
r"\d+\s+(?:tage?|monate?|jahre?|days?|months?|years?)",
|
|
r"(?:6|10)\s+jahre.*(?:handels|steuer|hgb|ao)",
|
|
r"(?:nach|innerhalb)\s+(?:von\s+)?\d+\s+(?:tag|monat|jahr)",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Konkrete Fristen pro Datenkategorie nennen: Logfiles 7-30 Tage, Rechnungen 10 Jahre (§147 AO), Bewerbungen 6 Monate (AGG-Frist), Newsletter-Daten bis Widerruf. Haeufiger Fehler: Nur eine pauschale Frist fuer alle Datenarten.",
|
|
},
|
|
{
|
|
"id": "retention_deletion",
|
|
"label": "Loeschkonzept/-prozess beschrieben",
|
|
"level": 2, "parent": "retention",
|
|
"patterns": [
|
|
r"l(?:oe|ö)schkonzept", r"l(?:oe|ö)schfrist",
|
|
r"(?:regel|routinem(?:ae|ä)(?:ss|ß)ig).*l(?:oe|ö)sch",
|
|
r"nach\s+(?:ablauf|wegfall|fortfall|entfall|beendigung).*(?:gel(?:oe|ö)scht|l(?:oe|ö)sch)",
|
|
r"(?:gel(?:oe|ö)scht|l(?:oe|ö)schung)\s+nach\s+(?:ablauf|wegfall|fortfall)",
|
|
r"zweck\s+(?:entf(?:ae|ä)llt|wegf(?:ae|ä)llt).*(?:gel(?:oe|ö)scht|l(?:oe|ö)sch)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Art. 5(1)(e) DSGVO (Speicherbegrenzung) erfordert ein Loeschkonzept. Beschreiben Sie den Prozess: automatische Loeschung nach Fristablauf, regelmaessige Pruefzyklen, oder Verweis auf DIN 66398 (Loeschkonzept). Reine Archivierung ohne Loeschfrist genuegt nicht.",
|
|
},
|
|
|
|
# ── L1: Betroffenenrechte ─────────────────────────────────────────
|
|
{
|
|
"id": "rights",
|
|
"label": "Betroffenenrechte (Art. 13(2)(b))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"recht\s+auf\s+auskunft", r"recht\s+auf\s+l(?:oe|ö)schung",
|
|
r"recht\s+auf\s+berichtigung", r"widerspruchsrecht",
|
|
r"art\.\s*1[5-9]", r"art\.\s*2[0-2]",
|
|
r"right\s+to\s+(?:access|erasure|rectification|object)",
|
|
r"betroffenenrecht", r"rechte\s+(?:des|der)\s+betroffenen",
|
|
r"ihnen\s+(?:stehen|steht)\s+(?:ein|folgende)\s+recht",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": "Art. 13(2)(b)-(d) verlangt Nennung ALLER Betroffenenrechte: Auskunft (Art. 15), Berichtigung (16), Loeschung (17), Einschraenkung (18), Portabilitaet (20), Widerspruch (21). Haeufiger Fehler: Art. 18 (Einschraenkung) oder Art. 20 (Portabilitaet) fehlen.",
|
|
},
|
|
{
|
|
"id": "rights_art15",
|
|
"label": "Recht auf Auskunft (Art. 15)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*15", r"recht\s+auf\s+(?:\w+\s+)?auskunft", r"auskunft\s+(?:ueber|über)\s+(?:herkunft|ihre)", r"right\s+(?:of|to)\s+access"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 15 DSGVO: Betroffene koennen kostenlos Auskunft und eine Kopie aller Daten verlangen. Antwortfrist: 1 Monat (Art. 12(3)). Haeufiger Fehler: Kein Hinweis auf Kostenfreiheit oder den konkreten Anfrageweg (E-Mail-Adresse).",
|
|
},
|
|
{
|
|
"id": "rights_art16",
|
|
"label": "Recht auf Berichtigung (Art. 16)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*16", r"recht\s+auf\s+berichtigung", r"right\s+to\s+rectification"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 16 DSGVO: Betroffene koennen Berichtigung unrichtiger Daten und Vervollstaendigung unvollstaendiger Daten verlangen. Nennen Sie den konkreten Weg zur Geltendmachung (z.B. E-Mail an datenschutz@...).",
|
|
},
|
|
{
|
|
"id": "rights_art17",
|
|
"label": "Recht auf Loeschung (Art. 17)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*17", r"recht\s+auf\s+(?:\w+\s+)?l(?:oe|ö)schung", r"(?:berichtigung|korrektur)\s+oder\s+l(?:oe|ö)schung", r"right\s+to\s+erasure"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 17 DSGVO ('Recht auf Vergessenwerden'): Loeschung ist Pflicht, wenn Zweck entfaellt, Einwilligung widerrufen wird oder Daten unrechtmaessig verarbeitet wurden. Erwaehnen Sie auch die Ausnahmen (z.B. gesetzliche Aufbewahrungspflichten §257 HGB, §147 AO).",
|
|
},
|
|
{
|
|
"id": "rights_art18",
|
|
"label": "Recht auf Einschraenkung (Art. 18)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*18", r"einschr(?:ae|ä)nkung\s+der\s+verarbeitung", r"right\s+to\s+restriction"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 18 DSGVO wird am haeufigsten vergessen. Einschraenkung greift z.B. bei bestrittener Richtigkeit oder laufendem Widerspruch. Konkret nennen: 'Statt Loeschung koennen Sie Einschraenkung der Verarbeitung verlangen (Art. 18 DSGVO).'",
|
|
},
|
|
{
|
|
"id": "rights_art20",
|
|
"label": "Recht auf Datenportabilitaet (Art. 20)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*20", r"daten(?:ue|ü)bertrag(?:ung|barkeit)|datenportabilit", r"maschinenlesbar\w*\s+format", r"right\s+to\s+data\s+portability"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 20 DSGVO: Gilt nur bei Verarbeitung auf Basis von Einwilligung (Art. 6(1)(a)) oder Vertrag (Art. 6(1)(b)) UND automatisierter Verarbeitung. Format: strukturiert, gaengig, maschinenlesbar (z.B. JSON, CSV). Nicht anwendbar bei Art. 6(1)(f).",
|
|
},
|
|
{
|
|
"id": "rights_art21",
|
|
"label": "Widerspruchsrecht (Art. 21)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [r"art\.\s*21", r"widerspruchsrecht", r"recht\s+auf\s+widerspruch", r"§\s*23\s+kdg", r"right\s+to\s+object"],
|
|
"severity": "LOW",
|
|
"hint": "Art. 21(4) DSGVO: Der Widerspruchshinweis muss spaetestens zum Zeitpunkt der ersten Kommunikation GESONDERT und in klarer Sprache erfolgen. Haeufiger Fehler: Widerspruchsrecht nur im Fliesstext versteckt — eigener Abschnitt/Hervorhebung noetig.",
|
|
},
|
|
{
|
|
"id": "rights_art22_profiling",
|
|
"label": "Automatisierte Entscheidungen / Profiling (Art. 22)",
|
|
"level": 2, "parent": "rights",
|
|
"patterns": [
|
|
r"art\.\s*22", r"automatisierte\s+entscheidung",
|
|
r"profiling", r"automated\s+(?:decision|individual)",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Art. 13(2)(f): Bei automatisierten Einzelentscheidungen muessen Logik, Tragweite und Auswirkungen erklaert werden. Falls kein Profiling stattfindet, explizit verneinen: 'Es findet keine automatisierte Entscheidungsfindung i.S.d. Art. 22 DSGVO statt.'",
|
|
},
|
|
|
|
# ── L1: Beschwerderecht ───────────────────────────────────────────
|
|
{
|
|
"id": "complaint",
|
|
"label": "Beschwerderecht (Art. 13(2)(d))",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
r"beschwerderecht", r"aufsichtsbeh(?:oe|ö)rde",
|
|
r"right\s+to\s+lodge\s+a\s+complaint",
|
|
r"supervisory\s+authority", r"datenschutzbeh(?:oe|ö)rde",
|
|
r"recht\s+auf\s+beschwerde", r"art\.\s*77",
|
|
r"beschwerde.*(?:wenden|einlegen|erheben)",
|
|
r"(?:zust(?:ae|ä)ndige|competent)\s+(?:beh(?:oe|ö)rde|authority)",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": "Art. 13(2)(d) verlangt einen Hinweis auf das Beschwerderecht bei der Aufsichtsbehoerde (Art. 77 DSGVO). Zustaendig ist die Behoerde am Sitz des Verantwortlichen — z.B. LfDI Baden-Wuerttemberg, BayLDA, oder LfD Niedersachsen. Name und Website angeben.",
|
|
},
|
|
{
|
|
"id": "complaint_authority_named",
|
|
"label": "Konkrete Aufsichtsbehoerde benannt",
|
|
"level": 2, "parent": "complaint",
|
|
"patterns": [
|
|
r"(?:landes|l)(?:beauftragt|datenschutz).*(?:niedersachsen|bayern|nrw|nordrhein|hessen|baden|schleswig|brandenburg|sachsen|berlin|hamburg|bremen|thueringen|thüringen|saarland|rheinland|mecklenburg)",
|
|
r"l(?:an)?fdi\s+\w+",
|
|
r"bfdi",
|
|
r"(?:bayerische|hessische|s(?:ae|ä)chsische|berliner)\s+(?:datenschutz|aufsicht)",
|
|
r"(?:katholisch|evangelisch|kirchlich)\w*\s+datenschutz",
|
|
r"datenschutzzentrum",
|
|
r"kd(?:oe|ö)r",
|
|
],
|
|
"severity": "LOW",
|
|
"hint": "Vollstaendigen Namen, Adresse und Website der Aufsichtsbehoerde angeben. Haeufiger Fehler: 'die zustaendige Aufsichtsbehoerde' ohne Konkretisierung. Korrekt z.B.: 'LfDI BW, Koenigstrasse 10a, 70173 Stuttgart, www.baden-wuerttemberg.datenschutz.de'.",
|
|
},
|
|
|
|
# ── L1: Versionsdatum / Nachweisbarkeit der Einwilligung ─────────
|
|
#
|
|
# Art. 7 Abs. 1 DSGVO verlangt vom Verantwortlichen, die Einwilligung
|
|
# NACHWEISEN zu koennen — inkl. WELCHEM Stand der DSE der Nutzer
|
|
# zugestimmt hat. Ohne Datum/Versionsnummer ist das nicht moeglich.
|
|
{
|
|
"id": "dse_version_date",
|
|
"label": "Stand/Versionsdatum der DSE auffindbar",
|
|
"level": 1, "parent": None,
|
|
"patterns": [
|
|
# "Stand: April 2024", "Stand Januar 2026"
|
|
r"stand:?\s*(?:januar|februar|m(?:ae|ä)rz|april|mai|juni|juli|"
|
|
r"august|september|oktober|november|dezember)\s+\d{4}",
|
|
# "Stand: 01.04.2024", "Stand 04/2024", "Stand 2024-04-01"
|
|
r"stand:?\s*\d{1,2}[./-]\d{1,2}[./-]\d{2,4}",
|
|
r"stand:?\s*\d{4}-\d{2}(?:-\d{2})?",
|
|
r"stand:?\s*\d{1,2}/\d{2,4}",
|
|
# "Letzte Aktualisierung: …", "Zuletzt geaendert: …"
|
|
r"letzte\s+(?:aktualisierung|(?:ae|ä)nderung|anpassung)",
|
|
r"zuletzt\s+(?:ge)?(?:ae|ä)ndert",
|
|
r"g(?:ue|ü)ltig\s+(?:ab|seit|f(?:ue|ü)r)",
|
|
r"version\s+\d+[.\d]*",
|
|
r"version:?\s*v?\d+\.\d+",
|
|
# Englisch
|
|
r"last\s+(?:updated|modified|revised|amended)",
|
|
r"effective\s+(?:date|as\s+of)",
|
|
r"as\s+of\s+(?:january|february|march|april|may|june|july|"
|
|
r"august|september|october|november|december)\s+\d{4}",
|
|
],
|
|
"severity": "HIGH",
|
|
"hint": (
|
|
"Art. 7 Abs. 1 DSGVO: Verantwortlicher muss NACHWEISEN koennen, "
|
|
"welcher DSE-Version der Nutzer zugestimmt hat. Ohne ein "
|
|
"sichtbares Versionsdatum / 'Stand: …' ist die Einwilligung "
|
|
"nicht beweisbar — Aufsichtsbehoerden + Verbraucherzentralen "
|
|
"stossen genau hier nach. Korrekt: 'Stand: Januar 2026' oder "
|
|
"'Version 3.2 — gueltig ab 01.01.2026' sichtbar am Anfang oder "
|
|
"Ende der DSE."
|
|
),
|
|
},
|
|
{
|
|
"id": "dse_version_proof",
|
|
"label": "Versions-eindeutige Beweis-Verankerung (PDF / Download / Archiv-Link)",
|
|
"level": 2, "parent": "dse_version_date",
|
|
"patterns": [
|
|
# PDF-Download verfuegbar
|
|
r"\.pdf\b",
|
|
r"(?:dse|datenschutz|privacy)[\w\-]*\.pdf",
|
|
# Download-Hinweis
|
|
r"(?:dse|datenschutzerkl(?:ae|ä)rung|datenschutzhinweis(?:e)?)"
|
|
r"[^.]{0,80}herunterladen",
|
|
r"als\s+pdf\s+(?:herunterladen|speichern|laden|verf(?:ue|ü)gbar)",
|
|
r"download[^.]{0,40}(?:dse|datenschutzerkl|privacy|policy)",
|
|
# Konkrete Versions-URL (Wayback / Archiv / versionierte URL)
|
|
r"web\.archive\.org",
|
|
r"version[\-_]?archive",
|
|
r"(?:dse|privacy)-v?\d+[.\d]*\.html?",
|
|
],
|
|
"severity": "MEDIUM",
|
|
"hint": (
|
|
"Beste-Praxis nach DSK-Orientierungshilfe 2024: fuer den Beweis "
|
|
"der konkreten DSE-Version sollte zusaetzlich zur Web-Version "
|
|
"ein PDF-Download oder ein versionierter Archiv-Link verfuegbar "
|
|
"sein. Reine HTML-DSE ohne Snapshot ist juristisch fragil — "
|
|
"der Anbieter kann die DSE jederzeit aendern und das Original "
|
|
"ist nicht mehr nachweisbar. Empfehlung: 'Aktuelle DSE als PDF "
|
|
"herunterladen' im Kopfbereich, oder eindeutige Versions-URLs "
|
|
"(z.B. /dse/v2026-01.html)."
|
|
),
|
|
},
|
|
]
|