我在root中有这个代码,当用户点击链接
时自动保存图像文件<?
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['file']))
{
$filename = $_GET['file']; // don't accept other directories
$size = @getimagesize($filename);
$fp = @fopen($filename, "rb");
if ($size && $fp)
{
header("Content-type: {$size['mime']}");
header("Content-Length: " . filesize($filename));
header("Content-Disposition: attachment; filename=$filename");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
fpassthru($fp);
exit;
}
}
header("HTTP/1.0 404 Not Found");
?>
问题:
黑客可以将任何字符串发送到此文件并保存我的根文件吗? (例如:index.php或者其他......)
如何查看包含图片文件的网址?
答案 0 :(得分:1)
Q1:您应该只限制对特定目录的访问 - 如果这只是一个目录,那么您无需使用$_GET
请求提供的目录,只需将其包含在您的php中即可。< / p>
$filename = end( explode( '/', $_GET['file'] ) );
$filename = '/uploadsdirectory/' . $filename;
Q2:要检查所请求文件的扩展名,您应该执行以下操作:
$extension = end( explode( '.', $filename ) );
这将返回jpg
或png
等。基本上是最后一段时间之后的任何内容
答案 1 :(得分:1)
int exif_imagetype ( string $filename )
答案 2 :(得分:0)
这是您需要白名单方法的事情。如果您的所有图片都存储在同一个文件夹中,只需传递文件名(例如image.jpg
),不要显示任何路径,并禁止出现任何/
。
下面的is_scalar()
检查会检查有人没有?file[]=test
,这会将数组发送到服务器。这有时不是什么大问题,但它可能会导致我们不想要的服务器输出错误。
if (!empty($_GET['file']) && is_scalar($_GET['file'])) {
$filename = $_GET['file'];
if (strpos('/', $filename) !== false) {
exit;
}
然后我们可以查看文件扩展名并确定是否允许。请注意strtolower()
的使用,以便它匹配大写扩展(PNG
,JPG
等)。检查$ext != $filename
确保没有人只是将“jpg”或“png”作为文件名传递。
$allowed_types = array('png', 'jpg', 'jpeg', 'gif');
$ext = preg_replace('/^(.*\.)(.*?)$/', '\\2', $filename);
if (!in_array(strtolower($ext), $allowed_types) && $ext != $filename) {
exit;
}
最后,检查文件是否确实存在,并且确实是文件。 file_exists()
也匹配目录,因此我们也可以通过is_file()
检查来确定。
$filename = '/images/' . $filename;
if (!file_exists($filename) || !is_file($filename)) {
exit;
}
完成这些检查后,您确定$filename
正常,您可以开始执行以下操作(从您的代码中获取):
$size = @getimagesize($filename);