Aktuelle Lage: PHP2Shell. Zwei kritische PHP-Lücken (CVSS 9.2) erlauben Schadcode ohne Anmeldung. Patches seit 21.10.2026.Was jetzt zu tun ist →

PHP-Ausführung in Upload-Ordnern verbieten

Eine Webshell braucht zwei Dinge: einen Ordner, in den sie geschrieben werden kann, und einen Server, der sie ausführt. So nehmen Sie ihr das zweite, und zwar in jedem beschreibbaren Ordner, nicht nur in uploads.

Stand 6 Min. LesezeitHärtung und Konfiguration

Kurz gesagt: Um PHP-Ausführung in Uploads zu verbieten, ermitteln Sie zuerst alle Ordner, in die PHP schreiben darf, und sperren dann in jedem davon die Ausführung von Skripten in der Serverkonfiguration, nicht per .htaccess. In Nginx muss die Sperre vor dem allgemeinen PHP-Block greifen, in Apache gehört sie in den VirtualHost mit AllowOverride None. security.limit_extensions = .php im FPM-Pool und ein Test mit einer harmlosen Datei schließen die Arbeit ab.

Warum gerade jetzt die Upload-Ordner zählen

Nach einer kritischen Lücke wie PHP2Shell wollen Angreifer selten nur einmal Code ausführen. Sie wollen wiederkommen, auch wenn der Server später gepatcht wird. Der einfachste Weg dafür ist eine Webshell: eine kleine PHP-Datei, abgelegt in einem beschreibbaren Ordner und später über den Browser aufgerufen.

Ein Patch entfernt eine solche Datei nicht. Wer ab dem 20. Oktober 2026 ungepatcht online war, sollte deshalb nicht nur aktualisieren, sondern auch prüfen, ob irgendwo neue PHP-Dateien liegen, und künftig verhindern, dass sie ausgeführt werden. Wie Sie Fundstellen deuten, beschreibt PHP-Dateien im Upload-Ordner: Fundstellen richtig deuten.

Die Ausführungssperre setzt an der zweiten Bedingung an. Sie verhindert nicht, dass eine Datei abgelegt wird, aber dass der Server sie als Programm behandelt.

Zuerst die Inventur: Wo darf PHP schreiben?

Die meisten Anleitungen nennen nur den Upload-Ordner. In der Praxis schreibt eine PHP-Anwendung an viel mehr Stellen. Jede davon, die über den Webserver erreichbar ist, braucht die Sperre.

Ordnertyp Typischer Inhalt Warum beschreibbar
Uploads, Medien Bilder, PDFs, Anhänge Nutzer und Redaktion laden Dateien hoch
Cache erzeugte Seiten, Vorschaubilder Anwendung beschleunigt Auslieferung
Temp, Import, Export CSV-Dateien, Zwischenstände Schnittstellen und Datenaustausch
Backups im Webroot .zip, .sql Erweiterungen sichern „vor Ort“
Logs im Webroot Fehler- und Debug-Logs falsch konfigurierte Anwendungen

Welche Ordner das auf Ihrem Server sind, zeigt eine Suche mit den Rechten des Laufzeitbenutzers. Sie verändert nichts:

# Alle Ordner unter /var/www, in die der PHP-Benutzer schreiben darf
# (Benutzer anpassen: www-data, nginx, apache oder eigener Pool-Benutzer)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Liegen in diesen Ordnern schon PHP-Dateien?
sudo -u www-data find /var/www -type d -writable -print0 2>/dev/null \
  | xargs -0 -I{} find {} -maxdepth 1 -type f -iname "*.ph*" 2>/dev/null

Gibt die erste Suche den gesamten Webroot zurück, gehört der Programmcode dem Laufzeitbenutzer. Das sollten Sie vorher ändern, wie der Ratgeber Dateirechte auf dem Webserver beschreibt. Sonst gibt es keinen Ordner, der nicht gesperrt werden müsste.

PHP-Ausführung in Uploads verbieten: Nginx

Bei Nginx entscheidet die Reihenfolge. Laut Nginx-Dokumentation werden reguläre Ausdrücke in der Reihenfolge der Konfigurationsdatei geprüft, und der erste Treffer gewinnt. Steht der allgemeine Block location ~ \.php$ vor Ihrer Sperre, wird die Datei ausgeführt. Eine einfache Präfix-Location ohne ^~ schützt aus demselben Grund nicht.

Sicher ist ein regulärer Ausdruck für alle gesperrten Ordner, der vor dem PHP-Block steht. Er deckt auch selten genutzte Endungen ab:

server {
    # ... Grundkonfiguration ...

    # 1. Sperre für beschreibbare Ordner, MUSS vor dem PHP-Block stehen
    location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
        deny all;
    }

    # 2. Allgemeiner PHP-Block: nur existierende Dateien übergeben
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/seite1.sock;
    }
}

Passen Sie die Ordnernamen an Ihre Inventur an. Bei Anwendungen mit einem einzigen Einstiegspunkt ist der Weg über eine Erlaubnisliste noch stärker; das Muster zeigt Nginx für PHP sicher konfigurieren.

Apache und PHP-FPM: die Sperre an der richtigen Stelle

In Apache gehört die Sperre in die Serverkonfiguration oder den VirtualHost. Eine .htaccess im Upload-Ordner ist ungeeignet, weil jeder sie ändern kann, der dort schreiben darf. Für den gesamten Webroot gilt deshalb AllowOverride None. Laut Apache-Dokumentation ist AllowOverride nur in <Directory>-Blöcken ohne reguläre Ausdrücke erlaubt, also setzen Sie es am Webroot und die Sperre per <DirectoryMatch> darunter:

