为什么对路径中的目录使用'-execdir'操作不安全?


19

为什么不使用-execdirfind动作组合-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)

是什么导致此提示出现?

Answers:


22

您可能运行了错误的程序。有人可以让您运行他们的程序。

-execdir操作从包含找到的文件的目录中运行命令。$PATH含有相对路径,如.或任何不下手/-execdir是不安全,因为其中的文件时发现一个目录(或其他目录解析相对于它)还可以包含一个可执行文件同名,你正在尝试的一个跑步。然后,该可能不受信任的可执行文件将开始运行。

另一个用户可能有意利用此漏洞,导致您运行他们的程序,而不是您尝试运行的程序,这可能会损害或破坏数据安全性。或者,即使没有任何人试图使问题发生,它也可能导致无意中运行错误的程序,这种情况很少见。

如果一切都在你的PATH环境变量是一个绝对路径,应该不会出现这种错误,即使目录你要搜索并-execdir从荷兰国际集团包含在PATH。(我检查过是否可行。)如果您认为自己没有任何相对目录,$PATH但仍收到此错误,请使用包括的输出在内的详细信息更新您的问题echo "$PATH"

一个具体的例子。

作为可能出问题的示例,假设:

  • 爱丽丝有.她的$PATH,因为她希望能够运行在她的任何目录项目cd“d来,而不打扰与前面加上自己的名字./
  • 爱丽丝的疯狂夏娃已经/home/eve/shared与爱丽丝分享了。
  • 爱丽丝希望得到.c夏娃与她共享的文件的统计信息(行,单词,字节)。

因此,爱丽丝跑了:

find ~eve/shared -name \*.c -execdir wc {} \;

对于爱丽丝,不幸的是,夏娃创建了自己的脚本,对其进行了命名wc,将其设置为可执行文件(chmod +x),然后秘密地将其放置在的目录之一中/home/eve/shared。夏娃的脚本如下所示:

#!/bin/sh
/usr/bin/wc "$@"
do_evil    # Eve replaces this command with whatver evil she wishes to do

因此,当Alice使用findwith与Eve共享的文件-execdir一起运行wc,并且到达与Eve的自定义wc脚本位于同一目录中的文件时,Eve就会wc运行-具有Alice的所有特权!

wc出于谨慎,Eve使她的脚本充当了系统的包装器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-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固有的风险,无论如何,实际上最好避免这样做。考虑上面示例中的虚构情况。假设findAlice 不用运行,而只是运行cdS ~eve/shared/blah并运行wc *.c。如果blah包含Eve的wc脚本,do_evil则作为Alice运行。


2
我不知道您是否曾听说过此事,否则您将成为一名非常好的老师:)
heemayl 2015年

5
@heemayl所有在网上写有用的东西的人都已经是老师:-)
Ciro Santilli新疆改造中心法轮功六四事件

5

有一个更详细的信息在这里。另一个出色的参考资料在这里。引用第一个参考文献:

选项-execdir是GNU中引入的更现代的选项。find是尝试创建-exec的更安全版本。它具有与-exec相同的语义,并具有两个重要的增强功能:

它总是提供文件的绝对路径(对于-exec,使用文件的相对路径确实很危险)。

除了提供绝对路径外,它还会检查PATH变量的安全性(如果PATH env变量中存在点,则可以从错误的目录中提取可执行文件)

从第二参考:

如果当前目录包含在$ PATH环境变量中,则'-execdir'操作将拒绝执行任何操作。这是必需的,因为“ -execdir”在与文件相同的目录中运行程序-通常,此类目录可由不受信任的用户写入。由于类似的原因,'-execdir'不允许'{}'出现在要运行的命令名称中。


您能否扩展您的答案,为什么“如果PATH env变量中存在点,则可以从错误的目录中提取可执行文件”?哪个错误的目录?以及为什么我们必须这样做以使其安全?谢谢
αғsнιη

我希望更新后的帖子中的第二个链接能够回答您的问题
罗恩(Ron)

3

主要问题是PATH其中包含相对文件夹的系统变量的值,因此出于安全原因,find命令将不允许您执行二进制文件,因为它可能执行错误的程序。


因此,例如,如果根据警告得到当前目录在PATH中,则会得到:

当前目录包含在PATH环境变量中。

然后运行命令:

find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

万一其中包含本地脚本(rm带有可执行标志)rm -fr /,它可以删除所有文件,因为不是执行期望的/bin/rm,而是rm从当前目录执行,所以可能不是您想要的。


附带说明一下,当Travis CI(GH#2811)失败并出现错误时,这是一个已知问题:

find:相对路径`./node_modules/.bin'包含在PATH环境变量中,与find的-execdir操作结合使用时不安全。请从$ PATH中删除该条目

因此,解决方案是从PATH变量中删除受影响的条目,例如

PATH=`echo $PATH | sed -e 's/:\.\/node_modules\/\.bin//'`

根据drogus的建议。可以在GH#4862处跟踪此错误的进度。


这是Bash版本的解决方法:

PATH=${PATH//:\.\/node_modules\/\.bin/}

用法示例(将过滤传递PATH给特定命令):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f

这是一个sed似乎删除所有的东西find不喜欢:askubuntu.com/questions/621132/...
西罗桑蒂利新疆改造中心法轮功六四事件

3

xargsbash -c cd解决方法

好吧,我放弃:

find . -type f |
  xargs -I '{}' bash -c 'cd "$(dirname "{}")" && pwd && echo "$(basename "{}")"'

sed 解决方法

比以前的解决方法好一点:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" find . -execdir echo '{}' \;

一个测试用例:

[ "$(printf '/a/b::c/d:/e/f\n' | sed -E 's/(^|:)[^\/][^:]*//g')" = '/a/b:/e/f' ] || echo fail

对于rename具体情况,你也可以解决一些Perl的正则表达式复:/programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS希望破灭

对于那些希望有一种方法可以忽略其find固执己见的人,让我用一些资料粉碎一下:

由此可见,似乎没有办法关闭路径检查。

它检查的确切规则是:如果PATH要么为空或不以开头,则失败/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.