2

在使用 Acunetix 扫描我们的代码以查找漏洞后,我们遇到了以下脚本的问题:

“针对域 hit0yPI7kOCzl.bxss.me 发起了一个 HTTP 请求,这表明该脚本容易受到 SSRF(服务器端请求伪造)的攻击。”

我怎样才能防止这种情况?

<?php
$filename = strip_tags($_GET['url']);

if (substr($filename,0,4) !== 'http') {
    die("Need a valid URL...");
}

$ext = pathinfo($filename, PATHINFO_EXTENSION);


switch ($ext) {
    case "gif":
        header('Content-Type: image/gif');
        readfile($filename);
        break;
    case "png":
        header('Content-Type: image/png');
        readfile($filename);
        break;
    case "jpg":
    default:
        header('Content-Type: image/jpeg');
        readfile($filename);
        break;
}
?>
4

1 回答 1

3

如果您遇到的问题是您的服务器将尝试从任何传递的 url 获取数据,则来源。鉴于它有http://google.com内部url参数,脚本将响应实际的谷歌网站内容。

为什么它不好?例如,这可能会被利用来绕过您的防火墙设置、访问服务器的内部网络或污染套接字连接,因此您的服务器将无法连接或连接到并且将变得无响应。

首先,您应该考虑是否真的想用 PHP 提供静态文件。这个责任很可能会委托给 Web 服务器。它甚至可以使用当前的网络服务器从 3rd 方网站“服务”静态,因此您应该认真考虑摆脱该代码。

如果你 100% 确定你想在这种情况下使用 PHP,你应该在你的代码中添加限制。

  1. 添加域白名单,以便只允许在url变量内部使用受信任的域列表;
  2. 不要处理带有未知扩展名的文件。

在这种情况下,代码将如下所示:

<?php

$whitelist = [
    'some.whitelisted.com',
    'other.whitelisted.com'
];

$extensionMap = [
    'gif'  => 'image/gif',
    'png'  => 'image/png',
    'jpg'  => 'image/jpeg',
    'jpeg' => 'image/jpeg'
];

$filename = strip_tags($_GET['url']);

$host = parse_url($filename, PHP_URL_HOST);

if(empty($host) || !in_array($host, $whitelist)) {
    header('HTTP/1.1 404 Not Found');
    exit;
}

$ext = pathinfo($filename, PATHINFO_EXTENSION);

if(!isset($extensionMap[$ext])) {
    header('HTTP/1.1 404 Not Found');
    exit;
}

header(sprintf('Content-Type: %s', $extensionMap[$ext]));
readfile($filename);
于 2016-03-14T13:22:49.827 回答