Zum Inhalt springen
Planen wir gemeinsam die passende Software für Ihre Prozesse. Demo oder Angebot: +90 546 737 48 29

TR EN DE

Datei-Upload-Sicherheit und Webshells

Der Datei-Upload (Profilfoto, Produktbild, Lebenslauf, Anhang) gehört zu den riskantesten Stellen einer Website. Wird der Upload nicht ausreichend geprüft, kann auf dem Server eine Skriptdatei platziert werden, die ausgeführt wird, sobald sie im Browser aufgerufen wird. Solche Dateien heißen Webshell: eine Hintertür, die dem Angreifer erlaubt, auf dem Server Dateien zu lesen, zu verändern und Befehle auszuführen. Eine Webshell kann nicht nur über ein Upload-Formular, sondern auch über ein übernommenes FTP-Konto oder über eine Schwachstelle in einem nicht aktualisierten Plugin platziert werden.

Die Verteidigung steht auf zwei Beinen: Uploads nur nach strengen Regeln annehmen und dafür sorgen, dass in dem Verzeichnis, in dem die hochgeladenen Dateien liegen, kein Skript ausgeführt wird. Das zweite verhindert den Schaden selbst dann, wenn beim ersten ein Fehler passiert.

Kurz gefasst

  • Der Dateityp wird anhand des Inhalts geprüft; akzeptiert werden nur Typen aus der Positivliste.
  • Den Dateinamen erzeugt der Server; die Dateien liegen außerhalb des Web-Roots oder in einem Verzeichnis ohne Skriptausführung.
  • Unerwartete PHP-Dateien, geänderte Datumsangaben und seltsame Weiterleitungen sind Anzeichen einer Webshell.
  • Kopieren Sie eine schädliche Datei, bevor Sie sie löschen, und schließen Sie das Einfallstor.
Auf dieser Seite

Die Regeln für sichere Uploads

  1. Prüfen Sie den Typ anhand des Inhalts und verwenden Sie eine Positivliste

    Vertrauen Sie weder dem Dateityp, den der Browser meldet ($_FILES[...]['type']), noch der Endung im Dateinamen; beides steht unter der Kontrolle des Benutzers. Lesen Sie den tatsächlichen Typ der Datei auf dem Server aus ihrem Inhalt (finfo) und akzeptieren Sie ausschließlich die Typen, die Sie erlauben. Der Ansatz „Diese Endungen sind verboten“ (Negativliste) ist nicht verlässlich; zählen Sie auf, was erlaubt ist, und lehnen Sie alles andere ab.

    Ablaufdiagramm: Upload-Fehler prüfen, Größenlimit, Typprüfung anhand des Inhalts, Positivliste, zufälliger Name, sicheres Verzeichnis : Vergrößern
  2. Legen Sie den Dateinamen selbst fest

    Verwenden Sie den vom Benutzer angegebenen Dateinamen nicht auf dem Datenträger. Sonderzeichen, Pfadtrenner und doppelte Endungen im Namen (etwa dokument.php.jpg) sind eine Fehlerquelle. Speichern Sie die Datei unter einem zufälligen Namen, den Sie auf dem Server erzeugen, und mit der Endung, die dem geprüften Typ entspricht; den Originalnamen bewahren Sie nur zur Anzeige in der Datenbank auf.

    Vergleich: Den Dateinamen des Benutzers und den gemeldeten Typ zu verwenden ist falsch; zufälliger Name und anhand des Inhalts geprüfter Typ sind richtig : Vergrößern
  3. Speichern Sie Dateien dort, wo nichts ausgeführt wird

    Der sicherste Ort ist ein Verzeichnis außerhalb des Web-Roots: Die Datei ist über eine Adresse nicht direkt erreichbar und wird nur über ein Skript ausgeliefert, das die Berechtigung prüft. Müssen die Dateien direkt über eine Adresse ausgeliefert werden (z. B. Produktbilder), schalten Sie die Skriptausführung im Upload-Verzeichnis über die Serverkonfiguration ab.

    Schaubild: Speicherung außerhalb des Web-Roots und Upload-Verzeichnis ohne Skriptausführung : Vergrößern
  4. Begrenzen Sie Größe, Anzahl und den Kreis der Berechtigten

    Setzen Sie ein Limit für die Dateigröße und für die Anzahl der Dateien, die ein Benutzer hochladen darf; andernfalls kann der Speicherplatz gefüllt werden. Der Upload sollte nach Möglichkeit nur angemeldeten Benutzern offenstehen, und das Formular sollte mit einem CSRF-Token geschützt sein.

    Schaubild: Upload-Grenzen; Größenlimit, Limit für die Anzahl der Dateien, Anmeldepflicht, CSRF-Token : Vergrößern
  5. Lernen Sie die Anzeichen einer Webshell kennen

    Trotz aller Maßnahmen kann sich eine schädliche Datei auf dem Server eingenistet haben. Unerwartete PHP-Dateien, geänderte Datumsangaben von Dateien und seltsame Weiterleitungen sind die ersten Hinweise; die ausführliche Liste steht weiter unten im Abschnitt „Anzeichen einer Webshell“.

    Checkliste: Anzeichen einer Webshell; unerwartete PHP-Dateien, geänderte Datumsangaben, fremde Weiterleitungen, unbekannte Konten : Vergrößern

