php - 防止 Drupal 7 中的任意文件下载
问题描述
Drupal 漏洞:
可以下载网络服务器可读的任何文件。问题在于 Web 应用程序提供的文件下载功能无法正确验证用户发送的指定要下载哪个文件的参数。这种漏洞最常见的用途之一是恢复应用程序的源代码以及可能包含其他服务密码的配置文件。
开发示例:
在 drupal 中创建的申请表允许用户上传文档。
如果提交时表单不完整,用户将被重定向回表单以完成缺失的详细信息。如果文档已上传,此表单将在名为 zivotopis 的隐藏 HTML 输入字段中包含上传简历的完整路径。表单正确填写并提交后,服务器执行如下代码:
<?php
if($_POST['zivotopis']) {
// Create managed File object and associate with Image field.
$oldFilepath = base64_decode($_POST['zivotopis']);
if(strpos($oldFilepath,'.doc')) $extension = '.doc';
else if(strpos($oldFilepath,'.docx')) $extension = '.docx';
else if(strpos($oldFilepath,'.pdf')) $extension = '.pdf';
$newFilename = strtoupper($_POST['field_item_last_name_label']).'_'.
$_POST['field_item_first_name_label'].'_CV'.$extension;
$newFilename = str_replace(" ", "-", $newFilename);
$newFilepath = drupal_realpath(dirname(__FILE__))."/tmp/".$newFilename;
copy($oldFilepath, $newFilepath);
// ...
可以看出,zivotopis 中提供的 base64 编码路径将在调用 copy() 时用作 $oldFilePath。因此,恶意用户可以提供任意文件路径,并且该文件将以新名称复制到 webroot。
当我提交表单但拦截 HTTP 请求时。使用 base64 编码格式的 ./sites/default/settings.php 将名为 zivotopis 的新 POST 参数添加到请求中,它应该类似于以下内容:
...
-----------------------------7667788801930707109771964994
Content-Disposition: form-data; name="zivotopis"
Li9zaXRlcy9kZWZhdWx0L3NldHRpbmdzLnBocA==
-----------------------------7667788801930707109771964994
....
访问上传的文件 url 后,它包含数据库凭据!
我的问题是
如何防止不接受用户控制的文件路径?
或者为什么不禁用 PHP eval() 函数?
关于如何遵循 Drupal Security Glydeness 的任何想法
解决方案
Drupal 提供公共和私有文件系统。对于每个文件字段(在网络表单或内容类型设置中),您可以选择应该使用哪一个。此外,在 Media -> File system 下,您可以指定这两个系统的路径。
我没有使用私有系统,但我猜 Drupal 会将 .htaccess 文件放在私有文件根目录中,防止直接访问位于那里的文件并通过 PHP 提供文件,并检查当前用户的访问权限。
同样,我不是 100% 确定,但应该可以将私有目录完全设置在站点 Web 根目录之外(上图)(Web 服务器无法访问),因此即使是 .htaccess 保护也不需要。
推荐阅读
- android - VS Xamarin.Forms (Android):使用 Xam.Plugin.Media 拒绝相机和存储访问
- python - 如何修复 Valueerror:烧瓶中的负查找值
- java - Spring 安全性 + 从头开始 java 扩展
- r - 如何识别脚本中最耗时的部分
- ruby-on-rails - 如何在 Active Admin 中为 has_many 关系加入的新资源创建表单
- excel - 将图表从一张纸复制到另一张纸到特定单元格。在继续下一个图表之前,更改图表 VBA excel 的 X 和 Y 边界
- parse-platform - 如何使用 Parse findObjectsInBackground 获取 objectID
- java - 如何为 JMeter 中的所有线程创建一个 Java 对象?
- azure-data-factory - 此表是无主索引 (NOPI) 表。”在带有 PI 的 Teradata 表上
- python - 在 CNN 模型中使用 Tf-idf 作为特征