为什么对于 PATH 中的目录使用 '-execdir' 操作是不安全的?

为什么对于 PATH 中的目录使用 '-execdir' 操作是不安全的?

为什么使用-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)

什么原因可能导致出现此提示?

答案1

您可能会运行错误的程序。有人可能会强迫您运行他们的程序。

-execdir操作从包含找到的文件的目录运行您的命令。$PATH包含相对路径时,例如.或任何不以/是不安全的,-execdir因为文件所在的目录(或相对于该文件解析的另一个目录)也可能包含与您尝试运行的可执行文件同名的可执行文件。然后,该可能不受信任的可执行文件将被运行。

另一个用户可能会故意利用这一点,让您运行他们的程序,而不是您尝试运行的程序,这可能会造成损害或破坏数据安全。或者,更不常见的是,它可能会导致无意中运行错误的程序,即使没有人试图制造问题。

如果PATH环境变量中的所有内容都是绝对路径,则不应发生此错误,即使您正在搜索和-execdir输入的目录包含在中PATH。 (我已经检查过这是否有效。)如果您认为您没有任何相关目录$PATH但仍然收到此错误,请使用包括输出在内的详细信息更新您的问题echo "$PATH"

一个具体的例子。

举个可能出错的例子,假设:

  • 爱丽丝.之所以有这样的能力,$PATH是因为她希望能够在她想要的任何目录中运行程序cd,而不必费心在其名称前面加上./
  • Alice 的敌友 Eve/home/eve/shared与 Alice 分享了彼此。
  • .cAlice 想要Eve 与她共享的文件的统计信息(行数、单词、字节数) 。

于是 Alice 运行:

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

不幸的是,对于 Alice 来说,Eve​​ 已经创建了自己的脚本,将其命名为wc,将其设置为可执行文件 ( chmod +x),并将其秘密地放在 下的一个目录中/home/eve/shared。Eve 的脚本如下所示:

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

因此,当 Alice 使用findwith-execdir运行wcEve 共享的文件时,并且它获取与 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——出现在$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根本不要有相对路径。

当使用自动更改目录的实用程序时,.或其他相对路径的风险尤其会增加,这就是为什么在这种情况下不允许您使用的原因。$PATHfind-execdir

.但是,在您的 中使用相对路径(尤其是)$PATH本身就存在风险,最好还是避免。考虑上面示例中的虚构情况。假设findAlice 不是运行 ,而是简单地cds 到~eve/shared/blah并运行wc *.c。如果blah包含 Eve 的wc脚本,do_evil以爱丽丝的身份奔跑。

答案2

有非常详细的信息这里. 另一个很好的参考是这里引用第一个参考文献:

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

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

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

来自第二个参考:

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

答案3

PATH=/usr/bin

这不是理想的,但它往往可以解决大多数用例,假设find和要使用的程序(rm此处)都在该目录中:

PATH=/usr/bin find -execdir rm ...

您可以根据需要添加任何缺失的 PATH。

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 regex-fu:https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS 希望破灭

对于那些希望有办法忽略的find固执己见的人,让我用一些来源来粉碎它:

由此我们看到似乎没有办法关闭路径检查。

它检查的具体规则是:如果 为PATH空或不以 开头,则失败/

答案4

解决方法是在命令前传递自定义 PATH,例如

PATH=/usr/bin find . -type f -name 'partOfFileNames*' -execdir echo rm -- {} +

上述解决方法将阻止加载全局的$PATH,而是我们自己的。


这是另一个例子(更灵活),假设我们要运行cat命令:

PATH=$(dirname $(which find)):$(dirname $(which cat)) find /etc -name hosts -execdir cat {} ';'

或者:

PATH=$(dirname $(which cat find) | paste -sd:) find ...

通过运行,$(dirname $(which cat))我们计算出要运行的命令位于何处。

相关内容