首页 > 解决方案 > 防止 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 的任何想法

标签: phpdrupaldrupal-7drupal-services

解决方案


Drupal 提供公共和私有文件系统。对于每个文件字段(在网络表单或内容类型设置中),您可以选择应该使用哪一个。此外,在 Media -> File system 下,您可以指定这两个系统的路径。

我没有使用私有系统,但我猜 Drupal 会将 .htaccess 文件放在私有文件根目录中,防止直接访问位于那里的文件并通过 PHP 提供文件,并检查当前用户的访问权限。

同样,我不是 100% 确定,但应该可以将私有目录完全设置在站点 Web 根目录之外(上图)(Web 服务器无法访问),因此即使是 .htaccess 保护也不需要。


推荐阅读