Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2025-67923 — JetEngine <= 3.7.7 — Nicht authentifiziertes gespeichertes Cross-Site-Scripting über die CCT REST API | Kitploit
Tools/GitHubGitHub/randomrobbiebf/cve-2025-67923
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitAPI-Sicherheit
GitHubrandomrobbiebf/cve-2025-67923

CVE-2025-67923

JetEngine <= 3.7.7 — Nicht authentifiziertes gespeichertes Cross-Site-Scripting über die CCT REST API

Repository anzeigen
19vor 6 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2025-67923 Exploit-Bericht

JetEngine <= 3.7.7 — Nicht authentifiziertes gespeichertes Cross-Site-Scripting über die CCT-REST-API

Datum: 11. März 2026 CVSS-Score: 7.1 (Hoch) CVSS-Vektor: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L Betroffenes Plugin: JetEngine <= 3.7.7 Plugin-Slug: jet-engine Behoben in: 3.7.8 CVE: CVE-2025-67923 CWE: CWE-79 Forscher: Bonds (über Patchstack) Gemeldet: 19. Oktober 2025 Offengelegt: Januar 2026 Getestete WordPress-Version: Aktuellste


Zusammenfassung

CVE-2025-67923 ist eine Schwachstelle für nicht authentifiziertes gespeichertes Cross-Site-Scripting im JetEngine-WordPress-Plugin, die alle Versionen bis einschließlich 3.7.7 betrifft. Ein nicht authentifizierter Angreifer kann über die öffentliche REST-API beliebiges HTML/JavaScript in ein Textfeld eines Custom Content Type (CCT) schreiben. Dieses wird anschließend über eine innerHTML-Senke im JavaScript des Maps-Listing-Widgets unbereinigt in das DOM injiziert, wenn ein Opfer eine Seite besucht, die dieses Widget enthält.

Der Angriff erfordert keine Authentifizierung und keine Berechtigungen. Er erfordert lediglich Folgendes:

  1. Es existiert ein JetEngine-CCT, dessen REST-API-Schreibzugriff auf public gesetzt ist.
  2. Ein Maps-Listing-Widget auf einer beliebigen Frontend-Seite ist so konfiguriert, dass es das Textfeld dieses CCT als Karten-Marker-Beschriftung anzeigt.

✅ SCHWACHSTELLE BESTÄTIGT — Gespeicherte XSS-Payload geschrieben und ausgeführt

Bestätigte Auswirkungen:

  • Beliebiges HTML/JS wird ohne Authentifizierung und ohne Bereinigung in der CCT-Datenbank gespeichert
  • XSS wird bei jedem Besucher ausgelöst, der eine Seite mit dem Maps-Listing-Widget lädt
  • Cookie-Diebstahl, Session-Hijacking, Ernte gespeicherter Anmeldedaten, Übernahme des Admin-Kontos

Details zur Schwachstelle

Technische Zusammenfassung

Die Schwachstelle ist eine Kombination aus zwei unabhängigen Fehlern:

  1. Fehlende Eingabebereinigung (Speicherung): Die Methode sanitize_field_value() des CCT-Item-Handlers besitzt keinen Bereinigungspfad für Felder vom Typ text. Der default:-Fall konvertiert nur Zeitstempel — rohes HTML passiert unverändert und wird in der Datenbank gespeichert.

  2. DOM-basierte XSS-Senke (Rendering): Das Maps-Listing-Widget liest den gespeicherten Feldwert über get_marker_label(), kapselt ihn für das HTML-Attribut data-markers in htmlspecialchars(json_encode(...)), und das JavaScript-Frontend liest das Attribut mit getAttribute() (das HTML-Entitäten dekodiert) und fügt markerData.label anschließend direkt über innerHTML ein — wodurch eingebettetes HTML/JavaScript ausgeführt wird.

Betroffene Komponenten

DateiProblem
includes/modules/custom-content-types/inc/rest-api/public-controller.php:424create_item_permissions_check gibt true zurück, wenn CCT rest_put_access = 'public' — keine Authentifizierung erforderlich
includes/modules/custom-content-types/inc/item-handler.php:489default:-Zweig von sanitize_field_value() — keine HTML-Bereinigung für text-Felder
includes/modules/maps-listings/inc/render.php:233get_marker_label() gibt rohen Metawert ohne esc_html() zurück
includes/modules/maps-listings/inc/render.php:247htmlspecialchars(json_encode($result)) — schützt nur die Attributgrenze, keine innerHTML-Injektion
includes/modules/maps-listings/assets/js/frontend-maps.js:112pinData.content = general.marker.html.replace('_marker_label_', markerData.label) — rohe Beschriftung wird in HTML-String eingefügt
includes/modules/maps-listings/assets/js/public/mapbox-maps.js:175el.innerHTML = data.content — XSS-Ausführungssenke
includes/modules/maps-listings/assets/js/public/leaflet-maps.js:34contentHtml.innerHTML = content — XSS-Ausführungssenke

