-execdir
为什么在使用 isn't的同时使用 find的操作组合是不安全的-exec
?
当我运行以下命令时,我收到以下提示消息:
/path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +
find: The current directory is included in the PATH environment variable, which is insecure
in combination with the -execdir action of find. Please remove the current directory
from your $PATH (that is, remove "." or leading or trailing colons)
什么可能导致出现此提示?
您可能会运行错误的程序。有人可以让你运行他们的程序。
该
-execdir
操作从包含找到的文件的目录运行您的命令。当$PATH
包含相对路径(例如.
或任何不以 开头的内容/
)时,-execdir
是不安全的,因为找到文件的目录(或相对于它解析的另一个目录)也可能包含与您尝试的文件同名的可执行文件跑步。然后将运行该可能不受信任的可执行文件。这可能会被其他用户故意利用,让您运行他们的程序,而不是您尝试运行的程序,这可能会造成危害或破坏数据安全。或者,在少数情况下,它可能只是导致无意中运行了错误的程序,即使没有人试图让问题发生。
如果您的
PATH
环境变量中的所有内容都是绝对路径,则不应发生此错误,即使您正在搜索和访问的目录-execdir
包含在. (我已经检查过这是否有效。)如果您认为您没有任何相关目录但仍然收到此错误,请使用详细信息更新您的问题,包括.PATH
$PATH
echo "$PATH"
一个具体的例子。
作为可能出错的示例,假设:
.
她$PATH
,因为她希望能够在她想要的任何目录中运行程序cd
,而不必费心在它们的名称前加上./
./home/eve/shared
与爱丽丝分享了。.c
Alice 想要Eve 与她共享的文件的统计信息(行数、字数、字节数) 。所以爱丽丝运行:
不幸的是,对于爱丽丝来说,夏娃已经创建了她自己的脚本,将其命名为
wc
,将其设置为可执行文件 (chmod +x
),并将其秘密地放置在 下的一个目录中/home/eve/shared
。Eve 的脚本如下所示:因此,当 Alice 使用
find
with-execdir
运行wc
Eve 共享的文件时,它会访问与 Eve 的自定义wc
脚本位于同一目录中的文件,Eve 的wc
运行——具有 Alice 的所有权限!(狡猾的 Eve 已经让她的
wc
脚本充当系统的包装器wc
,所以 Alice 甚至不知道出了什么问题,也就是说,它do_evil
已经运行了。然而,更简单——也更复杂——的变化是可能的。 )如何
find
防止这种情况。find
通过在包含相对目录时拒绝执行-execdir
操作来防止此安全问题的发生。$PATH
find
根据具体情况提供两种诊断信息。如果
.
在 中$PATH
,那么(如您所见)它说:find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)
它可能对这种
.
情况有特殊的信息,因为它特别常见。.
如果--say,foo
--appears以外的相对路径$PATH
并且你运行find
with-execdir
,它会说:find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH
最好根本不要有相对路径
$PATH
。.
使用自动更改目录的实用程序时,拥有或其他相对路径的风险$PATH
尤其高,这就是为什么find
不允许您-execdir
在这种情况下使用的原因。但是拥有相对路径,尤其是
.
在你$PATH
的路径中,本身就有风险,无论如何最好避免。考虑上面示例中的虚构情况。假设find
爱丽丝没有跑,而是简单地cd
跑~eve/shared/blah
了wc *.c
。如果blah
包含 Eve 的wc
脚本,do_evil
则作为 Alice 运行。这里有非常详细的信息。另一个很好的参考是这里。引用第一个参考:
来自第二个参考:
主要问题在于其中包含相关文件夹的系统变量的值
PATH
,因此出于安全原因,find
命令不允许您执行二进制文件,因为它可能会执行错误的程序。因此,例如,如果您根据收到的警告在 PATH 中有当前目录:
你将运行你的命令:
如果您的本地脚本(
rm
带有可执行标志)包含rm -fr /
在其中,它可以删除您的所有文件,因为/bin/rm
您不会执行 expected ,而是rm
从当前目录执行,所以它可能不是您想要的。作为旁注,这是 Travis CI ( GH #2811 ) 中的已知问题,当它失败并出现错误时:
所以解决方案是从 PATH 变量中删除受影响的条目,例如
正如drogus所提议的那样。可以在GH #4862关注此错误的进展。
这是 Bash 版本解决方法:
用法示例(将过滤传递
PATH
给特定命令):放
PATH=/usr/bin
这并不理想,但它倾向于解决大多数用例,假设两者
find
和要使用的程序(rm
此处)都在该目录中:您可以根据需要添加任何缺少的路径。
xargs
和bash -c cd
解决方法好吧,我放弃:
sed
解决方法比以前的解决方法差一点:
一个测试用例:
具体来说
rename
,您还可以使用一些 Perl regex-fu:https ://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971RTFS希望破灭
对于那些希望存在一种方法来忽略
find
的自以为是的人,让我用一些来源来粉碎它:从中我们看到似乎没有办法关闭路径检查。
它检查的确切规则是:如果
PATH
为空或不以 开头则失败/
。解决方法是在命令之前传递自定义 PATH,例如
以上解决方法将阻止加载全局
$PATH
,但我们自己的。这是另一个示例(更灵活),假设我们要运行
cat
命令:或者:
通过运行,
$(dirname $(which cat))
我们计算出要运行的命令所在的位置。