<Directory /var/www/seite1/public>
    AllowOverride None
    Require all granted
</Directory>

<DirectoryMatch "^/var/www/seite1/public/(uploads|media|cache|tmp|export)/">
    <FilesMatch "\.(php\d?|phtml|phar|pht|phps)$">
        Require all denied
    </FilesMatch>
</DirectoryMatch>

Läuft noch mod_php, ergänzen Sie im selben Block php_admin_flag engine off. Bei PHP-FPM wirkt eine zweite Schranke im Pool: security.limit_extensions legt fest, welche Endungen FPM überhaupt ausführt. Laut PHP-Handbuch ist der Standard .php .phar; empfohlen wird die Beschränkung auf .php.

; im Pool, z. B. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php

Testen mit einer harmlosen Datei

Ob die Sperre wirkt, zeigt nur ein Test. Legen Sie in jeden gesperrten Ordner kurz eine Datei, die lediglich einen Text ausgibt, rufen Sie sie über die Domain auf und löschen Sie sie danach.

  1. Konfiguration prüfen: nginx -t beziehungsweise apachectl configtest, dann neu laden.
  2. Testdatei anlegen, zum Beispiel uploads/sperrtest.php mit dem Inhalt <?php echo 'ausgefuehrt';.
  3. Mit curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php aufrufen. Erwartet wird 403.
  4. Erscheint stattdessen 200 und der Text „ausgefuehrt“, greift die Sperre nicht. Konfiguration und Reihenfolge prüfen.
  5. Testdatei löschen und den Test für jeden Ordner und jede Website wiederholen.
Wichtig

Finden Sie bei der Inventur bereits unbekannte PHP-Dateien in beschreibbaren Ordnern, löschen Sie nichts vorschnell. Sichern Sie zuerst den Zustand und die Logs, denn diese Dateien sind Beweismittel. Wie Sie dann vorgehen, beschreibt Webshells erkennen und entfernen.

Wie Upload-Funktionen im Code sicher gebaut werden, mit Typprüfung und Ablage außerhalb des Webroots, steht im Ratgeber Datei-Uploads in PHP sicher umsetzen.

Fazit: Schreiben ja, ausführen nein

Die Ausführungssperre in beschreibbaren Ordnern ist eine der wirksamsten Einzelmaßnahmen gegen dauerhafte Hintertüren. Sie kostet wenige Zeilen Konfiguration und bricht bei sauber gebauten Anwendungen nichts. Entscheidend sind drei Dinge: eine vollständige Inventur statt nur des offensichtlichen Upload-Ordners, die richtige Reihenfolge in Nginx beziehungsweise die richtige Ebene in Apache und ein echter Test mit einer harmlosen Datei.

Ergänzt um getrennte Eigentümer für den Programmcode, security.limit_extensions im Pool und eine regelmäßige Suche nach neuen PHP-Dateien entsteht ein Zustand, in dem eine abgelegte Datei zwar ärgerlich, aber kaum noch nutzbar ist. Das ersetzt weder das Update noch die Spurensuche, nimmt Angreifern aber eines ihrer wichtigsten Werkzeuge.

Wie hilft PHP SOS konkret?

  • Inventur: Wir ermitteln alle beschreibbaren Ordner je Website und prüfen sie auf vorhandene PHP-Dateien.
  • Sperren setzen: Wir tragen die Ausführungssperren in Nginx, Apache und PHP-FPM ein, in der richtigen Reihenfolge und ohne .htaccess-Abhängigkeit.
  • Testen: Jede Sperre prüfen wir mit einer harmlosen Datei und dokumentieren das Ergebnis.
  • Bereinigen: Bei Funden übernehmen wir Spurensicherung und Malware-Entfernung.

Häufige Fragen

Reicht eine .htaccess im Upload-Ordner, um PHP zu verbieten?

Nicht zuverlässig. Wer in den Ordner schreiben kann, kann auch die .htaccess ändern oder ersetzen. Die Sperre gehört in die Serverkonfiguration oder den VirtualHost, und für den Webroot sollte AllowOverride None gelten.

Welche Ordner muss ich sperren?

Alle Ordner, in die der PHP-Benutzer schreiben darf und die über den Webserver erreichbar sind. Neben Upload-Ordnern sind das oft Cache-, Temp-, Import-, Export- und Backup-Verzeichnisse. Ermitteln Sie sie mit einer Suche als Laufzeitbenutzer.

Bricht die Sperre meine Website?

In der Regel nicht, denn in Upload- und Cache-Ordnern liegen bei sauberen Anwendungen keine Skripte, die direkt aufgerufen werden. Einzelne Erweiterungen legen dort aber doch PHP-Dateien ab. Testen Sie deshalb nach der Umstellung die wichtigsten Funktionen.

Schützt die Sperre vor PHP2Shell?

Nein. PHP2Shell ist eine Lücke im PHP-Interpreter, die nur durch das Update und den Neustart aller Worker geschlossen wird. Die Sperre verhindert aber, dass eine abgelegte Datei später über den Browser aufgerufen und als dauerhafte Hintertür genutzt wird.

Quellen

Sofort-Kontakt

Jede Stunde zählt. Schreiben Sie uns jetzt.

Schildern Sie kurz System, PHP-Version und Beobachtung. Wir melden uns, klären die Lage und arbeiten remote, bis der Vorfall abgeschlossen und dokumentiert ist.

Sofort-Hilfe