Blog
Technische Deep Dives

Einbettbare Chat-Widgets: Architektur und Sicherheit

Der zweistufige Loader und das sandboxed iframe hinter dem Widget von Simmetric Chat, mit isolierten Sitzungen, Rate Limiting und geschichtetem Wissensdatenbank-Zugriff.

Simmetric Team7 Min. Lesezeit30/04/2026

Ihre Wissensdatenbank ist eine Produktoberfläche

Die Dokumente, die Ihr Team schreibt - Produktdokumentation, Support-Artikel, interne Wikis - beantworten dieselben Fragen, die sich Besucher Ihrer Website bereits stellen. Ein eingebettetes Chat-Widget verwandelt diese Wissensdatenbank in eine konversationelle Eingangstür: Besucher fragen mit ihren eigenen Worten, und Antworten fließen mit Zitaten zurück, verankert in den Workspaces, die Sie freigeben möchten.

Der schwierige Teil ist nicht der Chat; es ist, quasi nicht vertrauenswürdige Software in die Seite von jemand anderem einzubetten, ohne selbst zur Angriffsfläche zu werden. Das Widget-System von Simmetric Chat - Enterprise-Stufe - ist um diese Einschränkung herum gebaut. Dieser Artikel geht die Architektur durch: das zweistufige Embed, die sandboxed Runtime, die Sitzungsisolation, das Rate Limiting und das geschichtete Zugriffsmodell auf die Wissensdatenbank, das entscheidet, was die Frage eines Besuchers erreichen kann - und was nicht.

Das zweistufige Embed: Loader und sandboxed iframe

Das Widget wird in zwei Schritten ausgeliefert, und die Aufteilung ist bewusst:

  1. Das Loader-Skript. Fügen Sie ein Script-Tag zu Ihrer Website hinzu, das auf den Widget-Dienst mit Ihrer Widget-ID zeigt. Der Loader ist eine kleine JavaScript-Datei, die ein iframe in der Host-Seite erstellt.
  2. Das iframe-Panel. Das iframe lädt eine eigenständige Preact-Anwendung - als IIFE-Bundle mit Inline-CSS kompiliert -, die den schwebenden Button, das Chat-Panel und jede Interaktion in ihrem eigenen Dokument rendert.
html
<script src="https://your-simmetric-chat.com/widget/loader.js?widgetId=WIDGET_ID"></script>

Warum die Chat-Oberfläche nicht direkt in die Host-Seite injizieren? Weil das Interpolieren von Zeichenketten nicht vertrauenswürdiger Inhalte in eine Host-Seite der klassische XSS-Pfad ist - und der gesamte Inhaltsfluss eines Widgets ist quasi nicht vertrauenswürdig: Er enthält Modellausgaben, Dokumentenauszüge und Besuchereingaben. Die Oberfläche in einem sandboxed iframe mit opaker Herkunft laufen zu lassen, entfernt diese Risikoklasse gänzlich: Chat-Inhalte werden nie im Kontext Ihrer Seite ausgeführt, und Widget-Stile können nicht mit Ihren kollidieren (oder umgekehrt).

Die alten Embed-Routen per Zeichenketten-Interpolation wurden genau aus diesem Grund aus dem Produkt entfernt - das zweistufige Pattern ist keine Option unter vielen, es ist das Embed. Die IIFE-Kompilierung des Widgets existiert aus demselben Grund: Das Panel ist eine einzelne eigenständige Datei ohne Modulsystem und ohne Laden externer Assets zur Laufzeit, was die Netzwerkoberfläche des iframes vorhersehbar hält.

Was wo läuft

