为什么通过环境变量传递机密被认为“极其不安全”?

Mil*_*vić 14 command-line security password shell-script environment-variables

根据MySQL 文档,通过环境变量将机密(密码)传递给程序被认为是“极其不安全的”,并且在其他资源中被认为是糟糕的选择(从安全方面)。

我想知道为什么 - 我错过了什么?在提到的 MySQL 手册中(我以此为例),通过-p命令行中的选项传递密码被认为是“不安全”,通过 env var被认为是“极其不安全”,粗斜体。

我不是专家,但我知道基本原理:ps即使是非特权用户发出的简单命令也会读取每个程序以及命令参数,而只有同一用户(当然还有 root)可以读取进程的环境。因此,只有rootjohndoe可以读取johndoe启动进程的环境,而被黑www-data脚本则全部通过ps.

这里一定有一些我遗漏的大事 - 所以请解释我遗漏了什么?

我的目标是有一种将秘密从一个程序传输到另一个程序的方法,通常是非交互式的。

sou*_*edi 10

非常不安全,不应使用。某些版本的 ps 包括一个选项来显示正在运行的进程的环境。在某些系统上,如果您设置了 MYSQL_PWD,您的密码就会暴露给任何其他运行 ps 的用户。


这在这里解释(通过):

背景:在过程映像中 argv[] 和 envp[] 以相同的方式存储,彼此相邻。在“经典”的 UNIX 中,/usr/bin/ps 通常是 setgid“kmem”(或类似组),这允许它在 /dev/kmem 中挖掘以读取有关活动进程的信息。这包括读取系统上所有用户的进程参数和环境的能力。

这些天这些“特权 ps hacks”在很大程度上已经落后于我们:UNIX 系统都提出了查询此类信息的不同方法(Linux 上的 /proc 等)我认为所有(?)这些都认为进程的环境只是可读的通过它的uid。因此,环境中的密码等安全敏感数据不会泄露。

然而,旧的方式并不是 100% 死的。举个例子,这里有一个来自我有权访问的 AIX 5.2 机器的例子,它以非 root 用户身份运行

[AIX 5.2 于 2009 年终止。AIX,至少在 6100-09 并且在 7.2 上也得到确认,现在可以防止非 root 用户使用“ps ewwwax”命令查看其他用户进程的环境。 ]

...

作为记录,不久前我们发现(在 IRC 上?)OpenBSD 5.2 具有将环境泄露给其他本地用户的确切安全漏洞(尽管在该版本发布后不久已修复)。

[OpenBSD 5.2 于 2012 年发布]

这并不能解释为什么 MySQL 手册认为与命令行参数相比,使用环境变量是极其不安全的。请参阅此问题的其他答案。总之,要么是手册混乱,要么是环境变量太容易被误“泄露”了。

  • 谢谢。我希望“经典 UNIX”行为已经消失,至少在现代发行版上是这样。 (2认同)

Gil*_*il' 8

MySQL 文档中的这条建议措辞不佳。

\n\n

相反,在环境变量中传递密码并不比在命令行中传递密码安全。大多数现代 unice 通过以下方式向所有用户公开进程的命令行参数,但不公开其环境:ps。也有例外,但我从未听说过相反的系统(暴露环境而不暴露参数)。

\n\n

在交互式 shell 中键入的命令中包含密码是一个坏主意,因为密码最终会出现在 shell 历史记录中。如果关闭 shell 历史记录也没关系,但您必须记住这样做。无论密码是作为参数传递还是在环境中传递,这都适用。

\n\n

环境变量更危险的是,如果该变量被传递给其他进程。例如,设置数据库密码.profile将是一个非常糟糕的主意,因为它对所有程序都是可见的。同样,运行一个export MYSQL_PWD=\xe2\x80\xa6靠近顶部的脚本来运行许多超出其范围的命令mysql也是一个坏主意。但如果环境变量仅传递给mysql命令,那么就没有问题。

\n\n

MySQL 文档不应使用认为通过环境变量传递密码不如通过命令行参数传递密码安全的语言。恰恰相反。(除非环境设置超出了mysql命令范围,但这不是文档中描述的场景。)

\n


dol*_*men 6

在环境变量中传递机密的主要问题是将该环境的范围正确地限定到使用此机密的进程,并且不要将其提供给不应拥有该机密的进程。

仅在启动使用该环境变量的给定进程时设置环境变量是安全的。

但是在 shell 中全局环境中设置机密(对于当前会话)是不安全的(在 shell 的全局启动文件中更糟糕(.bash_profile.bashrc.profile)),因为从该 shell 启动的所有进程都将在其进程中包含此机密。环境。有些可能会有意(恶意软件)或无意地泄漏它们(考虑 shell 命令历史记录或将环境的完整内容转储到日志文件或远程服务器上的崩溃报告模块)。

不幸的是,从应用程序开发人员的角度来看,不可能强制应用程序的用户正确确定环境范围。我亲眼所见,里面储存了这么多的秘密~/.profile

因此,为了避免用户错误地使用环境,更安全的做法是不要直接在环境中加载机密(以减少泄漏的影响),而是使用环境变量将链接传递到真正存储机密的位置:使用额外的间接层。