Intelligente Dateityperkennung mit PHP

In den meisten heutigen Webanwendungen müssen Benutzer Bilder, Audio- und Videodateien hochladen können. Manchmal müssen wir auch das Hochladen bestimmter Dateitypen einschränken - eine ausführbare Datei ist ein offensichtliches Beispiel.

Abgesehen von der Sicherheit möchte man auch verhindern, dass Benutzer die Upload-Funktion missbrauchen, z. urheberrechtlich geschützte Musikdateien illegal hochladen und den Dienst nutzen, um Piraterie zu fördern! In diesem Artikel untersuchen wir einige Möglichkeiten, wie wir dies erreichen können.

Dateityperkennung über Erweiterungs- und MIME-Typen

Ich werde nicht zu ausführlich darüber sprechen, denn das ist, was wir normalerweise tun, wenn wir bestimmte Dateien einschränken wollen. Wir erhalten einfach den MIME-Typ der Datei mit $ _FILES ['myFile'] ['type'] und prüfen, ob es einen gültigen Typ hat.

Oder wir scannen die letzten Zeichen des Dateinamens und lehnen Dateien ab, die mit einer bestimmten Erweiterung enden. Leider sind diese Methoden kaum ausreichend, da man die Erweiterung einer Datei leicht ändern kann, um diese Einschränkung zu umgehen. Darüber hinaus werden Informationen zum MIME-Typ vom Browser bereitgestellt, und die meisten Browser bestimmen, wenn nicht alle, den Mime-Typ anhand der Dateierweiterung! Daher können MIME-Typen auch leicht gefälscht werden.

Lassen Sie uns nun einige andere Wege erkunden, die eine bessere Dummheit bieten.

Magic Bytes verwenden

Der beste Weg, den Dateityp zu ermitteln, besteht in der Untersuchung der ersten Bytes einer Datei, die als "magische Bytes" bezeichnet wird. Magische Bytes sind im Wesentlichen Signaturen, deren Länge zwischen 2 und 40 Byte in den Dateiheatern oder am Ende einer Datei variiert. Es gibt mehrere Hundert Dateitypen, und etliche von ihnen haben mehrere Dateisignaturen. Hier sehen Sie eine Liste der Dateisignaturen.

Obwohl inkonsistent, ist dies unsere beste Möglichkeit, Dateitypen zuverlässig zu erkennen. Diese anscheinend schwierige Aufgabe wurde durch eine PECL-Erweiterung namens Fileinfo sehr leicht gemacht. Ab PHP 5.3 wird Fileinfo mit der Hauptdistribution ausgeliefert und ist standardmäßig aktiviert. Dies ist definitiv eine robuste und einfache Möglichkeit, Einschränkungen für die hochgeladenen Dateitypen zu erkennen und aufzuerlegen.

Lassen Sie uns nun sehen, wie wir einen Dateityp mit Fileinfo erkennen können:

Umgang mit Bild-Uploads

Wenn Sie nur das Hochladen von Bildern zulassen möchten, können Sie die integrierte Funktion verwenden getimagesize () Funktion, um sicherzustellen, dass der Benutzer tatsächlich eine gültige Bilddatei hochlädt. Diese Funktion gibt false zurück, wenn die Datei keine gültige Bilddatei ist.

Magic-Bytes manuell lesen und interpretieren

Wenn Sie Fileinfo aus irgendeinem Grund nicht installieren können, können Sie den Dateityp immer noch manuell ermitteln, indem Sie die ersten paar Bytes einer Datei lesen und mit bekannten, dem jeweiligen Dateityp zugeordneten magischen Bytes vergleichen. Dieser Prozess hat definitiv ein Element von Versuch und Irrtum, da immer noch die Möglichkeit besteht, dass einige undokumentierte magische Bytes mit legitimen Dateiformaten verknüpft sind. Infolgedessen können gültige Dateien von Ihrem System abgelehnt werden. Dies war jedoch vor ein paar Jahren nicht unmöglich. Ich wurde gebeten, an einem Skript zu arbeiten, bei dem nur echte MP3-Dateien hochgeladen werden konnten. Da wir Fileinfo nicht verwenden konnten, haben wir auf dieses manuelle Scannen zurückgegriffen. Ich brauchte eine Weile, um einige der undokumentierten magischen Bytes für MP3 zu berücksichtigen, aber schon bald bekam ich ein stabiles Upload-Skript.

Bevor ich aufhöre, möchte ich mich einfach von einem allgemeinen Wort der Vorsicht trennen: Stellen Sie sicher, dass Sie niemals einen anrufen umfassen() mit einer hochgeladenen Datei, da PHP-Code sehr gut als Teil des Bildes ausgeblendet werden kann und das Bild Ihre Tests für die Dateivalidierung bestanden hat, nur, wenn es vom Server ausgeführt wird.