根据以下规定,通过环境变量将机密(密码)传递给程序被认为“极其不安全”MySQL 文档并且作为糟糕的选择(从安全方面)其他资源。
我想知道为什么 - 我错过了什么?在提到的MySQL手册中(我以此为例),通过-p
命令行中的选项传递密码被视为“不安全感“并通过环境变量为”极度没有安全感”,粗斜体字体。
我不是专家,但我确实知道基础知识:简单的ps
命令,即使是由非特权用户发出的,也会读取每个程序以及命令参数而只有同一用户(当然还有 root)可以读取进程的环境。因此,只能root
读取johndoe
启动johndoe
进程的环境,而黑客www-data
脚本则通过 读取所有内容ps
。
这里一定有什么大事我错过了 - 所以请解释一下我错过了什么?
我的目标是找到一种将秘密从一个程序转移到另一个程序的方法,通常是非交互式的。
答案1
极不安全,不应使用。某些版本的 ps 包含一个显示正在运行的进程的环境的选项。在某些系统上,如果您设置 MYSQL_PWD,您的密码就会暴露给任何其他运行 ps 的用户。
背景:在进程中,图像argv[]和envp[]以相同的方式存储,彼此相邻。在“经典”UNIX 中,/usr/bin/ps 通常是 setgid“kmem”(或类似组),这允许它在 /dev/kmem 中挖掘以读取有关活动进程的信息。这包括读取系统上所有用户的进程参数和环境的能力。
如今,这些“特权 ps 黑客”基本上已经成为过去: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手册认为使用环境变量是极其与命令行参数相比,不安全。请参阅此问题的其他答案。简而言之,要么是手册混乱,要么是环境变量太容易被错误地“泄漏”。
答案2
MySQL 文档中的这条建议措辞不佳。
相反,在环境变量中传递密码并不比在命令行中传递密码安全。大多数现代 unice 通过ps
命令和其他类似软件向所有用户公开进程的命令行参数,但不公开其环境。也有例外,但我从未听说过相反的系统(暴露环境而不暴露参数)。
在交互式 shell 中键入的命令中包含密码是一个坏主意,因为密码最终会出现在 shell 历史记录中。如果关闭 shell 历史记录也没关系,但您必须记住这样做。无论密码是作为参数传递还是在环境中传递,这都适用。
环境变量更危险的是,如果该变量被传递给其他进程。例如,设置数据库密码将.profile
是一个非常糟糕的主意,因为它对所有程序都是可见的。同样,运行一个export MYSQL_PWD=…
靠近顶部的脚本来运行许多超出其范围的命令mysql
也是一个坏主意。但如果环境变量仅传递给mysql
命令,那么就没有问题。
MySQL 文档不应使用认为通过环境变量传递密码不如通过命令行参数传递密码安全的语言。恰恰相反。 (除非环境设置超出了mysql
命令范围,但这不是文档中描述的场景。)
答案3
在环境变量中传递机密的主要问题是将该环境的范围正确地限定到使用此机密的进程,并且不要将其提供给不应拥有该机密的进程。
仅为启动使用该环境变量的给定进程而设置环境变量是安全的。
但是在 shell 中全局环境中设置机密(对于当前会话)是不安全的(在 shell 的全局启动文件中更糟糕(.bash_profile
、.bashrc
、.profile
)),因为从该 shell 启动的所有进程都将在其进程中包含此机密。环境。有些可能会有意(恶意软件)或无意地泄漏它们(考虑 shell 命令历史记录或将环境的完整内容转储到日志文件或远程服务器上的崩溃报告模块)。
不幸的是,从应用程序开发人员的角度来看,不可能强制应用程序的用户正确确定环境范围。我亲眼所见,里面储存了这么多的秘密~/.profile
。
因此,为了避免用户错误地使用环境,更安全的做法是不要直接在环境中加载机密(以减少泄漏的影响),而是使用环境变量将链接传递到真正存储机密的位置:使用额外的间接层。
答案4
请考虑一下这个场景:
- 您构建了一个 php/ruby/whatever + mysql 应用程序。
- 我设法让你的应用程序/服务器产生错误 500。某些配置会向我的浏览器产生 ENV 以及任何类型的堆栈跟踪。
- 我使用 mysql 或 smtp 秘密是为了乐趣和利润。
也想一想这个:
- 您未能正确配置 apache/nginx 文件夹,但我设法访问 .env 文件本身
- 再次,我使用 mysql 或 smtp 秘密来获取乐趣和利润。
底线:使用秘密提供程序(它们很容易使用而且不太昂贵),但如果您负担不起,请确保在设置的其他方面正确设置最大安全性,例如网络服务器公开披露 .env 文件或 env变量。