Beispiel für einen sicheren Upload (PHP)

Das folgende Beispiel verarbeitet den Upload eines einzelnen Bildes oder einer PDF-Datei: Es prüft Upload-Fehler und Größe, liest den Typ aus dem Inhalt, gleicht ihn mit der Positivliste ab, erzeugt einen zufälligen Namen und verschiebt die Datei in ein Verzeichnis außerhalb des Web-Roots.

PHP
<?php
// Erlaubte Typen: tatsächlicher MIME-Typ => Endung, unter der gespeichert wird
$izinli = [
    'image/jpeg'      => 'jpg',
    'image/png'       => 'png',
    'image/webp'      => 'webp',
    'application/pdf' => 'pdf',
];
$azamiBoyut = 5 * 1024 * 1024;                 // 5 MB
$hedefKlasor = dirname(__DIR__) . '/depo';     // AUSSERHALB des Web-Roots

$dosya = $_FILES['belge'] ?? null;
if ($dosya === null || !is_uploaded_file($dosya['tmp_name']) || $dosya['error'] !== UPLOAD_ERR_OK) {
    http_response_code(400);
    echo 'Die Datei konnte nicht hochgeladen werden. Bitte versuchen Sie es erneut.';
    return;
}
if ($dosya['size'] <= 0 || $dosya['size'] > $azamiBoyut) {
    http_response_code(400);
    echo 'Die Datei darf höchstens 5 MB groß sein.';
    return;
}

// Den Typ nicht aus der Angabe des Browsers, sondern aus dem Inhalt der Datei lesen
$finfo = new finfo(FILEINFO_MIME_TYPE);
$tur = $finfo->file($dosya['tmp_name']);
if (!isset($izinli[$tur])) {
    http_response_code(400);
    echo 'Es werden nur JPG-, PNG-, WebP- und PDF-Dateien akzeptiert.';
    return;
}

// Den Namen erzeugt der Server; der vom Benutzer angegebene Name wird auf dem Datenträger nicht verwendet
$yeniAd = bin2hex(random_bytes(16)) . '.' . $izinli[$tur];
if (!move_uploaded_file($dosya['tmp_name'], $hedefKlasor . '/' . $yeniAd)) {
    error_log('Hochgeladene Datei konnte nicht verschoben werden: ' . $yeniAd);
    http_response_code(500);
    echo 'Die Datei konnte nicht gespeichert werden.';
    return;
}
chmod($hedefKlasor . '/' . $yeniAd, 0644);

// Der Originalname wird nur zur Anzeige in der Datenbank gespeichert
$sorgu = $pdo->prepare('INSERT INTO dosyalar (kullanici_id, disk_adi, ozgun_ad, tur) VALUES (?, ?, ?, ?)');
$sorgu->execute([$kullaniciId, $yeniAd, mb_substr(basename($dosya['name']), 0, 150), $tur]);

Weitere Empfehlungen:

  • Bilder neu erzeugen: Ein hochgeladenes Bild mit GD oder Imagick zu öffnen und neu zu speichern, bestätigt, dass die Datei wirklich ein Bild ist, und entfernt eingebetteten Ballast.
  • Vorsicht bei SVG: SVG-Dateien können Skripte enthalten. Lassen Sie sie nicht zu, wenn sie nicht nötig sind; falls doch, bereinigen Sie sie und liefern Sie sie als Download aus.
  • Archive nicht entpacken: Archive wie Zip auf dem Server automatisch zu entpacken, bringt wegen der enthaltenen Dateinamen und Größen zusätzliche Risiken mit sich.
  • Office- und PDF-Dokumente: Sie werden auf dem Server nicht ausgeführt, können aber für die Person, die sie herunterlädt, ein Risiko darstellen; lassen Sie sie nach Möglichkeit von einem Malware-Scanner prüfen.

Eine Datei außerhalb des Web-Roots ausliefern

Liegen die Dateien außerhalb des Web-Roots, liefert sie ein kleines Skript aus, das die Berechtigung prüft. Das Skript ermittelt die Datei über den Datensatz in der Datenbank; einen Dateipfad nimmt es vom Benutzer nicht entgegen.

