我试图找出Web应用程序配置的最佳方法。目标是:
根据12 factor app Web应用程序配置最好在环境变量中提供。它简单而灵活,但看起来有一些security concerns与此相关。
另一种方法可能是将所有配置作为命令行参数传递。这对于操作系统来说再次简单,灵活和自然,但整个配置随后在主机的进程列表中可见。这可能是也可能不是问题(我没有OS专家),但解决方案至少很麻烦。
混合方法由流行的框架Dropwizard采用,其中命令行参数指定配置文件位置,并从那里读取配置。问题是制动灵活性约束,对我的配置(本地文件)的位置做出假设。它还使我的应用程序实现文件访问,虽然通常在大多数语言/框架/库中很容易实现,但本质上并不简单。
我在考虑另一种方法,即通过应用程序stdin
中的所有配置。最终,在本地存储文件甚至cat my-config-file.yml | ./my-web-app
的情况下,可以wget https://secure-config-provider/my-config-file.yml | ./my-web-app
。管道似乎很简单并且是OS过程的原生。它似乎非常灵活,并且它将配置如何提供给主机操作系统的问题分开。
问题是它是否符合安全约束。是否可以安全地假设一旦使用了管道内容,它就会永久消失?
我无法谷歌任何人尝试这个问题。
答案 0 :(得分:0)
将机密写入进程的stdin
比环境变量更安全-如果操作正确。
事实上,这是我所知的最安全的方式,将秘密从一个过程传递到另一个过程-如果正确完成,则再次 。
当然,这适用于所有不具有文件系统存在并且否则无法被其他进程打开的类似文件的输入,stdin
只是其中一个实例默认情况下可用,并且易于写入。
无论如何,正如您所链接的文章所描述的,具有环境变量的关键之处在于,一旦将某些东西放入环境中 变量会泄漏到所有子进程中,除非您小心清理它。
但是,其他进程也可能以您的用户或任何特权/管理用户身份运行,以检查您正在运行的进程的环境。
例如,在Linux上,查看文件/proc/*/environ
。该文件存在于每个正在运行的进程中,并且您可以检查以用户身份运行的任何进程的内容。如果您是root
,则可以查看周围的任何进程。
这意味着任何本地代码执行漏洞,甚至是一些非特权漏洞,都可以访问您环境变量中的秘密,这非常简单 。仍比将它们存储在文件中更好,但幅度不大。
但是,当您将内容通过管道传递到stdin
时,外部进程只有在能够使用调试系统调用来“附加”到该进程,监视系统调用或对其进行扫描的情况下,才能进行拦截。记忆。这是一个非常复杂的过程,在哪里看不太明显,最重要的是,它可以得到更多的保护。
例如,可以对Linux进行配置,以防止未特权的用户进程甚至将调试器系统调用调用到其他由同一用户启动的进程中,而该进程并未启动,而某些发行版开始转向默认情况下启用。
这意味着在几乎所有情况下,将数据正确写入stdin
至少比使用环境变量安全得多。
但是请注意,您必须“正确执行”。例如,这两个不会会给您带来相同的安全优势:
my-command </some/path/my-secret-config
cat /some/path/my-secret-config | my-command
因为机密仍然存在于磁盘上。因此,您获得了更多的灵活性,但没有更多的安全性。 (但是,如果cat
实际上是sudo cat
,或者对my-command
的文件访问权限比echo "$my_secret_data" | my-command
更多,那么这可能是安全的好处。)
现在让我们看一个更有趣的案例:
echo
这比环境变量安全吗? 这取决于:
如果您是在典型的shell中调用此函数,则stdin
可能是“内置”,这意味着shell永远不需要调用外部进程,并且变量在写入变量之前会保留在其内存中。 stdin
。
但是,如果您从外壳程序外部调用这样的内容,那么实际上这是一个很大的安全漏洞,因为它将把变量放入被调用进程的命令行中,在许多系统上,任何人都可以看到其他正在运行的进程,甚至是其他非特权用户!
只要您了解这一点,并使用正确的功能来确保直接从过程中具有凭据的任何地方直接写 ,stdin
可能是最安全的选择你有。
TL; DR: stdin
可以为您提供小得多的“表面积”,使数据泄漏,这意味着它可以帮助您更高的安全性,但是您是否这样做取决于您的使用方式以及系统其余部分的设置方式。
我个人使用{{1}}尽可能地传递秘密数据。