Das Ausblenden von Versionsnummern allein ist zwar reine “Security through Obscurity” und ersetzt niemals regelmäßige Sicherheitsupdates. In Kombination mit robusten HTTP-Sicherheitsheadern, restriktiven Dateiberechtigungen und der Blockierung ungenutzter Schnittstellen reduziert dieser Schritt jedoch das Angriffsrauschen drastisch. In diesem technischen Leitfaden analysieren wir, wie Sie WordPress auf Code- und Webserver-Ebene härten.
Warum das Generator-Tag und Asset-Versionsnummern ein Risiko darstellen
Standardmäßig gibt eine frische WordPress-Installation an mehreren Stellen bereitwillig Auskunft über ihre genaue Version. Der prominenteste Indikator ist das HTML-Meta-Tag im <head>-Bereich des Dokuments:
<meta name="generator" content="WordPress 6.7.1" />Automatisierte Crawler benötigen lediglich einen simplen cURL-Aufruf auf die Startseite, um diesen String mit regulären Ausdrücken auszulesen. Neben dem Meta-Generator-Tag exponiert WordPress die Kernversion jedoch noch an weiteren, oft übersehenen Stellen:
- RSS- und Atom-Feeds: In
/feed/generiert die Funktionthe_generatorTags wie<generator>https://wordpress.org/?v=6.7.1</generator>. - Eingebundene Skripte und Stylesheets: Core-Skripte wie
wp-emoji-release.min.jsoder Basistreiber werden mit URL-Parametern wie?ver=6.7.1ausgeliefert. - Statische Readme-Dateien: Die Datei
readme.htmlim Stammverzeichnis enthält oft Versionsdetails in Reinschrift.
Wenn Sicherheitsforscher eine Remote-Code-Execution (RCE) oder SQL-Injection in einer bestimmten Kern- oder Pluginversion entdecken, suchen Exploit-Netzwerke gezielt nach genau diesen Versionsstrings. Das Entfernen dieser Fußabdrücke nimmt Ihnen aus dem Raster vollautomatisierter Massen-Scans heraus.
PHP-Hardening: Generator und Asset-Parameter sauber entfernen
Viele Anleitungen empfehlen, einfach den Parameter ver aus allen Asset-URLs per PHP-Filter abzuschneiden. Dies birgt jedoch ein massives Problem für das Browser-Caching: Werden Stylesheets oder Skripte aktualisiert, bemerken Browser und CDNs die Änderung nicht mehr, da die Dateinamen identisch bleiben (Cache-Busting-Versagen).
Die saubere architektonische Lösung besteht darin, Core-Versionsnummern gezielt zu maskieren oder bei eigenen Assets auf Hash-basierte Datei-Fingerprints zu setzen.
Generator-Tags in Head und Feeds deaktivieren
Fügen Sie die folgenden Hooks in ein Must-Use-Plugin (wp-content/mu-plugins/hardening.php) oder in die functions.php Ihres Child-Themes ein:
<?php
/**
* Plugin Name: WPPoland Security Hardening
* Description: Entfernt Versionshinweise und schützt sensible Endpunkte.
*/
// 1. Meta-Generator aus dem HTML-Head entfernen
remove_action('wp_head', 'wp_generator');
// 2. Generator-Tags aus RSS-, Atom- und RDF-Feeds entfernen
remove_action('rss2_head', 'the_generator');
remove_action('rss_head', 'the_generator');
remove_action('rdf_header', 'the_generator');
remove_action('atom_head', 'the_generator');
remove_action('commentsrss2_head', 'the_generator');
remove_action('opml_head', 'the_generator');
// 3. Generator im XML-RPC-Kontext leeren
add_filter('the_generator', '__return_empty_string');Intelligentes Filtern von Skript- und Style-Versionsnummern
Anstatt den Versionsparameter blind zu löschen, prüfen wir, ob der übergebene Wert mit der globalen WordPress-Version übereinstimmt. Falls ja, entfernen wir den Parameter oder ersetzen ihn durch einen anwendungsbezogenen Cache-Schlüssel:
function wppoland_filter_core_asset_versions(string $src): string {
global $wp_version;
if (empty($src)) {
return $src;
}
$parts = parse_url($src);
if (!isset($parts['query'])) {
return $src;
}
parse_str($parts['query'], $query_args);
if (isset($query_args['ver']) && $query_args['ver'] === $wp_version) {
// Kernversion aus URL entfernen, um Footprinting zu verhindern
return remove_query_arg('ver', $src);
}
return $src;
}
add_filter('script_loader_src', 'wppoland_filter_core_asset_versions', 9999);
add_filter('style_loader_src', 'wppoland_filter_core_asset_versions', 9999);Durch diese selektive Methode behalten Plugins wie WooCommerce oder Elementor ihre spezifischen Cache-Busting-Strings, während die Kernversion von WordPress nirgends mehr im Quellcode auftaucht.
HTTP-Security-Header auf Webserver-Ebene implementieren
HTTP-Header sind Anweisungen, die der Webserver bei jeder Antwort an den Webbrowser des Besuchers mitsendet. Sie steuern moderne Sicherheitsmechanismen im Browser, die vor Cross-Site-Scripting (XSS), Clickjacking, MIME-Type-Sniffing und Downgrade-Attacken schützen.
Da PHP-basierte Header-Modifikationen bei statischem Caching (z.B. Nginx FastCGI-Cache, Varnish oder Cloudflare) oft umgangen werden, sollten Security-Header grundsätzlich direkt im Webserver (Apache .htaccess oder Nginx Server-Block) konfiguriert werden.
1. X-Content-Type-Options: nosniff
Verhindert, dass Browser versuchen, den MIME-Typ einer Datei eigenständig zu erraten (MIME-Sniffing). Dadurch wird verhindert, dass eine manipulierte Bilddatei plötzlich als bösartiges JavaScript ausgeführt wird.
Header always set X-Content-Type-Options "nosniff"2. X-Frame-Options: SAMEORIGIN
Schützt Ihre Website vor Clickjacking-Angriffen. Clickjacking tritt auf, wenn ein Angreifer Ihre Website in einem unsichtbaren <iframe> über eine betrügerische Seite legt und den Benutzer dazu bringt, unwissentlich auf administrative Buttons zu klicken.
Header always set X-Frame-Options "SAMEORIGIN"3. HTTP Strict Transport Security (HSTS)
HSTS zwingt kompatible Browser, die Verbindung zu Ihrer Domain ausschließlich über HTTPS aufzubauen, selbst wenn der Nutzer manuell http:// in die Adresszeile eingibt. Dies unterbindet SSL-Strip-Angriffe im lokalen Netzwerk vollständig.
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"4. Referrer-Policy: strict-origin-when-cross-origin
Steuert, wie viele Referrer-Informationen an externe Websites übermittelt werden, wenn Nutzer externen Links folgen. Diese Einstellung schützt sensible Parameter in URLs interner Arbeitsabläufe vor dem Abfluss an Drittanbieter.
Header always set Referrer-Policy "strict-origin-when-cross-origin"5. Permissions-Policy
Deaktiviert riskante Browser-APIs (Kamera, Mikrofon, Geolocation), sofern diese auf Ihrer Website nicht benötigt werden. Selbst im Falle einer XSS-Lücke kann ein Schadskript diese Geräteschnittstellen nicht ansprechen.
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=()"6. Content-Security-Policy (CSP)
Die Content Security Policy ist das mächtigste Werkzeug moderner Websicherheit. Sie legt fest, aus welchen Quellen Skripte, Styles, Bilder und Schriften geladen werden dürfen. Inline-Skripte ohne kryptografischen Nonce werden standardmäßig blockiert.
Da viele WordPress-Plugins Inline-JavaScript nutzen, erfordert eine strikte CSP sorgfältiges Testen. Beginnen Sie mit einem auditierbaren Basis-Set:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' data: https:; connect-src 'self' https://www.google-analytics.com; object-src 'none'; frame-ancestors 'self';"Konfigurationsbeispiele für Apache und Nginx
Hier finden Sie einsatzbereite Konfigurationsblöcke für die beiden am weitesten verbreiteten Webserver.
Vollständige Apache .htaccess Konfiguration
Fügen Sie diesen Block an den Anfang Ihrer .htaccess-Datei ein, idealerweise vor den Rewrite-Regeln von WordPress:
<IfModule mod_headers.c>
# Verhindert MIME-Sniffing
Header always set X-Content-Type-Options "nosniff"
# Clickjacking-Schutz
Header always set X-Frame-Options "SAMEORIGIN"
# HTTPS erzwingen (1 Jahr Laufzeit inkl. Subdomains)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Referrer-Kontrolle
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Hardware-APIs sperren
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
# Cross-Site Scripting Filter für ältere Browser
Header always set X-XSS-Protection "1; mode=block"
</IfModule>
# Zugriff auf sensible Dateien sperren
<FilesMatch "^(wp-config\.php|readme\.html|license\.txt|\.env)">
Require all denied
</FilesMatch>
# XML-RPC Schnittstelle deaktivieren
<Files xmlrpc.php>
Require all denied
</Files>Vollständiger Nginx Server-Block (nginx.conf)
Unter Nginx werden Header innerhalb der server-Direktive deklariert. Beachten Sie, dass add_header-Direktiven in tieferliegenden location-Blöcken vererbt werden müssen:
server {
listen 443 ssl http2;
server_name beispiel.de www.beispiel.de;
# SSL-Zertifikate
ssl_certificate /etc/letsencrypt/live/beispiel.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/beispiel.de/privkey.pem;
# Security Headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Server-Tokens ausblenden (versteckt Nginx-Version)
server_tokens off;
root /var/www/beispiel.de;
index index.php index.html;
# Sensible Core-Dateien blockieren
location ~* /(?:readme\.html|license\.txt|wp-config\.php) {
deny all;
}
# XML-RPC sperren
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
# PHP-Verarbeitung
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}Angriffsflächen schließen: XML-RPC und REST API User Enumeration
Neben dem einfachen Verstecken der WordPress-Version gibt es zwei kritische Standard-Endpunkte, über die Angreifer wertvolle Informationen über Ihr System gewinnen:
1. XML-RPC (xmlrpc.php)
Die XML-RPC-Schnittstelle stammt aus der Frühzeit von WordPress, als Drittanbieter-Anwendungen noch keine moderne REST API hatten. Heute wird sie fast ausschließlich von Pingback-DDoS-Attacken und Brute-Force-Bots missbraucht. Über den Methodenaufruf system.multicall kann ein Angreifer hunderte Passwortkombinationen in einer einzigen HTTP-Anfrage ausprobieren und so typische Login-Limiter umgehen.
Sofern Sie nicht die offizielle mobile WordPress-App oder das Jetpack-Plugin nutzen, sollte xmlrpc.php ausnahmslos auf Serverebene blockiert werden (siehe Webserver-Regeln oben).
2. User Enumeration über die REST API
Standardmäßig liefert der WordPress-Endpunkt /wp-json/wp/v2/users eine Liste aller Benutzer aus, die Beiträge verfasst haben, inklusive deren numerischer ID und des exakten Anmeldenamens (Slug). Angreifer kennen damit bereits 50 % der für einen Einbruch notwendigen Zugangsdaten.
Um das unbefugte Auslesen von Benutzerdaten zu stoppen, fügen Sie folgenden Hook in Ihr Hardening-Plugin ein:
add_filter('rest_endpoints', function(array $endpoints): array {
if (isset($endpoints['/wp/v2/users']) && !current_user_can('list_users')) {
unset($endpoints['/wp/v2/users']);
}
if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)']) && !current_user_can('list_users')) {
unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
}
return $endpoints;
});Zusätzlich sollte die traditionelle Abfrage via /?author=1 abgefangen und auf die Startseite umgeleitet werden:
add_action('template_redirect', function(): void {
if (is_author() && !is_admin()) {
wp_safe_redirect(home_url(), 301);
exit;
}
});Dateiberechtigungen und Konfigurationsdateien härten
Eine häufige Ursache für erfolgreiche Manipulationen nach einem Einbruch sind übermäßig liberale Dateirechte. WordPress benötigt lediglich im Verzeichnis wp-content/uploads/ Schreibrechte, um Mediendateien hochzuladen. Sämtliche PHP-Dateien des Cores, der Themes und der Plugins sollten für den Webserver-Prozess schreibgeschützt sein.
Empfohlenes Rechtemodell auf Linux-Servern
Verbinden Sie sich per SSH mit Ihrem Server und setzen Sie die Standardberechtigungen:
# Verzeichnisse auf 755 (rwxr-xr-x) setzen
find /var/www/beispiel.de/ -type d -exec chmod 755 {} \;
# Dateien auf 644 (rw-r--r--) setzen
find /var/www/beispiel.de/ -type f -exec chmod 644 {} \;
# Konfigurationsdatei restriktiv schützen
chmod 400 /var/www/beispiel.de/wp-config.phpWenn Ihr Webserver unter einem dedizierten Benutzer läuft (z.B. www-data), stellen Sie sicher, dass der Besitzer der Dateien ein unprivilegierter Systembenutzer ist und der Webserver-Benutzer nur der Gruppe angehört.
Dateibearbeitung im WordPress-Dashboard deaktivieren
Verhindern Sie, dass Administratoren oder kompromittierte Admin-Accounts PHP-Dateien direkt im WordPress-Backend editieren können. Fügen Sie folgende Zeile in die wp-config.php vor /* That's all, stop editing! */ ein:
define('DISALLOW_FILE_EDIT', true);Damit wird der integrierte Theme- und Plugin-Editor im Dashboard komplett deaktiviert.
Verifikation und Sicherheitsprüfung
Nach der Implementierung müssen die Maßnahmen auf Funktionstüchtigkeit geprüft werden, um Fehlkonfigurationen auszuschließen.
- HTTP-Header im Terminal prüfen:
curl -sI https://beispiel.de | grep -iE "(strict-transport|x-frame|x-content|permissions|x-xss)" - Versionshinweise im Quelltext suchen: Laden Sie die Startseite herunter und suchen Sie nach Versionsresten:
curl -s https://beispiel.de | grep -i "generator" - Automatisierte Audit-Tools: Nutzen Sie unabhängige Analyse-Plattformen wie SecurityHeaders.com, um eine A- oder A+-Bewertung Ihrer HTTP-Header zu bestätigen.
Häufig gestellte Fragen (FAQ)
Reicht es aus, die WordPress-Versionsnummer zu verstecken?
Verhindert das Entfernen des ver-Parameters das Browser-Caching?
Warum sollte XML-RPC deaktiviert werden?
Kann eine zu strikte Content Security Policy meine Website zerstören?
Fazit und nächste Schritte
Gezieltes WordPress-Hardening erfordert keine teuren All-in-One-Sicherheitsplugins, die das System oft nur verlangsamen. Durch saubere PHP-Filter zur Versionsmaskierung, robuste HTTP-Sicherheitsheader auf Webserver-Ebene und restriktive Dateiberechtigungen minimieren Sie Ihre Angriffsfläche nachhaltig.
Möchten Sie Ihre WordPress-Infrastruktur professionell absichern und auf Konformität prüfen lassen? Informieren Sie sich über unsere spezialisierten WordPress-Sicherheitsaudits oder lassen Sie Ihre Umgebung durch erfahrene WordPress-Entwickler optimieren.