PHP
<?php
// Die Datei wird über ihre ID angefordert; ein Pfad wird vom Benutzer nicht entgegengenommen
$sorgu = $pdo->prepare('SELECT disk_adi, ozgun_ad, tur FROM dosyalar WHERE id = ? AND kullanici_id = ?');
$sorgu->execute([(int) ($_GET['id'] ?? 0), $kullaniciId]);
$kayit = $sorgu->fetch();

$yol = $kayit ? dirname(__DIR__) . '/depo/' . basename($kayit['disk_adi']) : '';
if (!$kayit || !is_file($yol)) {
    http_response_code(404);
    echo 'Die Datei wurde nicht gefunden.';
    return;
}

header('Content-Type: ' . $kayit['tur']);
header('X-Content-Type-Options: nosniff');
header('Content-Disposition: attachment; filename="' . rawurlencode($kayit['ozgun_ad']) . '"');
header('Content-Length: ' . filesize($yol));
readfile($yol);

Der Header X-Content-Type-Options: nosniff verhindert, dass der Browser die Datei als einen anderen Typ interpretiert als den, den Sie angeben. Liefern Sie von Benutzern hochgeladene Dateien nach Möglichkeit als attachment (Download) aus.

Skriptausführung im Upload-Verzeichnis abschalten

Liegen die Dateien innerhalb des Web-Roots, legen Sie eine .htaccess wie die folgende in das Upload-Verzeichnis. Dieser Block verweigert den Zugriff auf Dateien mit PHP-Endung in diesem Verzeichnis vollständig; selbst wenn irgendwie ein Skript in das Verzeichnis gelangt, lässt es sich über die Adresse nicht aufrufen.

.htaccess (Apache)
# upload/.htaccess  (im Upload-Verzeichnis ablegen)

# Zugriff auf Dateien mit PHP-Endung verweigern
<FilesMatch "(?i)\.(php[0-9]?|phtml|phar|pht)$">
    Require all denied
</FilesMatch>

# Auch Namen ablehnen, die .php als Zwischenendung enthalten (z. B. name.php.jpg)
<FilesMatch "(?i)\.php[0-9]?\.">
    Require all denied
</FilesMatch>

# Verzeichnisauflistung und CGI-Ausführung abgeschaltet
Options -Indexes -ExecCGI
  • Diese Einstellung gilt für Apache 2.4 und für Hosting-Angebote, die .htaccess zulassen. Berücksichtigt Ihr Server keine .htaccess-Dateien (oder verwenden Sie Nginx), muss dieselbe Regel in der Serverkonfiguration definiert werden.
  • Testen Sie die Regel: Legen Sie eine Datei mit der Endung .php in das Verzeichnis, die lediglich einen harmlosen Text ausgibt, und rufen Sie ihre Adresse auf; Sie müssen die Antwort „403 Forbidden“ erhalten. Löschen Sie die Datei anschließend.
  • Ihr Upload-Skript darf nicht zulassen, dass eine Datei namens .htaccess hochgeladen wird; die Positivliste der Endungen verhindert das ohnehin.
  • Das Upload-Verzeichnis und die Dateien darin brauchen kein Ausführungsrecht; 755 für das Verzeichnis und 644 für die Dateien genügen.

Anzeichen einer Webshell

Wurde auf dem Server eine Hintertür platziert, läuft die Website meist ganz normal weiter. Achten Sie auf folgende Anzeichen:

  • Unerwartete PHP-Dateien: .php-Dateien in Upload-, Bild-, Cache- oder temporären Verzeichnissen; Namen, die Sie nicht kennen, die zufällig wirken oder einer Systemdatei nachempfunden sind.
  • Geänderte Datumsangaben: Core-Dateien, index.php, .htaccess oder die Konfigurationsdatei, die an einem Tag geändert wurden, an dem Sie kein Update durchgeführt haben.
  • Dateiinhalt: Abschnitte, die nichts mit normalem Code zu tun haben und aus einer sehr langen einzelnen Zeile sinnloser Zeichenfolgen bestehen; fremder Code, der am Anfang oder am Ende einer Datei eingefügt wurde.
  • Seltsame Weiterleitungen: Besucher, die über eine Suchmaschine oder vom Smartphone kommen, werden auf andere Websites umgeleitet; Links und Seiten, die Sie nicht angelegt haben.
  • Konten und Aufgaben: Administratorkonten, FTP-Konten und geplante Aufgaben (Cron), die Sie nicht kennen.
  • Protokolle: Aufeinanderfolgende POST-Anfragen an eine einzelne unbekannte PHP-Datei; Anfragen an eine Datei im Upload-Verzeichnis.
  • Warnungen von außen: Eine Missbrauchsmeldung Ihres Hosting-Anbieters, eine Warnung zu Sicherheitsproblemen in der Google Search Console, Spam-E-Mails, die von Ihrer Website versendet werden.

