如何在file_exists中使用$ _GET路径并保证其安全?
我有一个函数来检查文件是否存在,通过jQuery调用PHP脚本,我将在单击索引页面上的按钮更改某些图像时使用该脚本。
jQuery函数:
function fileExists(path){ $.getJSON("/ajax/fileExists.php",{ path: path }, function (data){ return data.path; }); }
fileExists.php:
$path=$_SERVER['DOCUMENT_ROOT'].'/packs'.$_GET['path']; if(file_exists($path)){ echo json_encode(TRUE); }else{ echo json_encode(FALSE); }
我担心人们使用这个脚本列出我可能不想让他们知道的服务器或文件的内容所以我使用了DOCUMENT_ROOT和/ packs来尝试限制对该目录的调用,但我认为人们可以简单地在提供的路径中使用../来检查备选方案。
什么是使这种安全的最佳方法,理想情况下将其限制为/包装,还有其他我担心的问题吗?
编辑:javascript / jQuery中的示例调用:
if( fileExists('/index.php') ){ alert('Exists'); }else{ alert('Doesn\'t exist'); }
这就是我过去处理它的方式:
$path = realpath($_SERVER['DOCUMENT_ROOT'].'/packs'.$_GET['path']); if (strpos($path, $_SERVER['DOCUMENT_ROOT']) !== 0) { //It's looking to a path that is outside the document root }
您可以从文件名中删除任何路径遍历:
$path_arr = explode("/", $_GET['path']); $path = $path_arr[count($path_arr - 1)];
这种做法是适度安全和快速的(O(1)复杂性),但并不是最好的,因为你必须注意编码,字符替换和所有类似的东西。
但总体最佳实践(尽管速度越慢,取决于您的目录大小,假设O(n)复杂性)将使用readdir()获取/ packs目录中所有文件的列表,然后查看提供的文件名是否为当下:
$handle = opendir($path=$_SERVER['DOCUMENT_ROOT'].'/packs'); while (false !== ($entry = readdir($handle))) { if ($entry === $_GET['path']) { echo json_encode(TRUE); return; } } echo json_encode(FALSE);