Exploit-Kette

Schritt 1 — Nicht authentifizierter REST-Schreibzugriff

Der öffentliche REST-Controller des CCT prüft Berechtigungen über check_user_permissions():

// public-controller.php:370-376
public function check_user_permissions( $request, $context ) {
    $content_type = $this->get_content_type_from_request( $request );
    $cap = $content_type->get_arg( $context );

    if ( ! $cap || 'public' === $cap ) {
        return true;  // No authentication required
    } else {
        return current_user_can( $cap );
    }
}

public function create_item_permissions_check( $request ) {
    return $this->check_user_permissions( $request, 'rest_put_access' );
}

Wenn ein CCT mit rest_put_access = 'public' konfiguriert ist (eine unterstützte, dokumentierte Konfiguration für öffentlich zugängliche Formulare), ist der Endpunkt vollständig ohne Authentifizierung erreichbar. Jeder HTTP-Client kann eine POST-Anfrage an /wp-json/jet-cct/{slug} senden.

Schritt 2 — Speicherung ohne Bereinigung

Der REST-Handler ruft $handler->update_item($params) auf, wodurch sanitize_field_value() erreicht wird:

// item-handler.php:489-562
public function sanitize_field_value( $value, $field ) {
    $type = isset( $field['type'] ) ? $field['type'] : false;

    switch ( $type ) {
        case 'repeater':    // sanitizes sub-fields
            // ...
        case 'checkbox':    // handles boolean arrays
        case 'checkbox-raw':
            // ...
        case 'media':
        case 'gallery':     // sanitizes media JSON
            // ...
        case 'wysiwyg':
            $value = jet_engine_sanitize_wysiwyg( $value );  // sanitized
            break;

        default:
            // TEXT TYPE FALLS HERE — only timestamp conversion, NO HTML sanitization
            $value = $this->factory->maybe_to_timestamp( $value, $field );
    }

    return $value;
}

Ein Feld vom Typ text erreicht den default:-Zweig. maybe_to_timestamp() gibt den Wert bei Nicht-Datum-Strings unverändert zurück. Die XSS-Payload `` wird unverändert gespeichert.

Schritt 3 — Beschriftung wird ohne Escaping abgerufen

Wenn das Maps-Listing-Widget rendert, liest get_marker_label() das Feld:

// render.php:479-535
public function get_marker_label( $post = null, $settings = array() ) {

    // ...
    switch ( $label_type ) {
        case 'meta_field':
            $field = $settings['marker_label_field'];
            if ( $field ) {
                $result = jet_engine()->listings->data->get_meta( $field, $post );
                // No esc_html() here — raw value returned
            }
            break;
    }

    return $result;  // Returns ""
}

Der zurückgegebene Wert wird in das Marker-Daten-Array eingefügt:

// render.php:231-237
$result[] = array(
    'id'        => $post_id,
    'latLang'   => $latlang,
    'label'     => $this->get_marker_label( $post, $settings ),  // raw XSS payload
    // ...
);

Schritt 4 — Attributkodierung verhindert innerHTML-XSS nicht

Das Marker-Array wird für ein HTML-Attribut kodiert:

// render.php:247
return htmlspecialchars( json_encode( $result ) );

json_encode serialisiert `` als den String "". htmlspecialchars kodiert anschließend das gesamte JSON als HTML und erzeugt:

[{...,&quot;label&quot;:&quot;&lt;img src=x onerror=alert(1)&gt;&quot;,...}]

Dies wird in das HTML-Attribut data-markers geschrieben. Die Kodierung schützt nur die Attributgrenze. Wenn JavaScript das Attribut liest, dekodiert der Browser die HTML-Entitäten und stellt die ursprünglichen Zeichen wieder her:

// Browser automatically decodes entities when reading via dataset / getAttribute
const markers = JSON.parse(el.dataset.markers);
// markers[0].label === ''

Schritt 5 — innerHTML-Injektion (XSS wird ausgelöst)

In frontend-maps.js wird der rohe Beschriftungs-String direkt in einen HTML-Inhaltsstring eingefügt:

Tool herunterladen