Das Widget berührt drei Prozesse, und die Kenntnis der Grenzlandkarte erklärt jede folgende Sicherheitseigenschaft:

  • Der Hauptserver besitzt CRUD und Branding der Widgets, die Workspace-Verknüpfung, die interne API, die der Widget-Dienst aufruft, und die Lead- und Analytics-Endpunkte auf der Admin-Seite. Der gesamte interne Widget-Router ist an das Feature gebunden - ist das Widget-Feature aus, antwortet er auf jeder Route mit 402.
  • Der Widget-Dienst ist die öffentliche Embed-Oberfläche: JS-Loader, iframe-HTML, Sitzungserstellung, Auslieferung der gecachten Konfiguration, der SSE-Proxy des Chats zum Hauptserver und der Lead-Endpunkt. Er authentifiziert sich beim Hauptserver mit einem dedizierten API-Schlüssel und bringt eigene Rate Limiter mit.
  • Das iframe ist der Preact-Client: Session-Bootstrap, SSE-Streaming, Anzeige der Zitate, vorgeschlagene Fragen, die Consent-Barriere und die Lead-Karte.

Der Chat-Proxy leitet dasselbe Ereignisformat wie die interne Streaming-API weiter - Statusmeldungen, Plan-Ankündigungen, gestreamte Tokens, Zitate und terminale done/error-Ereignisse -, sodass Besucher dieselbe Pipeline erleben, die Ihr Team intern nutzt, mit den Berechtigungen des Widgets.

Isolierte Sitzungen für anonyme Besucher

Besucher authentifizieren sich nie; das Widget prägt die Identität an ihrer Stelle. Wenn das Panel sich öffnet, fordert es eine Sitzung vom Widget-Dienst an, der den Hauptserver bittet, eine zu erstellen: ein 256-Bit-Hex-Token, serverseitig, mit 24 Stunden Ablauf. Jede weitere Widget-Anfrage validiert gegen diese Sitzung - kein JWT aus den Apps Ihrer Nutzer, kein Cookie, das Origins überquert, keinerlei Umgebungs-Credentials.

Sitzungsisolation ist es, was den Zustand eines Besuchers außer Reichweite eines anderen hält: Konversationen sind anonym, Zähler und Rate-Limit-Zustand hängen am Sitzungstoken statt an einer IP oder einem Fingerprint, und die Host-Seite sieht das Token nie - es lebt im Storage des iframes selbst, ausgetauscht mit dem Host über ein kleines versioniertes postMessage-Protokoll, das beide Seiten gegen das exakt erwartete contentWindow validieren, sodass von anderen Skripten gefälschte Nachrichten ignoriert werden.

Die Konfigurationsauslieferung folgt derselben Disziplin. Die Widget-Konfiguration - Branding, Willkommensnachricht, vorgeschlagene Fragen - wird dem iframe über einen JSON-Block im iframe-Dokument selbst übergeben, serverseitig injiziert, nicht über URL-Parameter, die ein Besucher manipulieren könnte. Der Besucher kann nichts beeinflussen, was der Server nicht auflöst: Eine neuere Ergänzung besiegelt dies weiter, indem die Konfiguration jedes Widgets den LLM-Provider und das Modell auswählen kann, die seine Chat-Antworten bedienen - serverseitig bei jeder Chat-Anfrage aufgelöst, nie vom Client geliefert.

Rate Limiting als Vertrag einer öffentlichen Oberfläche

Ein Widget ist ein öffentlicher Endpunkt auf Ihrer Infrastruktur, daher ist Missbrauchskontrolle Teil der Architektur, kein Nachgedanke. Die Limits sind nach Oberfläche geschichtet:

  • Chat-Limits pro Sitzung: 20 Nachrichten pro Stunde und 5 Konversationen pro Tag pro Sitzung; überschrittene Limits antworten mit 429 und einem retryAfter-Hinweis, und das Widget zeigt eine Rate-Limit-Warnung statt still zu scheitern.
  • API-Limiter pro Schlüssel: Die Aufrufe des Widget-Dienstes an den Hauptserver sind pro gehashtem API-Schlüssel begrenzt, damit ein fehlerhaftes Deployment nicht die gemeinsame Oberfläche erschöpfen kann.
  • Lead-Limiter: Der Lead-Capture-Endpunkt ist die engste Barriere mit 3 Anfragen pro Stunde, weil ein öffentliches Formular genau dort ist, wo sich Automatisierungsmissbrauch konzentriert.
  • CORS fail-closed: Der Origin-Header jeder Anfrage wird gegen die Liste erlaubter Origins des Widgets selbst validiert, die vom Admin-Panel aus bearbeitet werden kann. Nicht erlaubte Preflight-Anfragen werden abgewiesen - und wenn die Origin-Prüfung die Datenbank nicht erreichen kann, wird der Zugriff verweigert statt gewährt.

