
SureForms <= 2.2.0 - Nicht authentifiziertes gespeichertes Cross-Site Scripting
Eine kritische Stored XSS-Schwachstelle existiert im SureForms-Plugin. Die Schwachstelle beruht auf einer unsicheren clientseitigen Implementierung in entries.js, bei der Benutzereingaben programmatisch decodiert (was die serverseitige Bereinigung rückgängig macht) und dann ohne ordnungsgemäße clientseitige Bereinigung mithilfe von dangerouslySetInnerHTML gerendert werden. Dies ermöglicht es nicht authentifizierten Angreifern, schädliche JavaScript-Payloads über Standardformularfelder einzuschleusen und dabei die standardmäßigen WordPress--Filter zu umgehen.
wp_ksesUm zu überprüfen, ob eine Zielseite SureForms ausführt, überprüfen Sie den Header der Sprachdatei, der normalerweise die Versionsnummer enthält.
Ziel-URL:
http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot
Verifizierungsbefehl:
curl -s "http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot" | grep "Project-Id-Version"
Die Schwachstelle befindet sich in der React-basierten Admin-Oberfläche zum Anzeigen von Formulareinträgen (entries.js).
In der minifizierten entries.js-Datei gibt es eine Hilfsfunktion (im analysierten Build als Xv identifiziert), die HTML-Entities verarbeiten soll.
Code-Logik (Rekonstruiert):
// Funktion Xv: Vorverarbeitung von Feldwerten
var Xv = function(input) {
var value = input.value;
// SCHWACHSTELLENURSACHE:
// Wenn der String HTML-Entities enthält (z. B. <), wird ein textarea erstellt,
// der Inhalt eingefügt und der Wert extrahiert.
// Dadurch werden HTML-Entities effektiv zurück in rohe HTML-Tags decodiert.
// Beispiel: "<img ...>" wird zu ""
if (typeof value === "string" && value.match(/&[a-zA-Z0-9#]+;/)) {
var textarea = document.createElement("textarea");
textarea.innerHTML = value;
// Logik zum Rückgängigmachen der Bereinigung
if (textarea.value.includes("<") || textarea.value.includes(">")) {
value = textarea.value; // Enthält nun ROHES HTML
}
}
return { ...input, value: value };
}
Analyse: Diese Funktion macht die Backend-Sicherheit zunichte. Selbst wenn WordPress <script> korrekt als <script> in der Datenbank speichert, wandelt diese Funktion es sofort wieder in <script> um, nachdem es von der API abgerufen wurde.
Nach der Decodierung werden die Daten an die Rendering-Komponente (als Jv identifiziert) übergeben.
Code-Logik (Rekonstruiert):
// Funktion Jv: Rendern des Feldes
var Jv = function(props) {
var field = props.field;
var val = field.value; // Dieser Wert ist jetzt rohes HTML (nach Decodierung)
// DER AUSLÖSER: Prüfen, ob der String wie HTML aussieht
if (typeof val === "string" && val.match(/<[^>]+>/g)) {
// DIE SENKE: Rendern mit dangerouslySetInnerHTML OHNE clientseitige Bereinigung (z. B. DOMPurify)
return React.createElement("span", {
dangerouslySetInnerHTML: { __html: val }
});
}
// Sicheres Rendern für Nicht-HTML-Text
return React.createElement("span", null, val);
}
Injektion: Ein nicht authentifizierter Angreifer sendet ein Formular auf der Frontend-Seite. Anstatt rohe HTML-Tags zu verwenden (die vom WordPress-Backend entfernt/bereinigt würden), sendet der Angreifer HTML-Entities.
Speicherung: WordPress betrachtet die Eingabe (z. B. <img...) als sicheren Text und speichert sie in der Datenbank.
Ausführung (Die Falle):
Xv-Funktion erkennt die Entities und decodiert <img... zurück zu ` Einträge.Klicken Sie auf den in Schritt 1 eingereichten Eintrag, um die Details anzuzeigen.
Ergebnis: Der Browser führt die JavaScript-Payload (alert('XSS_SUREFORMS')) aus.