清理
$_GET['']
请求的最佳方法是什么?我想只允许从一个目录下载文件。
$baseDir = "/home/html/xy.com/public_html/downloads/";
$path = realpath($baseDir . $_GET['file']);
下一步是什么?
这是我在你的台词之后要做的事情:
if (dirname($path) === $baseDir) {
//Safe
}
基本上,在发送任何文件之前检查一下文件实际上是否位于您支持的路径中。请注意,您还必须在文件名之前添加您自己的
/
(在 $path
中)并将其从 $baseDir
定义中删除,因为 dirname()
不会留下尾随路径分隔符。
与其事后检查是否存在相对路径片段,不如立即删除它们更容易。获取值后立即使用
basename()
即可:
$baseDir = "/home/html/xy.com/public_html/downloads/";
$path = realpath($baseDir . basename($_GET['file']));
这已经保证它不能从您的基本目录向上或向下移动。
在将
$_GET
分配给 $path
之前,您需要清理该值。
我建议使用 PHP 自己的清理函数(http://php.net/manual/en/function.filter-input.php 和 http://php.net/manual/en/filter.filters.sanitize)。 php)。需要 PHP >= 5.2.0,
您可以组合
basename()
和 realpath()
功能。我发现像 this 做 basename(realpath("allowed/" . $filename))
这样的例子,但在我看来,这样真实路径甚至会检查是否存在不允许的文件。所以我会分三步进行:
$tha_basename=basename($_GET["fname"]); /* takes only file name and ext from get */
$tha_realpath=realpath("allowed/" . $tha_basename); /* checks for file existing in the allowed location */
$tha_basename=basename($tha_realpath); /* finaly this takes only file name and ext from the real location */