Zurück zum Blog

Folgen und abonnieren

Was ist Style Smuggler (CVE-2026-75650)?

CVE-2026-75650 (StyleSmuggler) ist eine kritische SSTI-Schwachstelle, die auf E-Commerce-Plattformen aktiv ausgenutzt wird. Erfahren Sie, worum es sich handelt und wie Fastly-Kunden geschützt bleiben können.

Matthew Mathur
Matthew MathurStaff Security Researcher, Fastly
Fastly Security Research Team
Fastly Security Research TeamFastly Security Research Team, Fastly

Übersicht

  • Sansec entdeckte die Schwachstelle in Adobe Commerce und Magento und stellte fest, dass sie bereits vor der Veröffentlichung von Patches aktiv ausgenutzt wurde, spätestens seit dem 4. September 2026.

  • Adobe veröffentlichte am 7. September 2026 APSB26-146, um Teile der Schwachstellenkette zu beheben.

  • Fastly hat einen virtuellen Patch für CVE-2026-75650 veröffentlicht. Kunden können ihn aktivieren, um Anfragen zu blockieren, die auf die Schwachstelle abzielen.

Analyse der Schwachstelle

CVE-2026-75650 ist eine ohne Authentifizierung ausnutzbare Schwachstelle vom Typ Server-Side Template Injection (SSTI), die unmittelbar die Ausführung von Code aus der Ferne (Remote Code Execution, RCE) ermöglicht. Die Ausnutzung erfolgt in drei Phasen über vier Anfragen: 

  1. Einschleusen von PHP-Code in Logs 

  2. Einrichten eines Warenkorbs und Einfügen des SSTI-Payloads in dessen Adressangaben 

  3. Auslösen der SSTI und Herbeiführen von RCE über eine E-Mail zu einer fehlgeschlagenen Zahlung

Phase 1: PHP-Code in Logs einschleusen

In der ersten Phase geht es darum, ungefilterten PHP-Code auf dem Datenträger des Zielsystems abzulegen. Eine Methode konnten wir in unseren Testumgebungen nachstellen. Mindestens eine weitere bestätigte Methode wurde bei tatsächlichen Angriffen beobachtet. Wichtig ist, dass es wahrscheinlich noch viele weitere Wege gibt, diese Phase umzusetzen. Bei der von uns nachgestellten Variante wird eine nicht maskierte Fehlermeldung zu einem ungültigen Store-Code protokolliert, wodurch der in die Anfrage eingebettete schädliche PHP-Code erhalten bleibt. Eine Anfrage könnte etwa so aussehen:

POST /graphql HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
Store: <?=eval(base64_decode('{{payload_b64}}'));?>

{"query":"{ storeConfig { store_code } }"}

Der Payload steckt im Store-Header und dürfte bei tatsächlichen Angriffen häufig kodierte Inhalte enthalten, um die Erkennung zu umgehen. Wenn Magento diesen Fehler protokolliert, wird <?= unmaskiert ins Log geschrieben. Das ist für Phase 3 entscheidend. Der konkrete PHP-Code kann je nach Angriff variieren.

Phase 2: SSTI-Payload in Adressangaben einfügen

Mit der zweiten Anfrage wird ein Gast-Warenkorb eingerichtet. Die dritte Anfrage enthält den SSTI-Payload in den Adressangaben des Warenkorbs. Die zweite Anfrage weist keine Besonderheiten auf und wird der Kürze halber nicht dargestellt.

Um den SSTI-Payload zu verstehen, muss man einige Bestandteile der Template-Engine von Magento kennen. Die Template-Engine von Magento ersetzt Variablen mithilfe von „Direktiven“ (z. B. var, block). Jede Direktive wird durch einen eigenen regulären Ausdruck erkannt. Ein „Filter“ verarbeitet die Direktiven in zwei Durchläufen. Im ersten Durchlauf löst ein Filter alle Direktiven auf, die er verarbeiten kann. Im zweiten Durchlauf verarbeitet er „zurückgestellte“ Direktiven, die von einem verschachtelten Filter signiert wurden. Wenn eine Direktive verarbeitet wird, einen übergeordneten Filter hat und ihre Ausgabe mit der Direktive selbst übereinstimmt, wird sie für die Verarbeitung durch den übergeordneten Filter „signiert“ (d. h. *Sig*{{directive}}*Sig*). 

Hier beginnt das Problem. Beim Signieren einer Direktive ersetzt str_replace in der Ausgabe die ursprüngliche Direktive durch die signierte Version. Die Ausgabe enthält jedoch alle zuvor verarbeiteten Direktiven, nicht nur die aktuelle. Sehen wir uns also an, wie Style Smuggler diese Direktiven nutzt.

Style Smuggler verwendet eine E-Mail-Vorlage für fehlgeschlagene Zahlungen, die die Adressfelder mit einem verschachtelten Filter verarbeitet. Der Filter für die Adresse kann block-Direktiven nicht verarbeiten. Deshalb übermitteln wir in den Adressfeldern der dritten Anfrage Folgendes:

Straße: {{if postcode}}{{var postcode}}{{/if}}{{/var}}{{if postcode}}{{var postcode}}{{/if}}{{if city}}{{block class=Magento\\Email\\Block\\Adminhtml\\Template\\Preview}}{{/if}}

Postleitzahl: {{var postcode}}

