Huginn: Szenario-Import führt Skript in der Sitzung des Opfers aus

Die Beschreibung eines importierten Szenarios wird als rohes HTML gerendert, und zwar schon in der Vorschau, bevor der Import bestätigt ist.

Advisory-ID: TP-2026-085
Produkt: Huginn (selbst gehostete Automatisierungsplattform, Ruby on Rails)
Schwachstellentyp: Stored Cross-Site-Scripting (CWE-79)
CVE: nicht zugewiesen
CVSS 3.1: 8.1 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Betroffene Versionen: <= 2026.08.27
Hersteller-Advisory: GHSA-x738-j22q-h2jw
Behoben in: 2026.09.08
Gemeldet: 03. Juni 2026

Zusammenfassung

Huginn wirbt damit, dass Nutzer fertige Automatisierungs-Szenarien als JSON-Datei oder über eine öffentliche URL austauschen. Beim Import zeigt Huginn zuerst eine Vorschau, in der die Beschreibung des Szenarios durch den Markdown-Helfer läuft. Dieser Helfer reicht rohes HTML unverändert durch und markiert das Ergebnis als sicher, sodass ein script-Element im Beschreibungsfeld ausgeführt wird. Das geschieht bereits auf der Vorschauseite, also bevor das Opfer den Import bestätigt, und Huginn sendet keine Content-Security-Policy. Wer einen Administrator dazu bringt, ein präpariertes Szenario anzusehen, führt Skript in dessen angemeldeter Sitzung aus.

Ursache

Der Helfer markdown() ruft Kramdown::Document.new(text, auto_ids: false).to_html.html_safe auf und wendet keinen Filter an (app/helpers/markdown_helper.rb:3-5). Kramdown lässt mit seinen Voreinstellungen parse_block_html und parse_span_html rohes HTML unverändert passieren, und .html_safe schaltet die automatische Maskierung von Rails ab. Die Vorschau reicht parsed_data["description"] direkt an diesen Helfer (app/views/scenario_imports/_step_two.html.erb:32), wobei parsed_data das rohe JSON des Angreifers ist (app/importers/scenario_import.rb:45-47), bezogen aus eingefügtem Text, einer hochgeladenen Datei oder einer abgerufenen URL (:124-128). ScenarioImportsController#create rendert die Vorschau jedes Mal neu, solange import_confirmed? falsch ist, weshalb das Skript vor jeder Bestätigung feuert. Nach dem Import wiederholt sich das auf der Szenario-Seite (app/views/scenarios/show.html.erb:12), und die Anwendung sendet keine Content-Security-Policy.

Proof of Concept

# Szenario-JSON, vom Angreifer unter einer oeffentlichen URL abgelegt
{
  "name": "Nuetzliches Szenario",
  "description": "<script>alert(document.domain)</script>",
  "guid": "...", "agents": []
}

# Opfer: Scenarios -> Import Scenario -> "Public Scenario URL" einfuegen
# Die Vorschau rendert die Beschreibung roh in einem <blockquote>,
# das Skript laeuft, ohne dass "Finish Import" geklickt wurde.

Kramdown maskiert ein alleinstehendes <svg onload=...> als Absatz, ein script-Block und Markdown-Links mit javascript: passieren dagegen unverändert. Das script-Element allein genügt, die Eigenheit mindert die Wirkung also nicht.

Auswirkung

  • Skriptausführung in der angemeldeten Sitzung jedes Nutzers, der ein fremdes Szenario in der Vorschau betrachtet.
  • Rechteausweitung, wenn das Opfer Administrator ist: das Sitzungs-Cookie ist zwar HttpOnly, das CSRF-Token steht aber im DOM, womit das Skript beglaubigte Anfragen stellt und über die Admin-Endpunkte ein neues Administratorkonto anlegt.
  • Auslesen und Verändern aller Agenten des Opfers samt der darin hinterlegten Zugangsdaten zu Fremddiensten.
  • Wiederholte Ausführung bei jedem Öffnen des Szenarios, sobald der Import bestätigt wurde.

Referenzen

Steckt so etwas in Ihrer Software?

Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.