fix(audit): P98 + P100 — Cookie-Tabellen-Whitespace + Anpassen-Button-Check
CI / detect-changes (push) Successful in 11s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 18s
CI / loc-budget (push) Failing after 17s
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / detect-changes (push) Successful in 11s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 18s
CI / loc-budget (push) Failing after 17s
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
P98: HTML-Tabellen-Zellen wurden bei VW-Cookie-Richtlinie ohne Whitespace
verkettet ('smartSignals2UiDsmartSignals2sUiDsmartSignals2CPs...'). Grund:
el.textContent ignoriert Block-Element-Grenzen. Fix: innerText (whitespace-
respecting) statt textContent. Cookie-Namen werden jetzt einzeln erkannt —
VW-Lauf sollte ~100 Cookies statt 1 finden.
P100: Banner-Check fuer 'Anpassen'/'Einstellungen'-Button im Initial-Banner.
VW-Pattern: nur 2 Buttons (Nur technisch notwendige / Alle akzeptieren),
keine granulare Wahl vor Akzeptanz/Ablehnung. Faktische Manipulation
Richtung Pauschal-Akzeptanz. HIGH-Finding nach EDPB 5/2020 §82.
Pattern: anpassen/einstellungen/cookie-einstellungen/manage cookies/
preferences/customize.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -196,6 +196,33 @@ async def check_banner_text(page) -> dict:
|
||||
legal_ref="EDPB 5/2020 (Consent) + DSK-OH 2024 (Telemedien)",
|
||||
))
|
||||
|
||||
# P100: Granular-Wahl-Pruefung — "Anpassen"/"Einstellungen"-Button
|
||||
# im Initial-Banner. Wenn er FEHLT (VW-Pattern), ist die granulare
|
||||
# Cookie-Wahl erst nach Akzeptanz/Ablehnung moeglich — faktische
|
||||
# Manipulation Richtung "Alle akzeptieren". EDPB 5/2020 §82.
|
||||
granular_button_texts = [
|
||||
"anpassen", "einstellungen", "cookie-einstellungen",
|
||||
"cookies verwalten", "manage cookies", "customize",
|
||||
"weitere optionen", "more options", "settings",
|
||||
"individuell", "detaillierte einstellungen",
|
||||
"praeferenzen", "preferences",
|
||||
]
|
||||
has_granular_button = any(t in banner_lower for t in granular_button_texts)
|
||||
if not has_granular_button:
|
||||
violations.append(Violation(
|
||||
service="Cookie-Banner",
|
||||
severity="HIGH",
|
||||
text="Granulare Cookie-Auswahl im Initial-Banner nicht "
|
||||
"moeglich (kein 'Anpassen'/'Einstellungen'-Button). "
|
||||
"Nutzer koennen nur 'Alle akzeptieren' oder 'Nur "
|
||||
"technisch notwendige' waehlen — Detailwahl pro "
|
||||
"Kategorie erst nach Akzeptanz/Ablehnung. Das ist "
|
||||
"faktische Manipulation Richtung Pauschal-Akzeptanz.",
|
||||
legal_ref="EDPB Guidelines 5/2020 §82 (granular consent), "
|
||||
"§25 Abs. 1 TDDDG, Art. 4(11) DSGVO (informierte "
|
||||
"Einwilligung)",
|
||||
))
|
||||
|
||||
# Check 5: Pre-ticked checkboxes (EuGH Planet49)
|
||||
try:
|
||||
pre_checked = await page.evaluate("""
|
||||
|
||||
@@ -506,14 +506,21 @@ async def discover_dsi_documents(
|
||||
];
|
||||
for (const sel of selectors) {
|
||||
const el = document.querySelector(sel);
|
||||
if (el && el.textContent.trim().length > 200) {
|
||||
return el.textContent.trim();
|
||||
if (el) {
|
||||
// P98: innerText statt textContent — innerText
|
||||
// respektiert Whitespace zwischen Block-Elementen.
|
||||
// textContent verkettet HTML-Tabellen-Zellen ohne
|
||||
// Spaces (VW-Cookie-Tabelle: ~100 Cookie-Namen
|
||||
// wurden zu einem Klumpen "smartSignals2UiDsmartSignals2sUiD...").
|
||||
const txt = (el.innerText || el.textContent || '').trim();
|
||||
if (txt.length > 200) return txt;
|
||||
}
|
||||
}
|
||||
// Fallback: full body minus nav/header/footer
|
||||
const body = document.body.cloneNode(true);
|
||||
body.querySelectorAll('nav, header, footer, script, style, [class*="nav"], [class*="sidebar"]').forEach(e => e.remove());
|
||||
return body.textContent?.trim() || '';
|
||||
// P98: innerText respektiert Whitespace (s.o.)
|
||||
return (body.innerText || body.textContent || '').trim();
|
||||
}
|
||||
""")
|
||||
if text and len(text) > 50:
|
||||
|
||||
Reference in New Issue
Block a user