MAISON CODE .
/ Security · Hydrogen · Remix · OWASP · Architecture

CSP-Leitfaden: Shopify Hydrogen sperren

Cross-Site Scripting (XSS) ist die größte Bedrohung für Headless Commerce. Ein technischer Leitfaden zur Implementierung von Strict CSP mit Nonces in Remix und Hydrogen.

AB
Alex B.
CSP-Leitfaden: Shopify Hydrogen sperren

Im E-Commerce ist Vertrauen die einzige Währung. Wenn ein Kunde seine Kreditkartennummer auf Ihrer Website eingibt, vertraut er darauf, dass Sie diese sichern. Wenn Sie jedoch eine Schwachstelle im Bereich Cross-Site Scripting (XSS) haben, kann ein Angreifer ein Skript einschleusen, das Tastenanschläge liest. Der Angreifer erhält die Kreditkarte. Sie bekommen die Klage.

Der Schutz gegen XSS ist die Content Security Policy (CSP). Es handelt sich um eine Whitelist. Dem Browser wird gesagt: „Laden Sie nur Skripte von diesen Domänen. Blockieren Sie alles andere.“

Die Implementierung von CSP in einer Single Page App (SPA) wie Shopify Hydrogen (Remix) ist aufgrund von Hydration und Drittanbieter-Tags bekanntermaßen schwierig. Dies ist der ultimative Leitfaden, um es richtig zu machen.

Warum Maison Code darüber spricht

Bei Maison Code Paris fungieren wir als das architektonische Gewissen unserer Kunden. Wir übernehmen oft „moderne“ Stacks, die ohne grundlegendes Verständnis für Skalierung gebaut wurden.

Wir diskutieren dieses Thema, weil es einen kritischen Wendepunkt in der technischen Reife darstellt. Die korrekte Implementierung unterscheidet ein fragiles MVP von einer widerstandsfähigen Plattform auf Unternehmensniveau.

1. Die Strategie: Strenges CSP mit Nonces

Früher haben wir „Domain Whitelisting“ verwendet. script-src 'self' https://google-analytics.com https://facebook.com Das ist unsicher. Wenn Google Analytics eine Open-Redirect-Schwachstelle aufweist, kann der Angreifer Ihren CSP umgehen.

Der moderne Standard ist Nonces (Einmal verwendete Zahl).

  1. Der Server generiert für jede Anfrage ein zufälliges kryptografisches Token („abc123yz“).
  2. Der Server fügt einen Header hinzu: „Content-Security-Policy: script-src ‚nonce-abc123yz‘“.
  3. Der HTML-Code enthält das Token: „

Wenn ein Angreifer „<script>alert(1)</script>“ einfügt, hat es keine Nonce. Der Browser blockiert es.

2. Umsetzung in Remix (Wasserstoff)

In Remix müssen wir die Nonce im Root-Loader generieren und weitergeben.

Schritt 1: Nonce in „entry.server.tsx“ generieren

„tsx // app/entry.server.tsx import { genericNonce } from ’./utils’; // crypto.randomBytes(16).toString(‘base64’)

