Was ist die sicherste Methode für eine Datei hochladen?
-
05-07-2019 - |
Frage
Das Unternehmen für die ich arbeite hat vor kurzem mit vielen Header-Injection und Datei-Upload-Exploits auf den Seiten getroffen worden wir hosten und während wir das Problem in Bezug behoben haben Injection-Angriffe auf Header, haben wir noch die Upload-Exploits unter Kontrolle zu bekommen.
Ich versuche, eine Plug-and-Play-Typenreihe von Upload-Skripten zur Einrichtung im Hause zu verwenden, die ein Designer in ihre Website-Struktur kopieren kann, einige Variablen ändern und haben ein ready-to-go Upload-Formular auf ihrer Website. Wir suchen unser Engagement so weit wie möglich zu begrenzen (wir haben geschlossen bereits fopen und Shell-Befehle nach unten).
ich gesucht habe die Website für die letzte Stunde und fand viele verschiedene Antworten mit spezifischen Methoden zu tun, die auf externe Quellen angewiesen. Was tun Sie alle denken, ist die beste skript einzige Lösung, die spezifisch genug ist als zuverlässiges Verfahren zum Schutz zu benutzen? Auch ich möchte die Sprache beschränkt sich auf PHP oder Pseudo-Code halten, wenn möglich.
Edit: Ich habe meine Antwort (geschrieben unten) und, während macht es die Verwendung des Shell-Befehl exec () machen, wenn Sie von Script-Dateien blockieren hochgeladen werden (was diese Lösung funktioniert sehr gut), werden Sie nicht auf Probleme stoßen.
Lösung
Die beste Lösung, IMHO, ist das Verzeichnis setzt die hochgeladenen Dateien außerhalb der „web“ Umgebung enthält und ein Skript verwenden, um sie zum Herunterladen zu machen. Auf diese Weise, auch wenn jemand ein Skript lädt es nicht durch den Aufruf aus dem Browser ausgeführt werden kann, und Sie müssen nicht die Art der hochgeladenen Datei überprüfen.
Andere Tipps
-
Erlauben Sie nur autorisierte Benutzer eine Datei hochgeladen werden. Sie können ein Captcha als auch hinzufügen, primitive Bots zu verhindern.
-
Zu allererst setzen Sie den
MAX_FILE_SIZE
in Ihrem Upload-Formular , und stellen Sie die maximale Dateisize
undcount
auf dem Server als auch.ini_set('post_max_size', '40M'); //or bigger by multiple files ini_set('upload_max_filesize', '40M'); ini_set('max_file_uploads', 10);
Haben Größenüberprüfung durch die hochgeladenen Dateien:
if ($fileInput['size'] > $sizeLimit) ; //handle size error here
-
Sie sollten Verwendung
$_FILES
undmove_uploaded_file()
Ihre hochgeladenen Dateien in das richtige Verzeichnis zu setzen, oder wenn Sie es bearbeiten wollen, dann mitis_uploaded_file()
überprüfen. (Diese Funktionen existieren verhindern Dateiname Injektionen durchregister_globals
.)$uploadStoragePath = '/file_storage'; $fileInput = $_FILES['image']; if ($fileInput['error'] != UPLOAD_ERR_OK) ; //handle upload error here, see http://php.net/manual/en/features.file-upload.errors.php //size check here $temporaryName = $fileInput['tmp_name']; $extension = pathinfo($fileInput['name'], PATHINFO_EXTENSION); //mime check, chmod, etc. here $name = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //true random id move_uploaded_file($temporaryName, $uploadStoragePath.'/'.$name.'.'.$extension);
Immer erzeugen eine zufällige ID anstelle der ursprünglichen Dateinamen mit .
-
Erstellen Sie eine neue Sub-Domain zum Beispiel http://static.example.com oder zumindest ein neues Verzeichnis außerhalb des
public_html
, für die hochgeladenen Dateien. Dieses Sub-Domain oder das Verzeichnis sollte nicht ausführen jede Datei . Legen Sie es in der Serverkonfiguration, oder setzen in a < strong>.htaccess
Datei durch das Verzeichnis.SetHandler none SetHandler default-handler Options -ExecCGI php_flag engine off
Setzen Sie ihn mit
chmod()
auch.$noExecMode = 0644; chmod($uploadedFile, $noExecMode);
Mit
chmod()
auf die neu zu hochgeladenen Dateien und legen Sie es auf dem Verzeichnis. -
Sie sollten überprüfen Sie die Mime-Typ durch den Hacker gesendet. Sie sollten eine Weiße Liste erlaubter Mime-Typ erstellen. Erlauben Sie Bilder nur , wenn ein anderes Format ist nicht erforderlich. Jedes anderes Format ist eine Bedrohung für die Sicherheit. Bilder auch, aber zumindest haben wir Werkzeuge, um sie zu handhaben ...
Der beschädigt Inhalt zum Beispiel: HTML in einer Image-Datei kann dazu führen, XSS von Browsern mit Inhalt Sniffing Verwundbarkeit . Wenn der beschädigte Inhalt ein PHP ist Code, dann kann es mit einem kombiniert werden eval Injektion Verwundbarkeit.$userContent = '../uploads/malicious.jpg'; include('includes/'.$userContent);
Versuchen Sie dies zu vermeiden, zum Beispiel einen
class autoloader
verwenden stattdessen PHP-Dateien manuell von einschließlich ...
Durch die Abwicklung der JavaScript-Injektion zunächst müssen Sie deaktivieren xss und Inhalt Sniffing in den Browsern . Content Sniffing Probleme sind typisch für ältere msie , ich denke, der andere Browser sie ziemlich gut filtern. Sowieso können Sie diese Probleme mit einem Bündel von Headern verhindern. (Nicht vollständig von jedem Browser unterstützt, aber das ist das Beste, was Sie auf Client-Seite tun können.)Strict-Transport-Security: max-age={your-max-age} X-Content-Type-Options: nosniff X-Frame-Options: deny X-XSS-Protection: 1; mode=block Content-Security-Policy: {your-security-policy}
Sie können überprüfen, ob eine Datei mit
Imagick identify
beschädigt ist, aber das bedeutet nicht, einen vollständigen Schutz.try { $uploadedImage = new Imagick($uploadedFile); $attributes = $uploadedImage->identifyImage(); $format = $image->getImageFormat(); var_dump($attributes, $format); } catch (ImagickException $exception) { //handle damaged or corrupted images }
Wenn Sie dienen andere Mime-Typen , sollten Sie immer Kraft herunterladen von ihnen, nie sind sie in Web-Seiten, wenn Sie wirklich wissen, was Sie tun ...
X-Download-Options: noopen Content-Disposition: attachment; filename=untrustedfile.html
-
Es ist möglich, gültige Bilddateien mit Code in sie zu haben, zum Beispiel in exif Daten. So haben Sie auf Säuberung exif von Bildern , wenn ihr Inhalt ist Ihnen nicht wichtig. Sie können das tun mit
Imagick
oderGD
, aber beide von ihnen erfordert Umpacken of die Datei. Sie können einexiftool
als Alternative finden. Ich denke, der einfachste Weg, exif zu löschen, ist es, Bilder mit GD Laden und speichern sie sie als PNG mit höchster Qualität . So werden die Bilder nicht verlieren, die Qualität und die exif Tag wird gereinigt werden, da GD es nicht verarbeiten kann. Machen Sie diese mit Bildern hochgeladen als PNG zu ...
Wenn Sie die exif Daten, verwenden niepreg_replace()
zu extrahieren, wenn diepattern
oderreplacement
von dem Benutzer ist, weil das zu einer eval Injektion führt ... Verwendenpreg_replace_callback()
statt dereval regex flag
, falls erforderlich. (Häufiger Fehler in Kopie Paste Codes.) Exif Daten können ein Problem sein, wenn Ihre Website eine hat eval Injektion Verwundbarkeit, wenn Sie zum Beispielinclude($userInput)
irgendwo verwenden. -
Nie
include()
,require()
durch hochgeladene Dateien verwenden , dienen sie als statische oder verwendenfile_get_contents()
oderreadfile()
, oder jede andere Datei Lesefunktion, wenn Sie den Zugriff steuern möchten.
Es ist selten möglich, aber ich denke, der beste Ansatz, um denX-Sendfile: {filename}
Header mit dem sendfile Apache-Modul zu verwenden. Durch die Headern, niemals Benutzereingaben ohne Validierung oder Hygienisierung verwendet werden, da das zu Header-Injection führt .
Wenn Sie nicht brauchen, Zugriffskontrolle (Mittel: nur autorisierte Benutzer die hochgeladenen Dateien sehen können), dann dienen die Dateien mit Ihrem Webserver. Es ist viel schneller ... -
Verwenden Sie einen antivir die hochgeladenen Dateien zu überprüfen, wenn Sie eine haben.
-
Immer verwenden, um einen kombinierten Schutz , nicht nur einen einzigen Ansatz. Es wird schwieriger sein, Ihre Verteidigung zu durchbrechen ...
Verwendung und Konfiguration von Gehärtete PHP ein einfaches Skript mit move_uploaded_file und die $ _ FILES superglobal. Das einfachste das Skript, die sichersten wird es (zumindest so sicher wie das läuft PHP-Version selbst) sein