我有一个脚本可以让用户将文本文件(PDF 或 doc)上传到服务器,然后计划将它们转换为原始文本。但是在文件被转换之前,它是原始格式,这让我担心病毒和各种讨厌的东西。
我需要做些什么来最大程度地降低这些未知文件的风险。如何检查它是否干净,或者它是否是它声称的格式并且它不会使服务器崩溃。
正如我对 Aerik 的评论,但这确实是问题的答案。
如果您有 PHP >= 5.3,请使用finfo_file()
. 如果您有旧版本的 PHP,您可以使用mime_content_type()
(不太可靠)或从 PECL 加载 Fileinfo 扩展。
这两个函数都返回文件的 mime 类型(通过查看其中的数据类型)。对于 PDF,它应该是
text/pdf
对于word doc,它可能是几件事。一般应该是
application/msword
如果您的服务器正在运行 *nix,请确保您保存的文件不可执行。更好的是:将它们保存到 Web 服务器无法访问的文件夹中。您仍然可以编写代码来访问这些文件,但请求网页的人根本无法访问它们。
如果您曾经在服务器上打开或执行过任何用户上传的文件,那么您应该预料到您的服务器现在已受到威胁。
即使是 JPG 也可以包含可执行的 php。如果您include
或require
文件以任何方式在您的脚本中,那也可能危及您的服务器。您在网络上偶然发现的图像是这样的……
header('内容类型:图片/jpeg'); header('Content-Disposition: inline; filename="test.jpg"'); echo file_get_contents('/some_image.jpg'); echo '<?php phpinfo(); ?>';
...您可以像这样保存并重新托管在自己的服务器上...
$q = $_GET['q']; // 假装这暂时被清理了 header('内容类型:'.mime_content_type($q)); header('Content-Disposition: inline; filename="'.$_GET['q'].'"'); 包括$q;
...将phpinfo()
在您的服务器上执行。然后,您的站点用户可以简单地将图像保存到他们的桌面并使用记事本打开它以查看您的服务器设置。简单地将文件转换为另一种格式将丢弃该脚本,并且不应触发附加到文件的任何实际病毒。
最好在上传时进行病毒搜索。您应该能够对检查器执行内联系统命令并解析其输出以查看它是否找到任何内容。无论如何,您的网站用户都应该检查他们下载的文件。
否则,即使是病毒感染用户上传的文件就在您的服务器上,也不应该损害任何东西......据我所知。
嗯 - 恕我直言,您不必担心文档类型或其他东西;如果您使用一个好的转换器来转换为原始文本,那么这个转换器应该在不使服务器崩溃的情况下进行这些检查。
从您的客户端计算机知道,服务器应始终受到保护以免受病毒和攻击 - 因此在处理新上传的文件之前要对其进行检查。
我从来没有见过一个网络应用程序自己做这些检查——你有吗?
恕我直言,直到有东西试图执行它,它只是一个文件。但是,您绝对可以检查(但不要依赖,如下所述)文件扩展名,还可以研究文件格式以查看文件头中是否有任何可以验证的特征字节序列。
如果您正在查看 PDF,除了获取防病毒软件并祈祷它恶意捕获已形成的 PDF 之外,您无能为力。
转换软件通常不是针对的,所以如果你只是转换它并查看文本格式输出,你应该会更安全一些。
哦,你担心服务器。只是不要执行上传的文件...
在上传的文件中,有 3 种安全方式: 最好:将文件放在另一台服务器中 最安全的一种更好:将它们放在您的 WWW 文件夹之外,这意味着没有人可以通过 URL 访问它们,您必须使用 readfile() 或 get_content 来阅读和最后显示文件:将文件放在 WWW 中并在文件夹中使用 .htaccess,以防止其他人执行文件或放置未知文件,这就是我通过上传文件所做的;将它们放在Web根目录之外并重命名它们甚至将假名保存在数据库中并通过算法创建文件的真实名称。
在 web 根目录之外上传文件后,您可以像我在这里一样访问它。这里是文件 caleed getfile.php 的内容:
<?php
define('DS', DIRECTORY_SEPARATOR);
//fake name of file
$uniqueid = $_GET['uniqueid'];
//file extension
$ext = $_GET['ext'];
if (isset($_GET['dir']))
//check address doenot contain ..
$addrss = str_replace('..', '_', $_GET['dir']);
$baseaddress = '..' . DS . 'foldername outside of web root';
if ((isset($_GET['uniqueid']) and strlen($uniqueid) === 32) and ( isset($_GET['ext']) and strlen($ext) === 3 )) {
$path = $baseaddress . DS . $addrss . DS;
$path .= md5($uniqueid . $uniqueid . $uniqueid . $ext.'*#$%^&') .'.'. $ext;
if (file_exists($path)) {
//you can check for all your accessible extension i just use for img
switch ($ext) {
case 'jpg':
$content_type = 'image/jpeg';
break;
case 'png':
$content_type = 'image/png';
break;
case 'gif':
$content_type = 'image/gif';
break;
}
header('Content-type: ' . $content_type . ' ');
$file = readfile($path);
}
在文件 src 或您需要显示文件的每个位置执行此操作(这是为我的图像):
<img src="/getfile.php?uniqueid=put fake file name here&ext=put extension here&dir=put rest of file address here" >
希望对您有所帮助。不要犹豫,提出更多问题