【问题标题】:Invalid file extension when uploading from Sharepoint从 Sharepoint 上传时文件扩展名无效
【发布时间】:2012-05-01 15:53:35
【问题描述】:

我有一个使用文件上传的网站正在运行。一切正常,除了其中一位用户。他们使用 IE8 将文件从他们的 SharePoint 服务器上传到网站。当我查看 PHP 中的 $_FILES 变量时,'name' 键看起来像这样:

somefilename[1]

代替

somefilename.pdf

然后上传被阻止,因为不允许扩展。有没有人曾经处理过/见过这个?它看起来像一个临时名称,或隐藏的文件扩展名。

编辑:

你们中的一些人请求了 $_FILES 变量:

[Filedata] => Array
    (
        [name] => Algemene%20Voorwaarden%20Corporate%20Services%202011[2]
        [type] => application/octet-stream
        [tmp_name] => /tmp/phps19zye
        [error] => 0
        [size] => 148021
    )

这应该是一个 PDF 文件。我需要扩展,不仅出于安全原因,[type] 更适合于此,而且还用于演示和功能。我需要为文件类型显示正确的图标,并单独处理图像。

HTML 表单只是一个基本的测试表单:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <form action="uploadtest3.php" method="post" enctype="multipart/form-data">
            <input type="file" name="file_upload" id="file_upload" />
            <br /><input type="submit" value="Uploaden" />
        </form>
    </body>
</html>

PHP 文件如下:

$targetFolder = '/uploadtests/uploads3';

if (!empty($_FILES)) {
    $tempFile = $_FILES['file_upload']['tmp_name'];
    $targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
    $targetFile = $targetPath . $_FILES['file_upload']['name'];

    move_uploaded_file($tempFile,$targetFile);
        echo "OK";
}

【问题讨论】:

  • 你能print_r($_FILES); 并粘贴输出吗?最好能看到上传表单的标记。
  • 您绝对需要扩展吗?你能启发式地嗅探文件类型吗?

标签: php html sharepoint file-upload


【解决方案1】:

简介

以前见过这个问题,但不确定是什么原因造成的。我什至不想将其称为错误,因为 some files extension can be intentionally removed or altered 出于恶意目的。

最多important thing is validating file properly,不用担心文件是否有扩展名

原因:

  • File Extension Can easily be faked 如果您的应用程序仅依赖文件扩展名进行验证,那就太糟糕了

  • $_FILES ['file_upload']['type'] 将为所有没有扩展名的文件返回 application/octet-stream,因此它也不是验证选项

  • 既然是浏览器问题,那么它就是Client Related Problem,所以你没有任何控制权。如果你能做到这一点,你肯定会增加用户体验

简单补丁

解决方案非常简单。您只需使用FILEINFO 验证您的文件并修复上传文件的任何扩展问题。

您还需要根据 Mime 类型验证所有上传的文件...并删除所有无效文件。

概念证明

$allowedTypes = array (
        "pdf" => "application/pdf" 
);

$pathFinal = "final";
$pathTemp = "temp";
try {
    if (! empty ( $_FILES )) {
        $tempFile = $_FILES ['file_upload'] ['tmp_name'];
        $fileName = $_FILES ['file_upload'] ['name'];
        $destinationTemp = $pathTemp . DIRECTORY_SEPARATOR . $fileName;
        $destinationFinal = $pathFinal . DIRECTORY_SEPARATOR . $fileName;
        /**
         * Move To tempary File
         */
        move_uploaded_file ( $tempFile, $destinationTemp );

        $fileMime = mimeInfo ( $destinationTemp );
        $key = array_search ( $fileMime, $allowedTypes );

        /**
         * Validate Mime Type
         */
        if (empty ( $key )) {
            unlink ( $destinationTemp );
            throw new Exception ( "File Type not Supported" );
        }

        /**
         * Fix Extention Issues
         */
        $ext = pathinfo ( $destinationTemp, PATHINFO_EXTENSION );

        if (empty ( $ext )) {
            $destinationFinal .= "." . $key;
        }

        /**
         * Transfer File to Original Location
         */
        copy ( $destinationTemp, $destinationFinal );
        unlink ( $destinationTemp );

        echo "OK";
    }
} catch ( Exception $e ) {
    echo "ERROR :", $e->getMessage ();
}

使用的功能

function mimeInfo($file) {
    return finfo_file ( finfo_open ( FILEINFO_MIME_TYPE ), $file );
}

【讨论】:

  • 这可能是一个很好的解决方案,但不幸的是服务器还没有更新到 PHP 5.3,所以我无法部署它。但是,PHP 函数 'mime_content_type' 是 PHP 5.2 的替代方案,它返回 mime 类型 application/pdf,而不是八位字节流。感谢您的帮助。
  • 不客气......我不知道你在哪里使用 PHP 5.2 ......很高兴知道我能够提供帮助
【解决方案2】:

somefilename 似乎是一个数组。您的用户是否选择了多个要上传的文件?您需要限制允许上传的文件数量,或者捕获数组并正确处理。您还可以确保将 Sharepoint 设置为 allow multiple file uploads

另外,我找到了有关IE8 passes the file 上传到服务器的方式的信息。源文章指出:

此外,“上传文件时包括本地目录路径”URLAction 已针对 Internet 区域设置为“禁用”。此更改可防止潜在敏感的本地文件系统信息泄露到 Internet。 例如,Internet Explorer 8 现在只提交文件名 image.png,而不是提交完整路径 C:\users\ericlaw\documents\secret\image.png。

这意味着,如果您的代码(或 Sharepoint)希望通过 PATH_SEP 将文件夹结构与文件名分隔开,那么对于 IE8,它显然会失败。

【讨论】:

  • 它看起来像一个数组,但文件上传得很好,只是文件名错误。另外,我无法捕获数组,文件上传不允许传递数组。我会让系统管理员研究将 SharePoint 设置为(禁止)允许多个文件上传。 IE8 信息并不真正适用。反正我不需要完整路径,我认为其他浏览器也不会传递完整的文件名。
【解决方案3】:

您不应该按扩展名而是按 Mime 类型检查文件类型。使用变量$_FILES["uploaded_file"]["type"] 获取 Mime 类型。

这样用户就不能用奇怪的 ASCII 字符篡改扩展名,并且你知道什么文件是什么可靠的。

【讨论】:

  • 查看附加信息。由于其他原因,我也需要文件扩展名。
  • @Bas 你应该检查它为什么发布application/octet-stream,它应该是application/pdf。如果你能解决这个问题,你的问题就会得到解决。依赖文件扩展名非常危险,真的很容易被锻炼。
猜你喜欢
  • 2014-04-06
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 2020-12-10
  • 2012-06-15
相关资源
最近更新 更多