Warum KI-generierter WordPress-Plugin-Code unsicher ist
Die Verwendung von Large Language Models (LLMs) wie GPT-4, Claude 3.5 Sonnet oder Gemini Pro zum Schreiben von WordPress-Plugin-Code ist für Entwickler und Website-Betreiber gleichermaßen zur Routine geworden. Das Versprechen ist verlockend: Beschreiben Sie die gewünschte Funktionalität in einfachem Deutsch, und die KI generiert in Sekundenschnelle eine gebrauchsfertige PHP-Datei.
Das Problem ist jedoch, dass Sprachmodelle zwar hervorragend in Syntax und Struktur sind, ihnen aber der betriebliche Kontext und ein echtes Verständnis der Sicherheitsprinzipien innerhalb des WordPress-Ökosystems fehlen. Sie wurden mit riesigen Mengen an öffentlichem Code trainiert und erben daher Millionen von veralteten, unsicheren und schlecht geschriebenen Plugins, die in den letzten zwei Jahrzehnten veröffentlicht wurden. Infolgedessen gibt die KI oft Code aus, der syntaktisch einwandfrei und funktional ist, unter der Haube jedoch kritische Sicherheitslücken aufweist.
Als WordPress-Entwickler müssen wir gegenüber jedem von einer KI geschriebenen Code eine strikte “Zero Trust”-Haltung einnehmen. Dieser Leitfaden beschreibt die fünf häufigsten Sicherheitsfehler-Muster, die wir bei Audits von KI-generiertem Plugin-Code beobachten, und veranschaulicht sie anhand von anfälligen PHP-Snippets neben sicheren, produktionsreifen Refactorings, die den WordPress-Codierungsstandards (WPCS) entsprechen.
1. Missbrauch von is_admin() zur Zugriffskontrolle
Der vielleicht häufigste logische Fehler, den KI bei dem Versuch macht, einen Endpunkt zu sichern, ist der Rückgriff auf die Funktion is_admin(), um den Zugriff auf Administratoren zu beschränken.
Warum is_admin() keine Admin-Rechte prüft
Trotz ihres Namens überprüft is_admin() nicht, ob der aktuell angemeldete Benutzer ein Administrator ist. Sie prüft lediglich, ob die aktuelle Anfrage für eine Administrationsseite bestimmt ist (z. B. jede URL, die mit /wp-admin/ beginnt).
Jede AJAX-Anfrage, die an /wp-admin/admin-ajax.php gesendet wird, unabhängig davon, ob sie von einem Administrator, einem angemeldeten Abonnenten mit minimalen Rechten oder einem nicht authentifizierten anonymen Besucher initiiert wurde, führt dazu, dass is_admin() den Wert true zurückgibt.
is_admin() als einzige Prüfung beim Speichern
// Ein von der KI generierter Hook zum Speichern von Plugin-Einstellungen
add_action( 'admin_init', 'ai_save_plugin_settings' );
function ai_save_plugin_settings() {
// Die KI nimmt fälschlicherweise an, dass dies den Zugriff auf Administratoren beschränkt
if ( is_admin() ) {
if ( isset( $_POST['my_plugin_option'] ) ) {
update_option( 'my_plugin_option', $_POST['my_plugin_option'] );
}
}
}Berechtigung mit current_user_can() prüfen
Um die tatsächlichen Berechtigungen des angemeldeten Benutzers zu überprüfen, müssen Sie die Funktion current_user_can() verwenden und eine spezifische Benutzerberechtigung anstelle eines Rollennamens übergeben, z. B. manage_options.
add_action( 'admin_init', 'secure_save_plugin_settings' );
function secure_save_plugin_settings() {
// 1. Überprüfen Sie die tatsächlichen Fähigkeiten des aktuellen Benutzers
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'Sie haben keine Berechtigung, diese Aktion auszuführen.', 'secure-plugin' ) );
}
if ( isset( $_POST['my_plugin_option'] ) ) {
// Eingabebereinigung anwenden (siehe Abschnitt 4)
$sanitized_value = sanitize_text_field( wp_unslash( $_POST['my_plugin_option'] ) );
update_option( 'my_plugin_option', $sanitized_value );
}
}2. WordPress-Nonce prüfen und CSRF verhindern
Cross-Site Request Forgery (CSRF)-Angriffe verleiten den Browser eines authentifizierten Benutzers (z. B. eines Administrators) dazu, unerwünschte Aktionen auf einer Website auszuführen, auf der er gerade angemeldet ist. WordPress verwendet kryptografische Token namens Nonces, um vor CSRF zu schützen.
KI-Generatoren lassen die Erstellung und Überprüfung von Nonces in Admin-Formularen, AJAX-Handlern und benutzerdefinierten REST-API-Endpunkten häufig weg. Dies geschieht, weil die Implementierung von Nonces die Koordinierung der Frontend-Rendering-Ebene (das HTML-Formular mit dem Nonce-Feld) mit dem Backend-Verarbeitungs-Controller erfordert, was für LLMs über verschiedene Codegenerierungen hinweg schwer abzustimmen ist.
AJAX-Handler ohne Nonce-Prüfung
// KI-generierte AJAX-Endpunktregistrierung
add_action( 'wp_ajax_ai_delete_post', 'ai_delete_post_handler' );
function ai_delete_post_handler() {
// KI prüft Berechtigungen, ignoriert aber CSRF vollständig (keine Nonce-Prüfung)
if ( ! current_user_can( 'delete_posts' ) ) {
wp_send_json_error( 'Nicht autorisiert.' );
}
$post_id = intval( $_POST['post_id'] );
wp_delete_post( $post_id );
wp_send_json_success( 'Beitrag gelöscht.' );
}Nonce mit check_ajax_referer() prüfen
Das Ausgabeformular muss ein Nonce-Feld mit wp_nonce_field() ausgeben, und der empfangende PHP-Controller muss das Token mit check_ajax_referer() oder wp_verify_nonce() überprüfen.
// Im Formular-Rendering-File oder Javascript-Payload:
// wp_nonce_field( 'delete_post_action', 'my_nonce_field' );
// Registrierung des gesicherten AJAX-Handlers
add_action( 'wp_ajax_secure_delete_post', 'secure_delete_post_handler' );
function secure_delete_post_handler() {
// 1. CSRF-Token frühzeitig verifizieren
check_ajax_referer( 'delete_post_action', 'my_nonce_field' );
// 2. Benutzerberechtigungen verifizieren
if ( ! current_user_can( 'delete_posts' ) ) {
wp_send_json_error( 'Nicht autorisiert.' );
}
// 3. Eingabevariablen validieren und typisieren
if ( ! isset( $_POST['post_id'] ) ) {
wp_send_json_error( 'Fehlende Beitrags-ID.' );
}
$post_id = absint( $_POST['post_id'] );
if ( wp_delete_post( $post_id ) ) {
wp_send_json_success( 'Beitrag erfolgreich gelöscht.' );
} else {
wp_send_json_error( 'Fehler beim Löschen des Beitrags.' );
}
}Wovor eine WordPress-Nonce nicht schützt
Eine Nonce belegt nur, dass eine Anfrage aus einem Formular oder Link stammt, den WordPress für diesen Benutzer ausgegeben hat. Das Nonce-Kapitel der WordPress-Sicherheits-APIs hält fest, dass Nonces nie für Authentifizierung, Autorisierung oder Zugriffskontrolle herangezogen werden dürfen, deshalb bleibt die Capability-Prüfung daneben Pflicht. Für das Review zählen drei Eigenschaften. Eine Nonce wird pro Benutzer und Sitzung erzeugt, ein aus einem Konto kopiertes Token scheitert also in einem anderen. Die Standardlebensdauer beträgt 24 Stunden, aufgeteilt in zwei Ticks, und WordPress akzeptiert den aktuellen und den vorherigen Tick, ein Token gilt also zwischen 12 und 24 Stunden. Außerdem ist eine Nonce nicht einmalig: Derselbe Wert lässt sich innerhalb dieses Fensters erneut senden, gegen Replay hilft sie daher nicht. Ein generierter Handler, der eine gültige Nonce als Identitätsnachweis behandelt, hat zwar den CSRF-Schutz, aber weiterhin keine Zugriffskontrolle.
3. SQL-Injection-Schwachstellen in $wpdb-Abfragen
Wenn ein Plugin direkt mit der Datenbank interagiert, anstatt den nativen WP_Query-Wrapper zu verwenden, nutzt es das globale Objekt $wpdb. Leider erstellen LLMs häufig rohe SQL-Zeichenfolgen unter direkter Verkettung von benutzerdefinierten Variablen ($_POST, $_GET), anstatt die Abfrage zu parametrisieren.
Warum verkettetes SQL gefährlich ist
Das direkte Verketten von rohen Variablen in Datenbankabfragen ermöglicht es einem Angreifer, die Abfragestruktur zu manipulieren. Dies kann zu unbefugtem Datenabruf (wie gehashten Benutzerkennwörtern), Datenbanklöschungen oder der Eskalation von Administratorrechten führen.
SQL-Abfrage mit verketteter Variable
// Von KI generierte Benutzersuchfunktion
function ai_find_users_by_city( $city_name ) {
global $wpdb;
// Kritischer Fehler: direkte Verkettung der Abfragevariablen
$query = "SELECT * FROM {$wpdb->prefix}custom_users WHERE city = '" . $city_name . "'";
return $wpdb->get_results( $query );
}Abfragen mit $wpdb->prepare() absichern
Es sollten niemals rohe Variablen direkt in SQL-Zeichenfolgen geschrieben werden. Verwenden Sie stattdessen die Methode $wpdb->prepare(), die als parametrisierte Abfrage-Engine fungiert und Werte unter Verwendung von Formatbezeichnern (%s für Zeichenfolgen, %d für Ganzzahlen, %f für Fließkommazahlen) typisiert und maskiert.
function secure_find_users_by_city( $city_name ) {
global $wpdb;
// 1. Verwenden Sie prepare() mit Formatbezeichnern
$query = $wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}custom_users WHERE city = %s",
$city_name
);
return $wpdb->get_results( $query );
}Hinweis: Wenn die Variable $city_name direkt aus einer Benutzereingabe stammt, muss sie vor der Datenbankverarbeitung dennoch mit sanitize_text_field() bereinigt werden.
4. XSS in WordPress-Plugins durch Escaping verhindern
Cross-Site Scripting (XSS) gehört zu den häufigsten Schwachstellen in WordPress-Plugins. Es ermöglicht das Speichern oder dynamische Spiegeln von böswilligem JavaScript-Code in der Datenbank, der dann im Browser ahnungsloser Besucher ausgeführt wird.
KI-Modelle verwechseln häufig Bereinigung (Bereinigen von Daten beim Empfang) mit Escaping (Sichern von Daten bei der Ausgabe). Selbst wenn die KI Eingaben bereinigt, zeigt sie Variablen in Vorlagen oft an, ohne sie vorher zu maskieren, was die Website für Stored XSS öffnet.
Ausgabe ohne Escaping
// Von der KI geschriebene Feedback-Anzeigeschleife
function ai_display_user_feedback() {
$feedbacks = get_option( 'ai_user_feedback_list', [] );
echo '<div class="feedback-list">';
foreach ( $feedbacks as $feedback ) {
// Kritischer Fehler: Rohausgabe ohne Escaping
echo '<p class="feedback-item">' . $feedback['user_comment'] . '</p>';
}
echo '</div>';
}Ausgabe mit esc_html() maskieren
Befolgen Sie die grundlegende WordPress-Regel: Sanitize Early, Escape Late (Eingabevariablen sofort bereinigen; Ausgabe unmittelbar vor der Ausgabe an den Browser maskieren).
Wählen Sie die richtige Escaping-Funktion für den Kontext:
esc_html(), für Standard-Textknoten innerhalb von HTML-Elementen.esc_attr(), für die Ausgabe innerhalb von HTML-Attributwerten.esc_url(), für die Ausgabe von Links.wp_kses(), wenn Sie bestimmte, sichere HTML-Tags zulassen müssen (wie strong, anchors).
function secure_display_user_feedback() {
$feedbacks = get_option( 'secure_user_feedback_list', [] );
echo '<div class="feedback-list">';
foreach ( $feedbacks as $feedback ) {
$comment = isset( $feedback['user_comment'] ) ? $feedback['user_comment'] : '';
// 1. Ausgabe kontextabhängig unmittelbar vor dem Rendern maskieren
echo '<p class="feedback-item">';
echo esc_html( $comment );
echo '</p>';
}
echo '</div>';
}5. Sicherer Datei-Upload in WordPress mit wp_handle_upload
Benutzern das Hochladen von Dateien zu erlauben (z. B. Kontaktformulare mit Anhängen oder Avatar-Uploads), gehört zu den risikoreichsten Operationen auf einer Website. Ein Fehler an dieser Stelle ermöglicht es Angreifern, eine .php-Datei hochzuladen, was zu Remote Code Execution (RCE) und einer vollständigen Serverkompromittierung führt.
KI-generierte Datei-Handler verlassen sich häufig auf native PHP-Befehle wie move_uploaded_file() in Kombination mit schwachen Dateierweiterungsprüfungen (wie einfachem String-Matching), die für Angreifer leicht zu umgehen sind (z. B. das Hochladen von Dateien mit dem Namen malicious.php.jpg oder die Verwendung alternativer Erweiterungen wie .phtml).
Upload mit move_uploaded_file() und Endungsprüfung
// Von KI geschriebener Upload-Handler
function ai_handle_avatar_upload() {
if ( isset( $_FILES['avatar'] ) ) {
$file_name = $_FILES['avatar']['name'];
$ext = pathinfo( $file_name, PATHINFO_EXTENSION );
// KI nimmt an, dass diese Erweiterungsprüfung sicher ist
if ( in_array( $ext, ['jpg', 'jpeg', 'png'] ) ) {
$target = wp_upload_dir()['path'] . '/' . $file_name;
move_uploaded_file( $_FILES['avatar']['tmp_name'], $target );
}
}
}Datei-Upload mit wp_handle_upload() und MIME-Prüfung
Verwenden Sie niemals natives PHP-move_uploaded_file() innerhalb von WordPress. Verwenden Sie stattdessen die Core-Funktion wp_handle_upload(). Sie führt eine robuste MIME-Typ-Prüfung durch (überprüft die tatsächliche Dateisignatur, nicht nur den Namen), validiert den Upload-Status und integriert sich in das WordPress-Berechtigungssystem.
function secure_handle_avatar_upload() {
// 1. Validieren Sie das CSRF-Token
if ( ! isset( $_POST['avatar_upload_nonce'] ) || ! wp_verify_nonce( $_POST['avatar_upload_nonce'], 'upload_avatar_action' ) ) {
wp_die( esc_html__( 'Ungültiges Sicherheits-Token.', 'secure-plugin' ) );
}
// 2. Capability-Prüfungen verifizieren
if ( ! current_user_can( 'upload_files' ) ) {
wp_die( esc_html__( 'Sie haben keine Berechtigung, Dateien hochzuladen.', 'secure-plugin' ) );
}
if ( isset( $_FILES['avatar'] ) ) {
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
// 3. Erlaubte MIME-Typen erzwingen
$allowed_mimes = [
'jpg|jpeg' => 'image/jpeg',
'png' => 'image/png'
];
$upload_overrides = [
'test_form' => false,
'mimes' => $allowed_mimes
];
// 4. Upload-Verarbeitung an Core-Funktion delegieren
$movefile = wp_handle_upload( $_FILES['avatar'], $upload_overrides );
if ( $movefile && ! isset( $movefile['error'] ) ) {
$avatar_url = $movefile['url'];
update_user_meta( get_current_user_id(), 'user_avatar', $avatar_url );
} else {
// Fehler sicher protokollieren
error_log( 'Fehler beim Hochladen der Datei: ' . $movefile['error'] );
}
}
}6. Erfundene WordPress-Funktionen und gefälschte Composer-Pakete
Eine Fehlerklasse, die ausschließlich bei generativen Modellen auftritt, ist das selbstbewusste Erfinden von Code, den es gar nicht gibt. Da ein LLM plausible Token vorhersagt, anstatt die tatsächliche WordPress-Referenz nachzuschlagen, ruft es bereitwillig Funktionen auf, die nie Teil des Cores waren, etwa wp_verify_admin(), get_current_user_role() oder sanitize_all_input(). Diese Namen wirken glaubwürdig, weil sie den WordPress-Namenskonventionen folgen, und ein Fatal Error zur Laufzeit ist oft das erste Anzeichen für ein Problem. Noch schlimmer: Ein Entwickler unter Zeitdruck “behebt” den Fatal Error, indem er einen eigenen dünnen Wrapper um den halluzinierten Namen schreibt und damit genau die Bereinigungs- oder Berechtigungslücke wieder einführt, die die erfundene Funktion vorgab zu schließen.
Dasselbe Muster betrifft Abhängigkeiten von Drittanbietern. Wenn die KI eine composer.json gerüstet oder require-Zeilen vorschlägt, kann sie auf Pakete verweisen, die auf Packagist nicht existieren, oder, noch gefährlicher, auf solche, deren Name sich nur um ein Zeichen von einer legitimen Bibliothek unterscheidet. Angreifer nutzen dieses “Slopsquatting” aus, indem sie die halluzinierten Paketnamen vorab registrieren, sodass ein ungeprüftes composer install Schadcode direkt in das Plugin zieht.
Zwei konkrete Prüfungen schließen diese Lücke. Erstens: Gleichen Sie jede unbekannte Funktion mit der offiziellen WordPress-Code-Referenz unter developer.wordpress.org ab, bevor Sie ihr vertrauen; existiert kein Eintrag, behandeln Sie den Aufruf als frei erfunden. Zweitens: Pinnen und prüfen Sie jede Abhängigkeit, verifizieren Sie, dass das Paket genau so existiert, vom erwarteten Maintainer stammt und auf eine geprüfte Version festgelegt ist statt auf eine offene Versionsspanne.
// Halluziniert: eine solche Core-Funktion existiert nicht
if ( wp_current_user_is_admin() ) { /* ... */ }
// Echte WordPress-API
if ( current_user_can( 'manage_options' ) ) { /* ... */ }wp plugin verify-checksums vergleicht Plugin-Dateien mit den auf WordPress.org veröffentlichten Prüfsummen (WP-CLI-Dokumentation) und hilft daher nur bei Plugins aus dem Verzeichnis, nicht bei einem Plugin, das die KI geschrieben hat. Für Composer-Abhängigkeiten ist eine festgeschriebene und im Diff geprüfte composer.lock die Kontrolle, und composer why <paket> zeigt, welche Anforderung ein unerwartetes Paket hineingezogen hat.
7. Direkten Aufruf von Plugin-PHP-Dateien blockieren
Jede PHP-Datei eines Plugins oder Themes sollte die Ausführung verweigern, wenn WordPress nicht geladen wurde. Das Plugin-Handbuch empfiehlt dafür eine Prüfung der Konstante ABSPATH am Dateianfang. Generierter Code lässt diese Zeile oft weg, besonders in Hilfsdateien, die das Modell der Lesbarkeit halber ausgelagert hat.
Hilfsdatei ohne ABSPATH-Prüfung
<?php
function fjord_get_export_rows() {
global $wpdb;
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}fjord_records" );
}Ein direkter Aufruf von /wp-content/plugins/fjord-exporter/helpers.php kann die Datei außerhalb von WordPress ausführen und je nach Serverkonfiguration die Anmeldung komplett umgehen.
ABSPATH-Prüfung für Plugin-PHP-Dateien
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}Im Review gilt: Jede .php-Datei im Plugin-Verzeichnis braucht diese Zeilen, auch uninstall.php und kopierte Bibliotheksdateien. Verdächtig sind außerdem generierte “API”-Dateien, die mit require 'wp-load.php'; WordPress selbst laden und danach keine Authentifizierung prüfen.
8. REST-API-Routen ohne permission_callback
Generierte Plugins stellen Daten häufig über register_rest_route() statt über admin-ajax.php bereit. Die Zugriffsentscheidung einer REST-Route steckt in einem einzigen Argument, permission_callback, und Modelle machen es auf zwei Arten falsch: Sie lassen es weg, oder sie setzen es auf __return_true, damit ein 401-Fehler im Test verschwindet.
Das REST-API-Handbuch behandelt beide Fälle. Seit WordPress 5.5 löst eine Route ohne permission_callback einen _doing_it_wrong-Hinweis mit dem Namen der Route aus, ein fehlender Callback steht also im Debug-Log jeder Website mit aktivem WP_DEBUG. __return_true ist der dokumentierte Wert für Endpunkte, die öffentlich sein sollen. Dafür erscheint kein Hinweis, eine versehentlich öffentliche Schreibroute fällt also nicht auf.
Schreibroute, die jeder aufrufen kann
register_rest_route( 'fjord/v1', '/settings', array(
'methods' => 'POST',
'callback' => 'fjord_update_settings',
'permission_callback' => '__return_true',
) );Schreibroute mit Capability-Prüfung und validierten Argumenten
register_rest_route( 'fjord/v1', '/settings', array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => 'fjord_update_settings',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
'args' => array(
'label' => array(
'type' => 'string',
'required' => true,
'validate_callback' => function ( $value ) {
return is_string( $value ) && strlen( $value ) <= 100;
},
'sanitize_callback' => 'sanitize_text_field',
),
),
) );Pro Argument gibt validate_callback true oder false zurück, und der REST-Server weist ungültige Eingaben mit einer für den Client lesbaren Fehlermeldung ab, während sanitize_callback den Wert bereinigt, bevor er Ihren Callback erreicht. Listen Sie im Review jeden Aufruf von register_rest_route() auf und lesen Sie zuerst dessen permission_callback: Ein __return_true auf einer Route, die mehr als GET annimmt, braucht eine schriftliche Begründung. Für Cookie-authentifizierte Anfragen aus dem Browser ergänzt das Kapitel zur Authentifizierung eine Regel: Ohne wp_rest-Nonce im Header X-WP-Nonce setzt die API den aktuellen Benutzer auf 0. Ein Frontend-Skript, das nur deshalb “funktioniert”, weil es die Nonce weglässt, ruft die Route in Wahrheit als abgemeldeter Besucher auf.
KI-generierten Plugin-Code für WordPress auditieren
Um von KI generierten Code sicher bereitzustellen, muss Ihr Engineering-Team einen systematischen Überprüfungsprozess einrichten. Implementieren Sie diese drei Schritte, bevor Sie generierte Assets in die Produktion überführen:
Schritt 1: Statische Analyse automatisieren (PHPCS)
Konfigurieren Sie die WordPress Coding Standards (WPCS) für das PHP_CodeSniffer-Tool. Es scannt Dateien und kennzeichnet fehlende Bereinigungen, weggelassene Nonces und unescapte Variablen automatisch.
# Scannen einer generierten Plugin-Datei mit WordPress-Standards
vendor/bin/phpcs --standard=WordPress-Extra path/to/generated-plugin.phpWelche WPCS-Sniffs die Sicherheitsmuster finden
WordPress Coding Standards 3.x lässt sich nur über Composer installieren und braucht PHP 7.2 oder neuer; das WordPressCS-Repository hat im Juli 2026 die Version 3.4.1 veröffentlicht.
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev wp-coding-standards/wpcs:"^3.0"WordPress-Extra enthält WordPress-Core plus empfohlene Praktiken. Die Sicherheits-Sniffs liegen in zwei Gruppen. WordPress.Security.NonceVerification meldet Zugriffe auf $_POST und $_GET ohne vorherige Nonce-Prüfung, WordPress.Security.ValidatedSanitizedInput meldet Superglobals ohne isset(), wp_unslash() und Bereinigungsfunktion, WordPress.Security.EscapeOutput meldet unmaskierte Ausgaben, und WordPress.Security.SafeRedirect meldet wp_redirect() an Stellen für eine sichere Weiterleitung. Auf der Datenbankseite melden WordPress.DB.PreparedSQL und WordPress.DB.PreparedSQLPlaceholders interpoliertes SQL und Platzhalterfehler, und WordPress.DB.DirectDatabaseQuery markiert direkte Abfragen zur Prüfung. So laufen nur die Sicherheits-Sniffs gegen ein generiertes Plugin:
vendor/bin/phpcs --standard=WordPress --sniffs=WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput,WordPress.Security.EscapeOutput,WordPress.DB.PreparedSQL path/to/generated-plugin/Kein Sniff erkennt, ob ein Handler die richtige Capability prüft, die Kontrolle von current_user_can() in Schritt 2 bleibt also Handarbeit.
Schritt 2: Manuellen Code-Review durchführen
Überprüfen Sie jeden Handler, der HTTP-Abfragen, Datenbanktransaktionen, AJAX-Aufrufe oder REST-API-Verbindungen ausführt, anhand des folgenden Flussdiagramms:
graph TD
A["KI-geschriebenen Plugin-Code empfangen"] --> B{"Akzeptiert er Benutzereingaben?"}
B -- Ja --> C["Auf Nonce & Capability-Prüfungen prüfen"]
B -- Nein --> D{"Modifiziert er die Datenbank?"}
C --> C1["check_ajax_referer() / CSRF-Validierung implementieren"]
C --> C2["current_user_can() Berechtigungsprüfung implementieren"]
C1 --> D
C2 --> D
D -- Ja --> E["Prüfen auf $wpdb->prepare() Nutzung"]
D -- Nein --> F{"Gibt er an den Browser aus?"}
E --> E1["Parametrisierte SQL-Variablen implementieren"]
E1 --> F
F -- Ja --> G["esc_html(), esc_attr(), oder esc_url() verifizieren"]
F -- Nein --> H["Mit Integrationstests fortfahren"]
G --> G1["Kontextbezogenes Ausgabe-Escaping implementieren"]
G1 --> HSchritt 3: Tests mit geringen Rechten ausführen
Überprüfen Sie die Zugriffsgrenzen des Codes. Melden Sie sich als Benutzer mit der Rolle “Abonnent” an und lösen Sie die REST- oder AJAX-Aktionen des Plugins direkt über curl oder Postman aus. Wenn der Server Änderungen ausführt oder Datenbankdaten preisgibt, fehlen die Berechtigungsebenen.
Übernimmt ein KI-Agent einen Teil dieser Prüfung, zeigt das Paket security-audit von Cloudflare, unter MIT-Lizenz veröffentlicht (README im Oktober 2026 gelesen), wie seine Befunde belastbar bleiben. Jeder Verdachtsfall geht an einen neuen Prüf-Agenten, der ihn zu widerlegen versucht; der Agent, der einen Befund prüft, ist also nie der, der ihn gefunden hat. Ein Hinweis, der sich nicht belegen lässt, bleibt als needs_validation markiert, ohne Schweregrad, und erscheint nicht als Schwachstelle im Bericht. Fehlt eine zweite Schutzschicht, während die erste den Angriff bereits blockiert, gilt das als Härtungshinweis. Cloudflare ergänzt, dass in den eigenen Testläufen ein einzelner Durchlauf etwa die Hälfte der Schwachstellen fand, die wiederholte Durchläufe insgesamt fanden. Bei einem generierten Plugin ist ein KI-Durchlauf daher ein Anfang; PHPCS, die Checkliste für jeden Handler und die Tests mit geringen Rechten bleiben nötig.
Aktualisierung vom . Zwei weitere Prüfungen gehören auf diese Liste, und WooCommerce-Erweiterungen brauchen beide. Die erste betrifft die Ausgabe eines Beitrags oder Produkts anhand seiner ID. Jede Funktion, die eine Beitrags- oder Produkt-ID aus einer Anfrage oder einem Shortcode-Attribut übernimmt, muss vor der Ausgabe Status, Sichtbarkeit und Passwort prüfen, sonst zeigt ein Entwurf, ein privates oder ein passwortgeschütztes Produkt Name, Preis oder Bild über einen Shortcode, eine Schnellansicht oder eine Vergleichsliste. Durchsuchen Sie den PHP-Code nach get_post(, wc_get_product( und shortcode_atts(, verfolgen Sie jede ID bis zur Ausgabe und suchen Sie dort eine Prüfung von Status und Sichtbarkeit (etwa current_user_can( 'read_post', $id ) oder $product->is_visible()) sowie post_password_required(). Die zweite Prüfung betrifft das JavaScript. WooCommerce löst seine Varianten- und Warenkorb-Ereignisse über jQuery aus, daher reagiert ein nativer addEventListener auf Namen wie found_variation oder updated_cart_totals nie. Durchsuchen Sie das JavaScript nach diesen Namen und prüfen Sie, ob die Listener über jQuery laufen, etwa jQuery( document.body ).on( 'updated_cart_totals', ... ).
Plugin Check auf ein KI-generiertes Plugin anwenden
Plugin Check ist das Werkzeug, mit dem WordPress.org Plugins gegen die Anforderungen des Verzeichnisses prüft, und es nützt ebenso bei einem privaten Plugin, das nie eingereicht wird. Version 2.1.0 erschien im August 2026. Es arbeitet in zwei Modi: statische Prüfungen, die den Code lesen, teils über PHP_CodeSniffer-Sniffs, teils über eigene Regeln, und Laufzeitprüfungen, die das Plugin aktivieren und Teile davon ausführen. Das Projekt rät davon ab, es auf einer Produktionsseite zu betreiben, installieren Sie es also auf Staging.
wp plugin check fjord-exporter
wp plugin check fjord-exporter --categories=security --format=csv --fields=code,type,severity,message
wp plugin check fjord-exporter --require=./wp-content/plugins/plugin-check/cli.phpÜber WP-CLI laufen standardmäßig nur die statischen Prüfungen; der dritte Befehl lädt cli.php, damit auch die Laufzeitprüfungen laufen. Die Liste der Prüfungen ordnet fünf davon der Kategorie security zu, und sie decken sich mit den Mustern in diesem Leitfaden:
| Prüfung | Was sie meldet | Muster in diesem Leitfaden |
|---|---|---|
direct_file_access | PHP-Dateien ohne ABSPATH-Prüfung | direkter Dateiaufruf |
late_escaping | Ausgabe an den Browser ohne Escaping | XSS |
direct_db | unmaskierte Werte in direkten Datenbankabfragen | SQL-Injection |
direct_db_queries | direkte Datenbankabfragen allgemein | SQL-Injection |
safe_redirect | wp_redirect() statt wp_safe_redirect() | offene Weiterleitung |
Das PHPCS-Regelwerk hinter der Prüfung plugin_review_phpcs lädt zusätzlich die WPCS-Sniffs für Nonces, Eingabebereinigung und vorbereitetes SQL, gehört aber zur Kategorie plugin_repo, daher blendet --categories=security diese Treffer aus. Eine weitere Prüfung betrifft speziell generierten Code: file_type meldet KI-Entwicklungsverzeichnisse wie .cursor, .claude, .aider, .continue, .windsurf und .ai, die im Plugin liegen geblieben sind, weil der Plugin-Ordner das Arbeitsverzeichnis eines Coding-Assistenten war. Jeder Treffer hat einen Typ (ERROR oder WARNING) und einen Schweregrad von 1 bis 10. Welche Capability ein Handler verlangen sollte, weiß Plugin Check nicht, es verkürzt das manuelle Review also, ersetzt es aber nicht.
Wann ein KI-Plugin gepatcht und wann die ganze Website gerettet wird
Lokale Lücken (ein AJAX-Handler, ein Admin-Formular) lohnen sich nach dem Review zu patchen. Wenn dieselben fünf Muster in mehreren generierten Dateien auftauchen, wenn erfundene Funktionen in Produktionspfaden hängen oder wenn von der KI gewählte Plugins neben schlechtem eigenem Code aktive CVEs mitbringen, hören Sie mit isolierten Patches auf. Das Audit zur Rettung KI-erstellter Websites liefert eine klare Aufteilung in Behalten, Neu schreiben und Entfernen. So zahlen Sie nicht für einen kompletten Neubau, wenn eine Rettung reicht, und patchen nicht endlos, wenn das Fundament nicht trägt. Wenn der Stack zusätzlich mehr als dreißig Plugins und kaputte Core Web Vitals hat, kombinieren Sie das Code-Audit mit der Core-Web-Vitals-Rettung für KI-erstellte Websites.
Der Preis für Rettung und Audit ist individuell und wird nach dieser Bestandsaufnahme festgelegt. Schreiben Sie uns mit der URL des Plugins oder der Website und mit der Angabe, wie der Code generiert wurde.
Zusammenfassung und Empfehlungen
Künstliche Intelligenz ist ein mächtiger Beschleuniger für das Schreiben von Code, kann aber keine technische Verantwortung übernehmen. Behandeln Sie den gesamten von einer KI geschriebenen Code so, als stammte er von einem unerfahrenen Praktikanten.
Stellen Sie sicher, dass Sie robuste Capability-Prüfungen (current_user_can()), CSRF-Verifizierungen (wp_verify_nonce()), Datenbankparametrisierungen ($wpdb->prepare()), Eingabebereinigung und spätes Ausgabe-Escaping implementieren. Durch die Kombination dieser Kernpraktiken mit statischen Analysetools können Sie WordPress-Code schneller schreiben und gleichzeitig eine absolut sichere Anwendung gewährleisten.







