.rar, .zip Dateien MIME Typ

156

Ich entwickle ein einfaches PHP-Upload-Skript und Benutzer können nur ZIP- und RAR-Dateien hochladen.

Welche MIME-Typen sollte ich zur Überprüfung verwenden $_FILES[x][type]? (eine vollständige Liste bitte)

Danke dir..

mrdaliri
quelle
Ich möchte nur alle komprimierten Dateien zulassen (rar, zip, tar.gz, jar usw.). Wie wird vorgegangen?
Ridhuvarshan

Antworten:

257

Die Antworten von freedompeace, Kiyarash und Sam Vloeberghs:

.rar    application/x-rar-compressed, application/octet-stream
.zip    application/zip, application/octet-stream, application/x-zip-compressed, multipart/x-zip

Ich würde auch den Dateinamen überprüfen. So können Sie überprüfen, ob es sich bei der Datei um eine RAR- oder ZIP-Datei handelt. Ich habe es getestet, indem ich eine schnelle Befehlszeilenanwendung erstellt habe.

<?php

if (isRarOrZip($argv[1])) {
    echo 'It is probably a RAR or ZIP file.';
} else {
    echo 'It is probably not a RAR or ZIP file.';
}

function isRarOrZip($file) {
    // get the first 7 bytes
    $bytes = file_get_contents($file, FALSE, NULL, 0, 7);
    $ext = strtolower(substr($file, - 4));

    // RAR magic number: Rar!\x1A\x07\x00
    // http://en.wikipedia.org/wiki/RAR
    if ($ext == '.rar' and bin2hex($bytes) == '526172211a0700') {
        return TRUE;
    }

    // ZIP magic number: none, though PK\003\004, PK\005\006 (empty archive), 
    // or PK\007\008 (spanned archive) are common.
    // http://en.wikipedia.org/wiki/ZIP_(file_format)
    if ($ext == '.zip' and substr($bytes, 0, 2) == 'PK') {
        return TRUE;
    }

    return FALSE;
}

Beachten Sie, dass es immer noch nicht 100% sicher ist, aber es ist wahrscheinlich gut genug.

$ rar.exe l somefile.zip
somefile.zip is not RAR archive

Aber auch WinRAR erkennt Nicht-RAR-Dateien als SFX-Archive:

$ rar.exe l somefile.srr
SFX Volume somefile.srr
Gfy
quelle
2
multipart / x-zip ist auch ein gültiger Mimetyp für .zip (PKZIP-Archiv)
Sam Vloeberghs
13
application/x-zip-compressed
Tatsächlich
Dies garantiert Ihnen überhaupt keine zipoder rarDatei. Gemäß den WC3-Spezifikationen wird dies wie folgt interpretiert: "Ich bevorzuge einen application/zip| application/x-rar-compressedInhaltstyp, aber wenn Sie diesen nicht liefern können, ist ein application/octet-stream(Dateistream) ebenfalls in Ordnung."
Wilt
1
Hier ist eine nützliche Liste von MIME-
sstauross
1
Wie in aller Welt könnte multipart/x-zipmöglicherweise gültig sein? Es ist nicht mehrteilig. Die SitePoint-Liste enthält viele ungenaue MIME-Typen und ist bei weitem nicht vollständig. Die offizielle Registrierung für IANA-Medientypen ist nicht zu 100% vollständig (und wird es wahrscheinlich auch nie sein).
Suncat2000
35

Zum Hochladen:

Eine offizielle Liste der MIME-Typen finden Sie bei der Internet Assigned Numbers Authority (IANA) . Entsprechend ihrer Content-TypeListenüberschrift für zipist application/zip.

Der Medientyp für rarDateien ist nicht offiziell bei IANA registriert, aber der inoffizielle häufig verwendete MIME-Wert ist application/x-rar-compressed.

application/octet-streambedeutet so viel wie: "Ich sende Ihnen einen Dateistream und der Inhalt dieses Streams ist nicht angegeben" (es ist also wahr, dass es sich auch um eine zipoder eine rarDatei handeln kann). Der Server soll den tatsächlichen Inhalt des Streams erkennen.

Hinweis: Beim Hochladen ist es nicht sicher, sich auf den im Content-TypeHeader festgelegten MIME-Typ zu verlassen . Der Header wird auf dem Client gesetzt und kann auf einen beliebigen Zufallswert gesetzt werden. Stattdessen können Sie die PHP-Datei-Info- Funktionen verwenden, um den MIME-Typ der Datei auf dem Server zu erkennen.


Zum Download:

Wenn Sie eine zipDatei und nichts anderes herunterladen möchten, sollten Sie nur einen einzigen AcceptHeader-Wert festlegen . Alle zusätzlichen festgelegten Werte werden als Fallback verwendet, falls der Server Ihren im AcceptHeader angeforderten MIME-Typ nicht erfüllen kann .

Gemäß den WC3-Spezifikationen gilt Folgendes :

application/zip, application/octet-stream 

wird interpretiert als: "Ich bevorzuge einen MIME -Typ, aber wenn Sie dies nicht liefern können, ist ein (ein Dateistream) auch in Ordnung".application/zipapplication/octet-stream

Also nur ein einziger:

application/zip

Garantiert Ihnen eine zipDatei (oder eine 406 - Not AcceptableAntwort, falls der Server Ihre Anfrage nicht erfüllen kann).

Verwelken
quelle
5

Sie sollten nicht vertrauen $_FILES['upfile']['mime'], überprüfen Sie den MIME-Typ selbst. Zu diesem Zweck können Sie die fileinfoErweiterung verwenden , die standardmäßig ab PHP 5.3.0 aktiviert ist.

  $fileInfo = new finfo(FILEINFO_MIME_TYPE);
  $fileMime = $fileInfo->file($_FILES['upfile']['tmp_name']);
  $validMimes = array( 
    'zip' => 'application/zip',
    'rar' => 'application/x-rar',
  );

  $fileExt = array_search($fileMime, $validMimes, true);
  if($fileExt != 'zip' && $fileExt != 'rar')
    throw new RuntimeException('Invalid file format.');

HINWEIS: Vergessen Sie nicht, die Erweiterung in php.iniIhrem Server zu aktivieren und neu zu starten:

extension=php_fileinfo.dll
fibriZo raZiel
quelle
0

In einer verknüpften Frage gibt es einen Objective-C-Code, um den MIME-Typ für eine Datei-URL abzurufen. Ich habe eine Swift-Erweiterung basierend auf diesem Objective-C-Code erstellt, um den MIME-Typ zu erhalten:

import Foundation
import MobileCoreServices

extension URL {
    var mimeType: String? {
        guard self.pathExtension.count != 0 else {
            return nil
        }

        let pathExtension = self.pathExtension as CFString
        if let preferredIdentifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil) {
            guard let mimeType = UTTypeCopyPreferredTagWithClass(preferredIdentifier.takeRetainedValue(), kUTTagClassMIMEType) else {
                return nil
            }
            return mimeType.takeRetainedValue() as String
        }

        return nil
    }
}
Wolfgang Schreurs
quelle
-2

Da die Erweiterung möglicherweise mehr oder weniger als drei Zeichen enthält, wird im Folgenden unabhängig von ihrer Länge auf eine Erweiterung geprüft.

Versuche dies:

$allowedExtensions = array( 'mkv', 'mp3', 'flac' );

$temp = explode(".", $_FILES[$file]["name"]);
$extension = strtolower(end($temp));

if( in_array( $extension, $allowedExtensions ) ) { ///

um nach dem letzten '.' nach allen Zeichen zu suchen.

theking2
quelle