防止mime伪装上传php上传

时间:2008-09-24 14:51:52

标签: php security

有没有办法防止有人在文件上传时伪造mime类型然后运行php / exe / etc ......

我必须使文件上载目录可写和可执行,以便可以存储文件,但这允许任何人在之后运行脚本。我可以做的一件事是将随机数据添加到文件名中,这样他们就无法猜出文件名(因为他们仍然无法从目录中读取以获取列表)。

我第一次使用php上传文件,我正试图涵盖所有安全问题。

4 个答案:

答案 0 :(得分:2)

Web浏览器不应访问文件上载目录。即不允许有人上传文件,比如“remove_all_my_files.php”,然后通过提供网址在您的系统上执行,例如“http://xample.com/uploads/remove_all_my_files.php”。

答案 1 :(得分:0)

$_FILES中的信息始终来自客户端,因此您要做的是接受该文件并在服务器上进行扫描。我建议使用finfo,这是一个PHP扩展,它很容易:

<?php
// example :-)
$finfo = finfo_open(FILEINFO_MIME);
echo finfo_file($finfo, '/path/to/your/upload/file);
finfo_close($finfo);
?>

如果您不喜欢程序性,还有一个OO界面。

如果finfo不是一个选项,您可以使用unix命令file进行检查。

此外,许多人建议通过包装器提供文件。我对这个问题很感兴趣,它可以是一个解决方案,但它远非理想,因为a)文件仍在你的服务器上,而b)提供这样的文件是很昂贵的。

答案 2 :(得分:0)

不要直接提供文件。将上传保留在无公共访问位置。从文件读取,输出缓冲区允许下载。

这是基本想法:

function ReadAndOutputFileChunked ($filename) { 
    $chunksize = 1*(1024*1024); // how many bytes per chunk 
    $buffer = ''; 
    $handle = @fopen($filename, 'rb'); 
    if ($handle === false) { 
        return false; 
    } 
    while (!feof($handle)) { 
        $buffer = @fread($handle, $chunksize); 
        print $buffer; 
    } 
    return @fclose($handle); 
}

header("Content-type: application/octet-stream");
ReadAndOutputFileChunked('/private/path/to/upload/files/' . $nameOfFile);

答案 3 :(得分:-1)

在我的Apache Web服务器配置中,我不相信实际的文件内容决定了文件是否作为脚本运行。通过匹配文件结尾来确定是将文件显示为文本还是图像格式,或者将其作为脚本运行。

例如,apache配置文件中的指令,

的httpd.conf

AddType application / x-httpd-php .php

告诉服务器运行以.php结尾的文件作为php脚本运行。因此,请确保没有任何上传的文件以.php结尾或任何其他脚本可执行文件结尾或任何结束您用于包含文件的文件保存。