Standardfunktion exportieren handleRequest(request, ResponseStatusCode, ResponseHeaders, RemixContext) { const nonce = genericNonce();

// Direktiven definieren const csp = [ „default-src ‚self‘“, script-src 'self' 'nonce-€{nonce}' https://cdn.shopify.com https://challenges.cloudflare.com, “style-src ‘self’ ‘unsafe-inline’ https://fonts.googleapis.com”, // unsafe-inline wird normalerweise für CSS-in-JS benötigt „img-src ‚self‘-Daten: https://cdn.shopify.com“, „connect-src ‚self‘ https://monorail-edge.shopifysvc.com https://www.google-analytics.com“, “frame-ancestors ‘none’”, // Anti-Clickjacking ].join(’; ’);

ResponseHeaders.set(‘Content-Security-Policy’, csp);

// Nonce an den Kontext übergeben, damit es verwenden kann return ; } „

Schritt 2: Nonce an Skripte in „root.tsx“ anhängen

„tsx // app/root.tsx import { useNonce } aus ‘@shopify/hydrogen’;

Standardfunktion App() exportieren { const nonce = useNonce();

zurück ( <Körper> ); } „

Jetzt verfügt jedes von Remix generierte Skript-Tag legal über die Nonce.

3. Die Ausfallsicherung „Nur Bericht“.

Die Bereitstellung eines CSP ist beängstigend. Wenn Sie eine Domain vergessen (z. B. „fonts.gstatic.com“), funktioniert Ihre Website nicht mehr. Lösung: Nur-Berichtsmodus.

  1. Legen Sie die Überschrift „Content-Security-Policy-Report-Only“ fest.
  2. Der Browser lädt die Ressourcen, protokolliert den Verstoß jedoch an der Konsole (und einem Endpunkt).
  3. Führen Sie dies 2 Wochen lang durch. Überwachen Sie Protokolle.
  4. Sobald die Protokolle sauber sind, wechseln Sie in den Durchsetzungsmodus.

4. Berichterstattung: Verwenden von Sentry

Das Auslesen von CSP-Verstößen in der Konsole ist für Produktionsbenutzer nutzlos. Sie benötigen einen Sammlungsendpunkt. Sentry (und Datadog) unterstützen CSP-Reporting-Schlüsselwerte. report-uri https://o450.ingest.sentry.io/api/.../security/?sentry_key=...; Wenn ein Benutzer in Brasilien einen CSP-Verstoß auslöst (möglicherweise eine Malware-Erweiterung), werden Sie von Sentry benachrichtigt. Rauschfilterung: Sie werden viel Rauschen von Browsererweiterungen bemerken (LastPass verursacht Verstöße). Ignorieren Sie die Schemata „moz-extension“ und „chrome-extension“. Konzentrieren Sie sich auf „http“-Injektionen.

5. Subressourcenintegrität (SRI)

Was passiert, wenn das CDN gehackt wird? Wenn Sie „https://code.jquery.com/jquery.min.js“ laden und ein Hacker diese Datei im CDN ändert, umgeht er Ihren CSP (da die Domain auf der Whitelist steht). Fix: SRI verwenden. <script src="..." Integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin="anonymous"></script> Der Browser hasht die heruntergeladene Datei. Wenn es nicht mit dem Attribut „Integrität“ übereinstimmt, wird die Ausführung verweigert. Dies garantiert, dass Code sich nicht ändern kann, ohne dass Sie eine neue HTML-Datei bereitstellen.

6. Drittanbieter-Hölle (Google Tag Manager)

Marketing liebt GTM. Sicherheit hasst GTM. GTM fügt Skripte dynamisch ein. Verbreitet GTM die Nonce? Ja, wenn richtig konfiguriert.

In Ihrem GTM-Snippet müssen Sie die „Nonce“ des übergeordneten Skripts überprüfen und weiterleiten. Allerdings sind die meisten Drittanbieter-Pixel (Facebook) nicht nonce-aware. Kompromiss: Sie müssen ihre Domänen oft zusätzlich zur Nonce in „script-src“ auf die Whitelist setzen.

script-src 'self' 'nonce-...' https://connect.facebook.net ...

5. Clickjacking verhindern (Frame Ancestors)

Beim Clickjacking bettet ein Angreifer Ihre Website in einen „

Fix: frame-ancestors 'none'. Dies verbietet jedem das Iframeing Ihrer Website. Wenn Sie ein Iframe benötigen (z. B. von einem Partner), setzen Sie ihn auf die Whitelist: „frame-ancestors ‚self‘ https://partner.com“.

6. CSP verletzt? Was geschieht?

Wenn ein CSP verletzt wird, gibt der Browser einen vereinfachten Fehler in der Konsole aus. „Das Laden des Skripts von „http://evil.com/hack.js“ wurde abgelehnt, da es gegen die folgende Richtlinie zur Inhaltssicherheit verstößt: „script-src ‚self‘ …“.“.

Für den Benutzer schlägt die Ausführung des bösartigen Skripts einfach fehl. Der Rest der Seite funktioniert gut. Der Angriff wird stillschweigend neutralisiert.

7. Vertrauenswürdige Typen (Die Zukunft der XSS-Verteidigung)

CSP blockiert das Laden schädlicher Skripte. Vertrauenswürdige Typen blockieren das Schreiben von Schadcode. Es zwingt Sie dazu, Zeichenfolgen zu bereinigen, bevor sie das DOM berühren. element.innerHTML = dirtyString; -> Blockierter Browserfehler. Sie müssen es einpacken: element.innerHTML = DOMPurify.sanitize(dirtyString); Dadurch wird ein „Policy“-Objekt erstellt. Der Browser garantiert, dass nur von Richtlinien erstellte Zeichenfolgen das DOM berühren können. Es zerstört eine ganze Klasse von DOM-basierten XSS-Schwachstellen.

8. Web-Worker-Sicherheit

Worker (Service Worker, Web Worker) sind isoliert. Aber sie können immer noch gefährlich sein (Crypto Mining). Sie müssen sie durch bestimmte Anweisungen einschränken:

  • worker-src 'self' blob:;: Nur Worker aus Ihrer Domäne zulassen.
  • child-src 'self': Beschränkt Iframes und Worker. Angreifer lieben es, einen Worker im Hintergrund hochzufahren, um anderen Websites DDoS zuzuweisen oder Bitcoin zu schürfen. Ihr CSP stoppt dies.

10. CSP für WebAssembly (WASM)

Wenn Sie WASM verwenden (z. B. zur clientseitigen Größenänderung von Bildern), benötigen Sie spezielle Anweisungen. script-src 'unsafe-eval' (für WASM-Kompilierung) ist gefährlich. Moderne Browser unterstützen: „script-src ‚wasm-unsafe-eval‘“. Dadurch kann WASM kompiliert werden, ohne die Tür zu JavaScript „eval()“ zu öffnen. Es hält die „Bad Good“-Teile von den „Bad Bad“-Teilen getrennt.

11. Der Nonce-Lebenszyklus (Anfrageumfang)

Eine Nonce ist nutzlos, wenn sie statisch ist. Wenn Sie „nonce=“123” in Ihrem HTML fest codieren, fügt ein Angreifer einfach „<script nonce="123"> ein. Die Nonce MUSS pro Anfrage generiert werden. Remix-Muster:

  1. „entry.server.tsx“: Generieren Sie „nonce = crypto.randomUUID()“.
  2. An „“ übergeben.
  3. Hydratieren Sie den Client mit „“. Dadurch wird sichergestellt, dass ich beim Aktualisieren der Seite eine neue Nonce erhalte. Der Angreifer kann es nicht erraten.

12. Stile vs. Skripte („unsafe-inline“)

Wir erlauben oft „style-src ‚unsafe-inline‘“. Warum? Weil CSS-in-JS-Bibliotheken (Emotion, Styled Components) zur Laufzeit „ (Zero-Runtime CSS), die statische „.css“-Dateien generiert. Dann können Sie „unsafe-inline“ entfernen und CSP Nirvana erreichen.

13. Warum Maison Code?

Bei Maison Code glauben wir, dass Sicherheit gleichbedeutend mit Reputation ist. Ein Hack kostet nicht nur Geld; es kostet Vertrauen. Wir geben uns nicht mit „Es funktioniert“ zufrieden. Wir fordern „Es ist sicher“. Wir implementieren strikte Crypto-Nonce-CSPs für jeden Kunden. Wir überwachen die Verstöße (Sentry) und schließen Lücken, bevor sie ausgenutzt werden. Wir schlafen nachts gut, weil wir wissen, dass der Browser unsere Regeln durchsetzt.

12. Fazit

Ein strikter CSP ist das Markenzeichen eines ausgereiften Ingenieurteams. Es zeigt, dass Sie die feindselige Umgebung des Webs verstehen. Es schützt Ihre Kunden vor Magecart, Keyloggern und Datenexfiltration. Die Einrichtung ist schwierig, aber für jede Marke, die Zahlungsdaten erfasst, obligatorisch. Warten Sie nicht auf den Bruch. Schließen Sie jetzt die Tür ab.


Ist Ihr Geschäft anfällig?

Wir führen Penetrationstests und CSP-Implementierung für Shopify Plus-Marken durch. Beauftragen Sie unsere Architekten.