Wenn die Postleitzahl vom Adressfilter verarbeitet wird, stimmt sie mit dem ursprünglichen Inhalt der Direktive überein und wird signiert. Da str_replace jedoch auf die gesamte Ausgabe angewendet wird, werden die Signaturen auch dort platziert, wo wir {{var postcode}} im Straßenteil der Adresse eingefügt haben. Aufgrund einer Unklarheit im regulären Ausdruck zur Erkennung von Direktiven wird die endgültige „verarbeitete“ Adresse, die {{var postcode}}{{var postcode}}Sig{{blockclass=Magento\\Email\\Block\\Adminhtml\\Template\\Preview}}Sig<br /> enthält, an den E-Mail-Filter weitergegeben. Der E-Mail-Filter löst dann die signierte Block-Direktive auf, die wir in den Straßenteil der Adresse eingeschleust haben. Vor Adobes Patch instanziierten block-Direktiven die angegebene Klasse unabhängig davon, ob es sich tatsächlich um eine „Block“-Klasse handelte. Damit können wir nun beliebige Objekte erzeugen.

Phase 3: Aus SSTI wird RCE

Zu diesem Zeitpunkt haben wir 1) PHP-Code in einer Log-Datei und 2) eine SSTI, mit der sich beliebige Klassen instanziieren lassen. Um beides zu verbinden, müssen wir eine Klasse instanziieren, die den in Phase 1 in der Logdatei abgelegten Code ausführen kann. An dieser Stelle wird das eingefügte Magento\Email\Block\Adminhtml\Template\Preview wichtig. Es handelt sich um eine Klasse, die Vorlagen anhand der Query-Parameter „text“, „styles“ und „type“ rendern kann. Daher senden wir eine Anfrage mit den folgenden Query-Parametern (URL-kodiert):

Text: {{block class=Magento\Backend\Block\Widget\Grid\ColumnSet rowUrl=$this.template_styles cache_key=y}}

styles (als JSON-kodierter Query-Parameter formatiert):

 {
    "first": "../var/log/system.log",
    "generatorClass": "Aws\\S3\\S3Client",
    "region": "us-east-1",
    "version": "latest",
    "s3_us_east_1_regional_endpoint": "regional",
    "with_resolved": [
      {
        "instance": "Magento\\Setup\\Module\\Di\\Code\\Scanner\\ArrayScanner"
      },
      "collectEntities"
    ],
    "path": "dummy"
  }

Typ: 2

In dieser Anfrage verwenden wir gleichzeitig auch die GraphQL-Mutation handlePayflowProResponse, um die Verarbeitung der Vorlage für fehlgeschlagene Zahlungen zu starten. Dadurch wird die folgende Ereigniskette ausgelöst:

  1. Unser zuvor eingefügter „Preview“-Block wird während der Verarbeitung der E-Mail-Vorlage verarbeitet, wodurch der Payload unseres anderen Blocks „ColumnSet“ aus dem Query-Parameter „text“ erstellt wird.

  2. ColumnSet erhält das Array „styles“ als Argumente und ruft eine „UrlGeneratorFactory“ mit der von uns angegebenen generatorClass „Aws\S3\S3Client“ auf.

  3. Beim Instanziieren von S3Client wird der von uns angegebene „Magento\Setup\Module\Di\Code\Scanner\ArrayScanner“ erzeugt. Dieser ruft die Methode „collectEntities“ auf.

  4. collectEntities führt „include“ für den Wert „first“ aus, den wir im Array „styles“ angegeben haben. Dieser Wert verweist auf unsere mit PHP-Code präparierte Logdatei. 

  5. Der Code, den wir in der Log-Datei platziert haben, wird während des Includes ausgeführt (aufgrund des nicht maskierten <?=), und jetzt haben wir RCE. 

Daher stammt der Name „Style Smuggler“. Über den von der Klasse Preview verwendeten Parameter „styles“ werden die zusätzlichen Gadget-Informationen eingeschleust, die für die Codeausführung nötig sind. Wichtig ist außerdem, dass es in der Magento Codebasis möglicherweise weitere geeignete Gadget-Ketten gibt. Wir haben bereits mindestens eine Variante identifiziert, die einen anderen Payload als den „Preview“-Block verwendet.

Nuclei-Template

Um der Community dabei zu helfen, auf Style Smuggler anfällige Instanzen zu testen, haben wir ein Nuclei Template für CVE-2026-75650 beim offiziellen Repository nuclei-templates eingereicht. Wir haben das Template selbst entwickelt, mit der Einreichung aber gewartet, bis Graycore eine Analyse der Schwachstelle veröffentlicht hatte, die Sansec bestätigte. So wollten wir vermeiden, zuvor zurückgehaltene Informationen über die Schwachstelle offenzulegen. Wir haben das Template lokal mit Magento v2.4.9 und v2.4.7-p2 getestet, um sicherzustellen, dass es mit mehreren Versionen zuverlässig funktioniert.

Virtueller Patch für CVE-2026-75650

Fastly hat einen virtuellen Patch für CVE-2026-75650 veröffentlicht, der jede Phase des Style-Smuggler-Exploits abdeckt. Dies bietet Defense-in-Depth gegen Varianten innerhalb eines Teils der Kette und verschafft Betreibern Zeit, ihre Systeme zu patchen. Dieser virtuelle Patch ist unempfindlich gegenüber False Positives im normalen Betrieb, einschließlich Aktualisierungen von Admin-Vorlagen, und steht in keinem Zusammenhang mit den in anderen Artikeln beschriebenen False Positives.

Sind Sie bereit, loszulegen?

Treten Sie noch heute mit uns in Kontakt