繁体   English   中英

PHP:建议在路径中转义斜线的方法(例如,防止目录遍历攻击)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM