【发布时间】:2020-11-14 19:04:45
【问题描述】:
PHP 函数escapeshellarg() 变成这样:
"A schema"."A table"
进入这个:
" A schema . A table "
也就是说,它用空格代替引号而不是引用它们。预期和期望的结果(由我)是:
"\"A schema\".\"A table\""
这浪费了我一生中无数个小时的故障排除。在很长一段时间里,我只是不知道发生了什么;我的大脑从来没有想过,实际上完全删除双引号会如此愚蠢!即使这“让它变得安全”,但在逃避它们时这样做是一件很奇怪的事情,不仅是标准和受支持的处理方式,而且不会导致使用此功能产生任何问题。
需要注意的是,我已经阅读了 cmets:https://www.php.net/escapeshellarg
我还阅读了很多其他文章,抱怨这个功能以及 Windows shell 转义等等,所以我至少“模糊地”知道原因:“这很复杂。”
但是,我发现自己被这个核心函数 (escapeshellarg) 彻底削弱了,可悲的是,PHP 经常出现这种情况,我发现自己试图创建自己的函数来替换它。当然,这是非常有问题和可怕的,因为这个功能的一半是与安全相关的!它应该“确保”任意字符串作为命令行参数使用,而不会有攻击者可以“突破”它并执行任意命令的风险!
出于这个原因,我很确定只是这样做:
$likely_not_a_safe_argument = '\"' . str_replace('"', '\"', $user_input) . '\"';
...不安全!如果就这么简单,那么我敢肯定 PHP 开发人员会在 escapeshellarg 中为 Windows 执行此操作。
基本上,我现在不知道该怎么办。是的,我确实需要在参数中发送双引号。下面是一个真实世界的例子:
pg_dump --format plain --verbose --file "dump.txt" --exclude-table-data="\"Test schema\".\"Test table\"" --host="localhost" --port="5432" --username="postgres" --dbname="testdb"
(不,它不需要单引号或其他任何东西。它必须是标识符周围的双引号。)
我应该如何安全地“改进”escapeshellarg() 使其不会破坏我的双引号?其他人都做什么?
【问题讨论】:
-
Cygwin 没有这个问题,也许你可以切换到 Cygwin 或 WSL?
-
@hanshenrik 好吧,我运行的是 Windows 而不是 Unix。 PHP 应该是跨平台的,但现在的普遍态度似乎是“要么你运行 Linux,要么你不能做所有这些事情”。如果 Linux 是一个替代方案,我会在 20 年前开始尝试切换到它时切换。
-
仅供参考,这里是 escapeshellarg 的最新 source code。它确实用空格字符替换了
!、%和",所以你可能对此无能为力。 -
由于该函数的源代码非常简单,您可以通过对
"案例的小修改来重新实现它。 -
@user1597430 嗯...如果是这样,为什么不是他们做的?您似乎认为这是某种“疯狂的边缘情况”,但实际上它完全删除双引号而不是转义它们。像这样重新实现这个与安全相关的功能对我来说听起来不太合适?
标签: php terminal command-line-interface