Files
dogfather-universe/_probe2.mjs
T
DogFatherGitandClaude Opus 5 8fa15c04f1 Kasse und Google-Anmeldung in der Inhaltsrichtlinie freigegeben
Fortsetzung des Musik-Fundes: PayPal und Google haetten an derselben
Stelle still versagt, sobald Dogi seine Zugangsdaten eintraegt -- leerer
Bereich statt Bezahlknopf, ohne Fehlermeldung, ohne Protokolleintrag.

Vorgehen bewusst gemessen statt geraten: Erst die Angaben der Anbieter
(PayPal "Best Practices", Google CSP-Abschnitt der Setup-Anleitung),
dann im echten Browser mit PayPals offizieller Testkennung
"client-id=test" nachgemessen und die Verstoesse ueber das Ereignis
securitypolicyviolation eingesammelt. Die Messung hat zwei Dinge
gefunden, die in keiner Anleitung standen:

- www.sandbox.paypal.com (frame-src + connect-src). Beim Einrichten
  testet man mit Sandbox-Zugangsdaten; ohne diesen Eintrag haette die
  Kasse in genau dieser Phase nicht abgeschlossen werden koennen.
- accounts.google.com/gsi/style (style-src). 'unsafe-inline' deckt das
  NICHT ab -- es erlaubt nur Stile im Dokument, keine nachgeladene
  Stilvorlage. Der Anmelde-Knopf waere unformatiert erschienen.

Bewusst einzelne Adressen statt PayPals vorgeschlagener Platzhalter
(*.paypal.com): Was die Messung nicht gebraucht hat, steht nicht drin.
Skripte bleiben ohne 'unsafe-inline' -- die Pruefsummen-Loesung fuer die
eigenen Inline-Bloecke bleibt unangetastet, und ein zusaetzliches
'unsafe-inline' waere neben Pruefsummen ohnehin wirkungslos.

Neuer Test pruef-kasse.mjs (15 Pruefungen): laedt das echte PayPal-SDK,
baut die Bezahlknoepfe wirklich auf, rendert den echten Google-Knopf und
verlangt NULL Verstoesse. Bestandstest pruef-inhaltsrichtlinie.mjs (22)
und pruef-musik.mjs (17) bleiben gruen -- inklusive der Gegenprobe, dass
eingeschleuste Skripte weiterhin blockiert werden.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-27 15:11:27 +02:00

39 lines
3.0 KiB
JavaScript

import { chromium } from "playwright";
import { spawn } from "node:child_process";
const server = spawn(process.execPath, ["index.js"], { cwd: "server", env: { ...process.env, PORT: "4434" }, stdio: "ignore" });
const warte = async () => { for (let i=0;i<40;i++){ try { if ((await fetch("http://127.0.0.1:4434/index.html")).ok) return; } catch{} await new Promise(r=>setTimeout(r,250)); } throw new Error("kein Server"); };
await warte();
const b = await chromium.launch();
const s = await b.newPage();
await s.goto("http://127.0.0.1:4434/abonnieren.html", { waitUntil: "domcontentloaded" });
await s.evaluate(() => { window.__v = []; document.addEventListener("securitypolicyviolation", (e) => window.__v.push({ dir: e.violatedDirective, blockiert: e.blockedURI })); });
const paypal = await s.evaluate(async () => {
const geladen = await new Promise((res) => { const sk = document.createElement("script"); sk.src = "https://www.paypal.com/sdk/js?client-id=test&currency=EUR"; sk.onload = () => res(true); sk.onerror = () => res(false); document.body.appendChild(sk); setTimeout(() => res(false), 15000); });
if (!geladen || !window.paypal) return { geladen, buttons: false };
const ziel = document.createElement("div"); ziel.id = "pp-test"; ziel.style.width = "300px"; document.body.appendChild(ziel);
try { await window.paypal.Buttons({}).render("#pp-test"); } catch (e) { return { geladen, buttons: false, fehler: String(e).slice(0,150) }; }
const f = ziel.querySelector("iframe");
return { geladen, buttons: !!f, rahmenHoehe: f ? Math.round(f.getBoundingClientRect().height) : 0 };
});
console.log("PAYPAL:", JSON.stringify(paypal));
const google = await s.evaluate(async () => {
const geladen = await new Promise((res) => { const sk = document.createElement("script"); sk.src = "https://accounts.google.com/gsi/client"; sk.onload = () => res(true); sk.onerror = () => res(false); document.head.appendChild(sk); setTimeout(() => res(false), 15000); });
if (!geladen || !window.google) return { geladen, knopf: false };
const ziel = document.createElement("div"); ziel.id = "g-test"; document.body.appendChild(ziel);
try {
window.google.accounts.id.initialize({ client_id: "000000000000-testtesttesttesttesttest.apps.googleusercontent.com", callback: () => {} });
window.google.accounts.id.renderButton(ziel, { type: "standard" });
} catch (e) { return { geladen, knopf: false, fehler: String(e).slice(0,150) }; }
await new Promise(r => setTimeout(r, 4000));
return { geladen, knopf: ziel.children.length > 0, inhalt: ziel.innerHTML.slice(0, 60) };
});
console.log("GOOGLE:", JSON.stringify(google));
await s.waitForTimeout(3000);
const v = await s.evaluate(() => window.__v);
const zus = {};
for (const e of v) { const k = e.dir + " <- " + (e.blockiert || "(inline)"); zus[k] = (zus[k]||0)+1; }
console.log("\nVERSTOESSE:", Object.keys(zus).length === 0 ? "KEINE" : "");
Object.entries(zus).sort().forEach(([k,n]) => console.log(" " + n + "x " + k));
console.log("\nRahmen:"); s.frames().forEach(f => console.log(" " + f.url().slice(0,75)));
await b.close(); server.kill();