PHP - 访问 Web 根目录之外的文件的安全性

标签 php html image .htaccess security

我有一个名为 gallery.php 的 php 文件,它是用户特定图片库的页面。为了安全起见,用户图像存储在网络根目录之外。

为了为每个用户检索适当的文件,我使用了一个 getimage.php 文件,该文件从他们的位置提供图像。总而言之,目录结构如下所示:

  • 用户图片
    • 用户 1
      • user1 的图片列表
    • 用户 2
      • user2 的图片列表
  • public_html
    • 画廊.php
    • getimage.php

getimage.php 的写法如下:

$imgString = realpath('/UserImages/' . $_SESSION['username'] . '/' . $_GET['img']);
if (!startsWith($imgString, '/UserImages/' . $_SESSION['username'] . '/')
    || !(endsWith(strtolower($imgString), '.jpg') || endsWith(strtolower($imgString), '.jpeg')))
{
    header('HTTP/1.0 403 Forbidden');
    die();
}

$img = file_get_contents($imgString);
header("Content-type: image/jpeg");
echo($img);
exit();

我依靠 $_GET['img'] 来确定要检索哪个图像,这可能是一个安全漏洞(也是一个主要漏洞)。我可以预见到目录遍历攻击,因此使用了真实路径,尽管我确信可能存在我未包含在该脚本中的其他攻击途径。

出于这个原因,我更愿意将 getimage.php 移动到 webroot 之外,或者至少防止它被直接访问(并且只能通过 gallery.php,其中发送的 img 参数完全在我的控制之下) .

然而,每当我尝试将 getimage.php 移出 public_html 时,即使我在 gallery.php 中要求或包含,我似乎也无法再调用它。我访问 getimage.php 的方式是这样做的:

<img src=getimage.php?img=IMG_FILENAME.jpg />

但是如果我将它移出 public_html 目录,getimage.php 将会失败。

那么,长话短说:我需要做什么来防止 getimage.php 被滥用?

最佳答案

最安全的方法是不使用 $_GET['img'] 传递图片 url,而是发送对图片的引用。

问题

首先,$_GET['img'] 可以是有害代码的任何外部 URL,使用 file_get_contents 可以直接下载它。

其次,任何人都可以使用您的服务器作为免费图像代理,只需在他自己的网站上使用以下 url:

<img src="http://www.yourwebsite.com/getimage.php?img=[external_image_url]">

正确的方法

1) 在您的数据库中创建包含用户图像路径的图像表。当您想要提供图像时,传递图像 ID 而不是 url:

$imageID = $_GET['image'];
.... your sql query here to retrieve the image....
$img = file_get_contents($imgString);

2) 因为您知道 $_GET['image'] 是一个 ID,所以您可以轻松地对其进行清理:

if( !preg_match("/^[0-9]+$/", $_GET['image']) )
{
    header('HTTP/1.1 404 Not Found');
    exit();    
}

3) 在你的 SQL 中不要忘记使用准备好的语句:

$sql = "SELECT image_path from images WHERE id = ?";

4) 只应将图像移动到文档根文件夹之外,如果您也想将 getimage.php 移动到根文件夹之外,您可以使用 Apache Alias 来提供它。在 Apache 虚拟主机配置中,您可以使用:

Alias /getimage.php /path/to/getimage.php

5) 使用 404 not found 而不是 403 forbidden,不要给攻击者你捕获他的 Action 的暗示。

关于PHP - 访问 Web 根目录之外的文件的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27613379/

相关文章:

php - 检测 .htaccess 中对 php_value/php_flag 的支持以抑制错误 - PHP CGI 模式 - mod_php

php - 获取mysql查询中所有匹配的数组?

php 正则表达式去除不需要的 html 属性

python - 当使用 Gimp 手动预处理图像时,使用 Tesseract-OCR 的图像到文本识别比我的 Python 代码更好

image - 如何避免 Matlab 中的图像显示伪影?

jquery - 为链接剪下一张人脸

用于合并单元格的 PHPExcel setAutoSize

php - 使用 Square Connect ChargeResponse 对象时遇到问题

html - Google Chrome 中页脚 <div> 后的空白

javascript - 在平滑传输和颜色变化中调整拨动开关