Signaturbasierte Scanner helfen, reichen für sich allein aber nicht aus; eine Hintertür, die sie nicht kennen, können sie als „sauber“ ausweisen. Das verlässlichste Verfahren ist, die Dateien auf dem Server mit einer sauberen Quelle zu vergleichen: Jede Datei und jede Abweichung, die im Originalpaket der Software oder in Ihrem eigenen Quellcode nicht vorkommt, muss untersucht werden.

Wenn Sie eine schädliche Datei gefunden haben

  1. Nicht sofort löschen, zuerst kopieren. Bewahren Sie eine Kopie der Datei, ihr Änderungsdatum und die zugehörigen Protokolleinträge auf; Sie brauchen sie, um das Einfallstor zu finden.
  2. Gehen Sie nicht davon aus, dass es nur eine Datei ist. Hintertüren werden meist an mehreren Stellen hinterlassen. Vergleichen Sie alle Dateien mit einer sauberen Quelle.
  3. Ändern Sie alle Passwörter: Hosting-Panel, FTP/SFTP, Datenbank, Administrationsbereich.
  4. Finden Sie das Einfallstor: Sehen Sie sich die Protokolleinträge rund um den Erstellungszeitpunkt der Datei an; welches Upload-Formular, welches Plugin oder welches Konto wurde benutzt?
  5. Schließen Sie die Schwachstelle und aktualisieren Sie die Software. Wenn Sie nur die Datei löschen, wird sie auf demselben Weg erneut hochgeladen.

Das schrittweise Vorgehen bei einem Sicherheitsvorfall beschreibt die Anleitung Website gehackt: Was tun?.

Checkliste

  • Der Dateityp wird auf dem Server anhand des Inhalts geprüft; akzeptiert werden nur Typen aus der Positivliste.
  • Der Dateiname wird auf dem Server zufällig erzeugt; der vom Benutzer angegebene Name wird auf dem Datenträger nicht verwendet.
  • Es gibt ein Limit für Größe und Anzahl der Dateien.
  • Die Dateien liegen außerhalb des Web-Roots oder in einem Verzeichnis ohne Skriptausführung.
  • Die Regel im Upload-Verzeichnis wurde getestet (eine PHP-Datei liefert 403).
  • Das Upload-Formular ist durch Anmeldung und CSRF-Token geschützt.
  • Die Upload-Verzeichnisse werden regelmäßig auf unerwartete Dateien kontrolliert.
  • Die Dateien lassen sich mit einer sauberen Quelle vergleichen (es gibt eine aktuelle Kopie des Quellcodes oder eine Liste der Datei-Hashes).

Häufige Fragen

Warum reicht es nicht, nur die Endung zu prüfen?

Die Endung ist Teil des Dateinamens und wird vom Benutzer bestimmt; der Inhalt kann von einem anderen Typ sein. Den Typ anhand des Inhalts zu prüfen, den Namen auf dem Server zu erzeugen und die Ausführung im Verzeichnis abzuschalten, muss zusammen umgesetzt werden.

Ist es sicherer, Dateien in der Datenbank zu speichern?

Das beseitigt das Risiko der Ausführung, bläht aber die Datenbank auf und macht das Backup schwerfälliger. Ein Verzeichnis außerhalb des Web-Roots bietet in den meisten Fällen dieselbe Sicherheit mit weniger Aufwand.

Der Sicherheitsscan meldet „sauber“; kann ich sicher sein, dass es keine Webshell gibt?

Nein. Scanner suchen nach bekannten Signaturen; eine veränderte oder neue Hintertür können sie übersehen. Verlässlicher ist es, die Dateien mit einer sauberen Quelle zu vergleichen und unerwartete Dateien anhand von Name und Speicherort zu untersuchen.

Ich habe keine Upload-Funktion; besteht trotzdem ein Risiko?

Ja. Eine Webshell kann auch über eine Schwachstelle in einem nicht aktualisierten Plugin oder über ein übernommenes FTP-Konto platziert werden. Updates, starke Passwörter und die Überwachung von Dateiänderungen bleiben notwendig.

BYK Yazılım Support-Team
Diese Anleitung wird vom Support-Team von BYK Yazılım erstellt und regelmäßig überprüft. Letzte Aktualisierung: 04.10.2026.

Verwandte Anleitungen

Sehen wir uns Ihre Website gemeinsam an

BYK Yazılım entwickelt Unternehmenswebsites. Schreiben Sie uns, wenn Sie Fragen zu Ihrer Website haben.

Kontakt aufnehmen Unsere Leistung: Unternehmenswebsite