[英]PHP: Recommended way to escape slashes in path (e.g. to prevent directory traversal attack)
我正在寻找一个PHP函数来将字符串清理成没有目录分隔符(斜杠)的安全有效的文件名。
理想情况下,它应该是可逆的,并且不应使名称混乱过多。
当然,我想防止故意的目录遍历攻击。 但是我也想防止创建子文件夹。
我认为urlencode()
可以工作,但是我想知道这是否足够,和/或是否有更好或更受欢迎的东西。
另外,如果在Windows上有同样有效的方法(反斜杠作为目录分隔符),则该解决方案是可移植的。
用例/场景:
作为数据导入的一部分,我想将文件从远程URL下载到本地文件系统中。 网址来自csv文件。 其中大多数都可以,但其中的斜线可能比预期的多。
例如,大多数人是这样的:
https://files.example.com/pdf/12345.pdf
但是,单个文件可能是这样的:
https://files.example.com/pdf/1/2345.pdf
这些文件应全部放入同一目录,例如https://files.example.com/pdf/12345.pdf
> /destination/dir/12345.pdf
1/2345.pdf
类的文件不应位于子目录中。 相反, /
应该以某种(可逆的)方式转义。 例如,使用urlencode(),它将为1%2F2345.pdf
。
您可以创建一组替换。 例如,您可以使文件名中出现的/ char用“(斜杠)”之类的东西来表示。 只需使用str_replace在查找文件名和将文件名编码为url之间切换。 这只是一个例子。
这应该对您有帮助。
输入 : https : //files.example.com/pdf/1/2345.pdf
输出 :pdf_1_2345.pdf
$url = 'https://files.example.com/pdf/1/2345.pdf';
$parse = parse_url($url);
//get path, remove first slash
//$path: pdf/1/2345.pdf
$path = substr($parse['path'],1);
//result becomes: pdf_1_2345.pdf
$result = str_replace('/','_',$path);
编辑:最好的选择是将远程文件的url存储在数据库中,对它的值进行哈希处理(使用md5或类似的文件),然后在本地以该名称保存文件,并将该哈希值也存储在数据库中。
这是您最好的选择,通过这种方式,您始终可以知道哪个远程文件与您的本地文件相对应,反之亦然,并且您不必在本地处理文件名,因为它们可以是您想要的任何文件名(只要您保持他们检查唯一性)
Database Table:
--------------------
| id | remote_url | local_name |
-----------------------------------------------------
| 1 | http://example/.../123.pdf | sdflkfd..dl.pdf|
你明白了。
您可以使用此功能,它将所有目录分隔符替换为下划线。
function secureFilePath($str)
{
$str = str_replace('/', '_', $str);
$str = str_replace('\\', '_', $str);
$str = str_replace(DIRECTORY_SEPARATOR, '_', $str); // In case it does not equal the standard values
return $str;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.