验证文件的扩展名足以知道该文件没有隐藏病毒(或可以渗透到我的服务器的东西)吗?
Is verifying a file's extension enough to know that the file isn't hiding a virus (or something that can infiltrate my server)?
我正在开发一个用户可以上传“.docx”文件的系统。验证它的扩展名足以知道这个“.docx”文件没有被感染吗?
这是我的上传 PHP 代码:
<?php
session_start();
include("connection.php");
include("functions.php");
// Just to validate the user
$user_data = check_login($con);
include("connectionPostsDB.php");
if (isset($_POST['submit'])){
$title = $_POST['title'];
$tag = $_POST['tag'];
$description = $_POST['description'];
$file = $_FILES['file'];
$fileName = $_FILES['file']['name'];
$fileTmpName = $_FILES['file']['tmp_name'];
$fileSize = $_FILES['file']['size'];
$fileError = $_FILES['file']['error'];
$fileType = $_FILES['file']['type'];
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt)); //here I get the actual file's extension (I hope xD)
$allowed = array('docx');
if(in_array($fileActualExt, $allowed)){
if($fileError === 0){
if($fileSize < 1000000){
$fileNameNew = uniqid('', true).".".$fileActualExt;
$fileDestination = '../imgs/posts/'.$fileNameNew;
move_uploaded_file($fileTmpName, $fileDestination);
$query = "INSERT INTO posts (title, descr, imgname, tag)
VALUES ('".$title."','".$description."','".$fileNameNew."','".$tag."')";
mysqli_query($postcon, $query);
echo 'File successfully uploaded';
}
else {
echo 'Your file is too big.';
}
}
else {
echo 'There was an error uploading your file.';
}
}
else {
echo 'This type of file not allowed.';
}
}
那么,我检查文件的扩展名是否足以防止某些用户将某些 php 代码放入我的服务器(或执行某些操作以从服务器获取信息)?
不,仅仅检查文件扩展名是不够的,因为我们可以为任何文件类型设置 .docx
扩展名。
我们还应该检查更多内容,例如:
- 文件的 mime 类型是预期的吗?
- 文件大小是否足够合理。例如,如果有人上传了一个 25 GB 的 docx 文件,那么即使它是一个有效的 docx 文件,您的服务器也可能会崩溃。
- 理想情况下,您不应在任何生产服务器中上传任何文件,而应在任何存储提供商(如 AWS 的 s3 存储桶)中上传。因此,即使该文件是可执行文件,它也不会在您的服务器中执行。它被上传到另一个服务器,该服务器经过优化可以处理文件。
还有很多这样的事情需要考虑。
不,仅检查扩展名是不够的,但主要问题是您所说的 safe 的确切含义。
您显示的代码仅将文件存储在您的服务器上(在服务器生成的名称下),然后在数据库中发布它的存在。这些东西 本身 都不会有危险,即使该文件包含黑死病的数字等价物。
但是让我们先退一步;您的 SQL 查询非常 不安全 ,尽管这与上传的文件无关。当您以这种方式创建查询时,您应该阅读准备好的语句,因为您的整个网站都对 SQL 注入敞开大门。
现在,回到主题:
为了让 .docx
文件成为它应有的样子,您至少可以探索两件事。
据我所知,docx
格式实际上只是一个 .zip
文件,其中包含一些 .xml
文件。 PHP 理解这两种格式,因此您可以尝试解压缩它的内容,查看它是否包含您期望的文件类型,包括 xml
(s),然后查看那些 XML文件是可解析的。
您可以将上传的文件提供给病毒扫描程序
这两种方法都不是完全证明,但它们都会稍微说明情况,让您(更具体地说,您的算法)做出更明智的决定。
现在说说我所说的“你所说的安全到底是什么意思”。您在此处执行的操作(仅重命名和存储文件以及将文本写入数据库)基本上是非常安全的。
但我想在该数据库的另一端,有人或其他东西读取同一个数据库 table,并允许某人打开和/或下载该文件。现在 该操作 实际上有很多安全隐患。
现在,如果该数据库只能通过您的应用程序查看,那么理论上您可以放弃所有责任并说“此文件是由上帝知道是谁匿名上传的,就好像它是由未知发件人到达您的电子邮件垃圾文件夹一样对待”。但是,如果您要承担任何级别的责任(无论是隐含的还是字面上的),您都必须在您满意的程度上对其进行验证table。
我正在开发一个用户可以上传“.docx”文件的系统。验证它的扩展名足以知道这个“.docx”文件没有被感染吗?
这是我的上传 PHP 代码:
<?php
session_start();
include("connection.php");
include("functions.php");
// Just to validate the user
$user_data = check_login($con);
include("connectionPostsDB.php");
if (isset($_POST['submit'])){
$title = $_POST['title'];
$tag = $_POST['tag'];
$description = $_POST['description'];
$file = $_FILES['file'];
$fileName = $_FILES['file']['name'];
$fileTmpName = $_FILES['file']['tmp_name'];
$fileSize = $_FILES['file']['size'];
$fileError = $_FILES['file']['error'];
$fileType = $_FILES['file']['type'];
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt)); //here I get the actual file's extension (I hope xD)
$allowed = array('docx');
if(in_array($fileActualExt, $allowed)){
if($fileError === 0){
if($fileSize < 1000000){
$fileNameNew = uniqid('', true).".".$fileActualExt;
$fileDestination = '../imgs/posts/'.$fileNameNew;
move_uploaded_file($fileTmpName, $fileDestination);
$query = "INSERT INTO posts (title, descr, imgname, tag)
VALUES ('".$title."','".$description."','".$fileNameNew."','".$tag."')";
mysqli_query($postcon, $query);
echo 'File successfully uploaded';
}
else {
echo 'Your file is too big.';
}
}
else {
echo 'There was an error uploading your file.';
}
}
else {
echo 'This type of file not allowed.';
}
}
那么,我检查文件的扩展名是否足以防止某些用户将某些 php 代码放入我的服务器(或执行某些操作以从服务器获取信息)?
不,仅仅检查文件扩展名是不够的,因为我们可以为任何文件类型设置 .docx
扩展名。
我们还应该检查更多内容,例如:
- 文件的 mime 类型是预期的吗?
- 文件大小是否足够合理。例如,如果有人上传了一个 25 GB 的 docx 文件,那么即使它是一个有效的 docx 文件,您的服务器也可能会崩溃。
- 理想情况下,您不应在任何生产服务器中上传任何文件,而应在任何存储提供商(如 AWS 的 s3 存储桶)中上传。因此,即使该文件是可执行文件,它也不会在您的服务器中执行。它被上传到另一个服务器,该服务器经过优化可以处理文件。
还有很多这样的事情需要考虑。
不,仅检查扩展名是不够的,但主要问题是您所说的 safe 的确切含义。
您显示的代码仅将文件存储在您的服务器上(在服务器生成的名称下),然后在数据库中发布它的存在。这些东西 本身 都不会有危险,即使该文件包含黑死病的数字等价物。
但是让我们先退一步;您的 SQL 查询非常 不安全 ,尽管这与上传的文件无关。当您以这种方式创建查询时,您应该阅读准备好的语句,因为您的整个网站都对 SQL 注入敞开大门。
现在,回到主题:
为了让 .docx
文件成为它应有的样子,您至少可以探索两件事。
据我所知,
docx
格式实际上只是一个.zip
文件,其中包含一些.xml
文件。 PHP 理解这两种格式,因此您可以尝试解压缩它的内容,查看它是否包含您期望的文件类型,包括xml
(s),然后查看那些 XML文件是可解析的。您可以将上传的文件提供给病毒扫描程序
这两种方法都不是完全证明,但它们都会稍微说明情况,让您(更具体地说,您的算法)做出更明智的决定。
现在说说我所说的“你所说的安全到底是什么意思”。您在此处执行的操作(仅重命名和存储文件以及将文本写入数据库)基本上是非常安全的。
但我想在该数据库的另一端,有人或其他东西读取同一个数据库 table,并允许某人打开和/或下载该文件。现在 该操作 实际上有很多安全隐患。
现在,如果该数据库只能通过您的应用程序查看,那么理论上您可以放弃所有责任并说“此文件是由上帝知道是谁匿名上传的,就好像它是由未知发件人到达您的电子邮件垃圾文件夹一样对待”。但是,如果您要承担任何级别的责任(无论是隐含的还是字面上的),您都必须在您满意的程度上对其进行验证table。