Das Ergebnis ist eine öffentliche Chat-Oberfläche, die unter Last oder Missbrauch anmutig degradiert, statt zusammenzubrechen oder alle auszuschließen.

Geschichteter Zugriff auf die Wissensdatenbank

Ein Widget sollte aus dem Wissen antworten, das Sie veröffentlichen möchten - nicht mehr. Die Schichtung des Zugriffs wird strukturell erzwungen, nicht per Prompt:

  • Workspace-Whitelist. Jedes Widget ist mit einem oder mehreren Workspaces verknüpft, und die Whitelist wird bei jedem Update atomar ersetzt. Das Wissen, aus dem ein Widget schöpfen kann, ist exakt die Vereinigung der Vektor-Collections und Dokumente der verknüpften Workspaces - ein Support-Widget kann Ihren öffentlichen Dokumentations-Workspace sehen, ohne je die Daten interner Projekte zu berühren.
  • Feature-Bindung. Das Erstellen von Widgets erfordert das Widget-Feature-Flag und respektiert das numerische Widget-Limit der Stufe, damit die Oberfläche nicht still wachsen kann.
  • Zitate als Grenzen. Antworten fließen mit Zitaten, die nur in erlaubte Workspaces zeigen - ein Besucher kann nachvollziehen, woher eine Antwort kommt, und die Zitatspur kann nicht aus der Whitelist herauszeigen.

Das Branding - Primärfarbe, Bot-Name, Logos, Position - ist eine Pro-Widget-Konfiguration, die über CSS-Custom-Properties im iframe gerendert wird, sodass eine Beratung den Assistenten als den ihres Kunden präsentieren kann. Community-Stufen-Deployments erhalten sinnvolle Standards, wenn Felder leer sind; vollständige Anpassung und White-Labeling sind Enterprise-Flags.

Die Sicherheitscheckliste, zusammengefasst

Jede Schicht oben existiert, weil ein Widget Software ist, die Sie in die Vertrauensgrenze von jemand anderem ausliefern:

  • Zweistufiger Loader + sandboxed iframe mit opaker Herkunft - kein XSS durch Zeichenketten-Interpolation
  • Serverseitig injizierte Konfiguration - nichts Sicherheitsrelevantes wird vom Client geliefert
  • Serverseitig aufgelöster Model Pin - das antwortende Modell kann vom Browser des Besuchers nicht manipuliert werden
  • Anonyme 256-Bit-Sitzungen mit 24 Stunden Ablauf - keine Umgebungs-Credentials
  • Geschichtete Rate Limits mit 429 + retryAfter - anmutige Degradation unter Missbrauch
  • Dynamisches fail-closed CORS - Origin-Vertrauen an genau einem Punkt entschieden
  • Atomare Workspace-Whitelist - Wissenszugriff ist strukturell, nicht im Prompt erhofft

Vom Admin-Panel zum funktionierenden Snippet dauert es Minuten: Widget erstellen, Workspaces whitelisten, Origins hinzufügen, Script-Tag einfügen. Der vollständige Integrationsleitfaden deckt Branding, das simmetric:*-postMessage-Protokoll und Lead Capture end-to-end ab.

Lies die vollständige Anleitung in der Doku →

Ähnliche Artikel