每个文件都有与之关联的MIME类型吗?

4

我最近实施了一个安全系统,我们会检查MIME类型和文件扩展名是否在可接受的列表中。如果扫描的文件具有此列表中的MIME和扩展名,则我们继续进行。下面是我们扫描文件的函数。 ALLOWED_EXTENSIONSALLOWED_MIME_TYPES只是字符串,例如“ txt,pdf,jpeg ...”。

我假设您知道MIME类型是什么以及它们如何工作,但最近我们收到了没有任何MIME类型的PDF上传。顺便说一句,这段代码大多数时候都有效。我见过PDF、图像、文本文件等都可以通过。

一个文件完全没有MIME类型是可能的吗?

 /**
 * scan the file before upload to do our various security checks
 *
 * @param  tmpName    the file's location in /tmp, used for MIME type scan
 * @param  name       the filename as it was uploaded, used for extension scan
 * @param  oid        the order id, passed along to notifyStaffIllegalFileUpload() if email needs to be sent
 * @return            true on success, error string on failure
 */
function scanFile($tmpName, $name, $oid) {
    global $_email;

    // get lists from config
    $allowedExtensions = explode(",", ALLOWED_EXTENSIONS);
    $allowedMIMEs = explode(",", ALLOWED_MIME_TYPES);

    // get extension
    $ext = pathinfo($name, PATHINFO_EXTENSION);

    // get MIME type
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $tmpName);
    finfo_close($finfo);

    // check against allowed
    if (!in_array(strtolower($ext), $allowedExtensions) || !in_array(strtolower($mime), $allowedMIMEs)) {
        capDebug(__FILE__, __LINE__, "Order #" . $oid . " - A user attempted to upload a file with extension '" . $ext . "' and MIME type '" . $mime . "'. The attempt was blocked.\n", "/tmp/file_errors.log");
        $_email->notifyStaffIllegalFileUpload($oid, $name, $ext, $mime);
        return "Our security systems detected an illegal file type/mime type. The file upload was cancelled.";
    }

    return true;
}

2
content-type是对接收端提示正在发送的内容的一种方式。并不意味着必须提供或准确无误。在某些系统上(咳咳,Windows),文件类型完全由其文件扩展名确定。如果上传一个没有扩展名的文件,则无法正确设置任何content-type,除了可能是通用类型,如application/octet-stream。 - Marc B
这个问题以及我从同事那里得到的其他建议,让我找到了答案。使用 MIME 类型进行安全检查是不可行的。没有商量的余地。 - Jeremy Muckel
2
它们不是安全检查,这是确定的。但它们确实告诉你文件的外层是它所声称的。但仅仅说“这确实是一个PDF”是不够的。PDF本质上是一个PostScript程序,也可以包含其他“活动”的内容。 - Marc B
2个回答

1
除了OP自己的答案(并没有试图回答实际问题),这个问题并不是很明确。内容类型application/octet-stream是通用的,因此可以分配给每个文件。另一方面,显然可以创建没有有用内容类型的文件;你如何用MIME类型标记dd if=/dev/urandom的输出?在这个问题的框架下,我倾向于“不可能”——无法为每个可能的文件分配一个有用的MIME类型。

0
经过几天的研究和咨询,问题的答案似乎不太相关,因为作为安全功能检查 MIME 类型在第一时间是不可行的。不同操作系统上 MIME 类型存在太多问题,不同应用程序以不同方式保存文件,有些文件根本没有 MIME,最后,恶意用户或程序可能会更改扩展名和 MIME。结束。

您实际上没有关闭问题,因此它仍在需要回答的问题队列中。如果您不想接受这里的任何答案,也许您真的想删除您的问题?当您以作者身份登录时,在实际问题下方的[编辑]链接旁边有一个“删除”链接。我认为这有点含糊不清,也许可以接受并保留。 - tripleee
是的,你说得对,我需要关闭它。我正在尝试弄清楚如何关闭它。 - Jeremy Muckel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接