Manchmal müssen Sie Benutzern zusätzlich zu den Standardformulardaten auch das Hochladen von Dateien ermöglichen. Da Dateien anders als andere Formulardaten in einem Formular übertragen werden, müssen Sie eine spezielle Codierung multipart/form-data angeben:
CODE:
<form action="upload.php" method="POST" enctype="multipart/form-data">
Ein Formular mit sowohl gewöhnlichen Formulardaten als auch Dateien ist ein spezielles Format, und die Angabe der Kodierungsmethode ermöglicht es dem Browser, die zu verarbeitenden Formatanforderungen zu befolgen.
Das Formularelement, mit dem Benutzer Dateien auswählen und hochladen können, ist sehr einfach:
CODE:
<input type="file" name="attachment" />
Dieses Element sieht in verschiedenen Browsern unterschiedlich aus. Traditionell umfasst die Benutzeroberfläche ein Standardtextfeld und eine Schaltfläche zum Durchsuchen, sodass der Benutzer den Pfad der Datei direkt manuell eingeben oder durch Durchsuchen auswählen kann. Im Safari-Browser gibt es nur die Schaltfläche „Durchsuchen“. Glücklicherweise sind ihre Funktionen und Verhaltensweisen gleich.
Um den Mechanismus zum Hochladen von Dateien besser zu veranschaulichen, finden Sie hier ein Beispiel, das Benutzern das Hochladen von Anhängen ermöglicht:
CODE:
<form action="upload.php" method="POST" enctype="multipart/form-data">Please choose a file to upload:
Die versteckte Formularvariable MAX_FILE_SIZE teilt dem Browser das Maximum mit Zulässige Dateigrößen zum Hochladen. Wie viele clientseitige Einschränkungen kann auch diese von einem Angreifer leicht umgangen werden, bietet jedoch eine Orientierungshilfe für legitime Benutzer. Diese Einschränkung ist nur dann zuverlässig, wenn sie auf dem Server erfolgt.
Unter den PHP-Konfigurationsvariablen steuert upload_max_filesize die maximal zulässige Dateigröße, die hochgeladen werden darf. Gleichzeitig kann post_max_size (die maximale Größe der übermittelten Daten des POST-Formulars) möglicherweise auch gesteuert werden, da die Datei über die Formulardaten hochgeladen wird.
Das empfangende Programm upload.php zeigt den Inhalt des superglobalen Arrays $_FILES an:
CODE:
<?php header('Content-Type: text/plain'); print_r($_FILES); ?>
Um den Upload-Prozess zu verstehen, verwenden wir eine Datei mit dem Namen Autor. txt-Test, das Folgende ist sein Inhalt:
CODE:
Chris Shiflett http://www.php.cn/
Wenn Sie diese Datei in das Programm upload.php hochladen, sehen Sie im Browser eine Ausgabe ähnlich der folgenden:
CODE:
Array ( [attachment] => Array ( [name] => author.txt [type] => text/plain [tmp_name] => /tmp/phpShfltt [error] => 0 [size] => 36 ) )
Obwohl es zu sehen ist Sehen Sie sich oben an, was PHP tatsächlich im superglobalen Array $_FILES bereitstellt, aber es liefert keine Rohinformationen der Formulardaten. Als sicherheitsorientierter Entwickler, der Eingaben identifizieren muss, um zu wissen, was der Browser tatsächlich sendet, lohnt es sich, einen Blick auf die folgenden HTTP-Anfrageinformationen zu werfen:
CODE:
POST /upload.php HTTP/1.1 Host: example.org Content-Type: multipart/form-data; boundary=----------12345 Content-Length: 245 ----------12345 Content-Disposition: form-data; name="attachment"; filename="author.txt" Content-Type: text/plain Chris Shiflett http://www.php.cn/ ----------12345 Content-Disposition: form-data; name="MAX_FILE_SIZE" 1024 ----------12345--
Obwohl Sie das Format der Anfrage nicht verstehen müssen , können Sie Dateien und zugehörige Metadaten identifizieren. Der Benutzer gibt nur den Namen und den Typ an, daher werden tmp_name, Fehler und Größe alle von PHP bereitgestellt.
Da PHP die hochgeladene Datei im temporären Dateibereich des Dateisystems (in diesem Beispiel /tmp/phpShfltt) speichert, besteht der übliche Vorgang darin, sie zum Speichern und Einlesen in den Speicher an andere Orte zu verschieben. Es besteht ein theoretisches Risiko, wenn Sie tmp_name nicht überprüfen, um sicherzustellen, dass es sich um eine hochgeladene Datei handelt (und nicht um etwas wie /etc/passwd). Dies wird als theoretisches Risiko bezeichnet, da keine bekannte Angriffsmethode bekannt ist, die es einem Angreifer ermöglicht, den Wert von tmp_name zu ändern. Nur weil es keine Angriffsmöglichkeiten gibt, bedeutet das jedoch nicht, dass Sie keine einfachen Sicherheitsmaßnahmen ergreifen müssen. Jeden Tag treten neue Angriffe auf und ein einfacher Schritt kann Ihr System schützen.
PHP bietet zwei praktische Funktionen, um diese theoretischen Risiken zu mindern: is_uploaded_file( ) und move_uploaded_file( ). Wenn Sie sicherstellen müssen, dass die Datei in tmp_name eine hochgeladene Datei ist, können Sie is_uploaded_file() verwenden:
CODE:
<?php $filename = $_FILES['attachment']['tmp_name']; if (is_uploaded_file($filename)) { /* $_FILES['attachment']['tmp_name'] is an uploaded file. */ } ?>
如果你希望只把上传的文件移到一个固定位置,你可以使用move_uploaded_file( ):
CODE:
<?php $old_filename = $_FILES['attachment']['tmp_name']; $new_filename = '/path/to/attachment.txt'; if (move_uploaded_file($old_filename, $new_filename)) { /* $old_filename is an uploaded file, and the move was successful. */ } ?>
最后你可以用 filesize( ) 来校验文件的大小:
CODE:
<?php $filename = $_FILES['attachment']['tmp_name']; if (is_uploaded_file($filename)) { $size = filesize($filename); } ?>
这些安全措施的目的是加上一层额外的安全保护层。最佳的方法是永远尽可能少地去信任。
以上就是PHP安全-文件上传攻击的内容,更多相关内容请关注PHP中文网(www.php.cn)!