Zum Inhalt springen
Server & .htaccess

WordPress .htaccess Sicherheitsregeln, die wirklich etwas bringen

Das meiste, was als WordPress .htaccess Sicherheit verkauft wird, ist Füllmaterial. Die Regeln, die deine Angriffsfläche tatsächlich verändern, sind kurz — hier erfährst du, was was ist

Veröffentlicht

Das meiste, was als “WordPress .htaccess Sicherheit” verkauft wird, ist Füllmaterial. Die Regeln, die deine Angriffsfläche wirklich verändern, sind kurz: PHP-Ausführung innerhalb von wp-content/uploads blockieren, direkten Zugriff auf wp-config.php verweigern und das Directory-Listing abschalten. Die populären Regeln — xmlrpc.php blockieren, “um Brute-Force zu stoppen”, die WordPress-Version verstecken, eine 200 Zeilen lange Bad-Bot-User-Agent-Liste einfügen — reichen von marginal bis reines Theater. Im Folgenden liest du, was was ist und warum.

Eines vorweg: .htaccess bewirkt überhaupt nur etwas auf Apache (und auf LiteSpeed, das die Datei ebenfalls liest). Auf nginx wird sie komplett ignoriert — die Datei liegt einfach nur herum, während du dich geschützt wähnst. Läuft bei deinem Hoster nginx, gilt nichts davon und du brauchst stattdessen server/location-Blöcke. Prüfe es mit curl -I https://yoursite.com und wirf einen Blick auf den Server:-Header, bevor du eine Stunde damit verbringst, eine Datei zu bearbeiten, die der Server nie liest.

Die Regel, die wirklich zählt: kein PHP in /uploads

Das ist die eine, die sich lohnt. wp-content/uploads ist konstruktionsbedingt für alle beschreibbar — jeder Medien-Upload, jedes Plugin, das eine Datei speichert, schreibt dorthin. Schafft es ein Angreifer, eine .php-Datei in dieses Verzeichnis zu bekommen (über einen verwundbaren Upload-Handler, ein Bildfeld, das den MIME-Typ nicht prüft, ein kompromittiertes Plugin), entscheidet sich der Unterschied zwischen einer Belästigung und einer vollständigen Remote-Code-Execution allein daran, ob der Server diese Datei bei Aufruf ausführt. Verweigere die Ausführung, und der hochgeladene Payload ist nur eine inaktive Datei auf der Festplatte.

Trag das in wp-content/uploads/.htaccess ein (leg die Datei an, falls sie nicht existiert):

<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

Das ist die Syntax von Apache 2.4. Auf dem älteren 2.2 lautet das Äquivalent Order Deny,Allow / Deny from all. Beide Dialekte in einer Datei zu vermischen ist die häufigste Ursache für einen plötzlichen 500 Internal Server Error nach dem “Härten” — wenn die ganze Seite in dem Moment stirbt, in dem du speicherst, ist fast immer das der Grund. Deine Version prüfst du mit apachectl -v.

wp-config.php schützen

wp-config.php enthält deine Datenbank-Zugangsdaten und die Auth-Salts. Solange PHP läuft, liefert eine direkte Anfrage darauf eine leere Seite zurück — PHP führt die Datei aus, statt sie auszugeben. Das Risiko ist der Fehlerfall: Stürzt PHP jemals ab, wird bei einer Migration falsch konfiguriert oder der Handler deaktiviert, liefert Apache die Datei als Klartext aus und schüttet dein DB-Passwort jedem aus, der danach fragt. Den Zugriff zu verweigern ist eine billige Versicherung gegen fünf schlechte Minuten:

<Files wp-config.php>
    Require all denied
</Files>

Directory-Listing abschalten

Besucht jemand einen Ordner ohne index.php und Apache hat Options +Indexes aktiv, listet es den Inhalt auf — jede Backup-Datei, jeden vergessenen SQL-Dump. Schalte es seitenweit ab:

Options -Indexes

Geringe Schwere, aber real, und es kostet nichts.

Das ist die ehrliche Kernliste. Du kannst diese Regeln — samt der korrekten 2.4-vs-2.2-Syntax, damit du deine Seite nicht mit einem 500 lahmlegst — mit dem WordPress .htaccess Generator zusammenstellen, statt sie aus einem Forenbeitrag zu kopieren, der für die falsche Apache-Version geschrieben wurde.

Was du NICHT tun solltest

xmlrpc.php blockieren “zum Brute-Force-Schutz”. Das ist der große Punkt, den alle nachplappern, und so wie er dasteht, ist er falsch. Ja, die Methode system.multicall von XML-RPC erlaubte es einem Angreifer früher, viele Login-Versuche in eine einzige Anfrage zu bündeln — echte Verstärkung. Aber der überwältigend häufige Brute-Force-Vektor sind schlichte POST-Anfragen an wp-login.php, und xmlrpc.php zu blockieren bringt dagegen nichts. Brute-Force schlägst du mit Rate-Limiting, starken Passwörtern und 2FA zurück — nicht damit, einen einzelnen Endpunkt abzuwürgen. Es gibt einen legitimen Grund, XML-RPC zu deaktivieren: Seine Pingback-Funktion lässt sich für DDoS-Reflection missbrauchen. Nutzt du also weder Jetpack noch die mobile App noch Pingbacks, verkleinert das Schließen deine Angriffsfläche. Rede dir nur nicht ein, es sei dein Brute-Force-Schutz, denn das ist es nicht.

Die WordPress-Version verstecken / das Generator-Tag entfernen. readme.html zu entfernen und das <meta name="generator">-Tag zu strippen fühlt sich nach Härtung an. Ein Angreifer erkennt deine Version an den Query-Strings der eingebundenen Assets, am Block-Editor-Markup und an einem Dutzend weiterer Merkmale in Sekunden. Du versteckst gar nichts; du kommst dir nur beschäftigt vor.

Riesige Bad-Bot-User-Agent- und Referrer-Blocklisten. Der User-Agent ist ein einziger, leicht gefälschter HTTP-Header. Diese Listen sind an dem Tag veraltet, an dem du sie einfügst, sie blockieren nichts Kompetentes, und Apache wertet jedes Regex bei jeder Anfrage aus — du zahlst eine echte Performance-Steuer für null Sicherheit. Lass sie weg.

wp-login.php per IP sperren. Toll, bis dein Provider deine Adresse wechselt und du dich aus deinem eigenen Admin ausgesperrt hast. Nur mit einer echten statischen IP praktikabel.

Redirects gegen Autoren-Enumeration (?author=1). Das .htaccess-Rewrite, das die Leute dafür einfügen, ist für sich genommen unvollständig — der REST-Endpunkt /wp-json/wp/v2/users listet die Benutzernamen weiterhin auf. Einen Pfad zu blockieren, während der andere offen bleibt, ist Theater.

Immer noch festgefahren?

Legt eine Regel die Seite mit einem 500 lahm, ist es die Syntax — zieh den zuletzt hinzugefügten Block wieder raus und lade neu; das isoliert das Problem sofort. Scheint eine Regel gar nichts zu bewirken, vergewissere dich, dass du tatsächlich auf Apache bist und dass AllowOverride für das Verzeichnis aktiviert ist (viele Managed-Hoster schränken das ein). Bau die Datei aus einer nachweislich funktionierenden Vorlage mit dem .htaccess Generator, behalte die drei Regeln, die zählen, und lass den Rest weg.