在 stdin 中传递应用程序配置是否是环境变量的安全替代方案?
Is passing application configuration in stdin a secure alternative to environment variables?
我正在尝试找出 Web 应用程序配置的最佳方法。目标是:
- 可配置性。强制在部署时指定配置。确保配置与代码或可部署工件分开。
- 安全。防止秘密从部署环境中泄露。
- 简单。确保解决方案简单且符合 OS 流程的概念。
- 灵活性。不假设配置的存储位置。
根据12 factor app web application configuration is best provided in environment variables. It is simple and flexible but it looks like there are some security concerns与此相关。
另一种方法是将所有配置作为命令行参数传递。这对 OS 来说又是简单、灵活和自然的,但整个配置随后在主机的进程列表中可见。这可能是也可能不是问题(我不是 OS 专家)但解决方案至少很麻烦。
流行的框架 Dropwizard 采用了一种混合方法,其中命令行参数指定配置文件位置并从那里读取配置。问题是它打破了对我的配置(本地文件)的位置做出假设的灵活性约束。它还使我的应用程序实现文件访问,虽然在大多数 languages/frameworks/libraries 中通常很容易实现,但本质上并不简单。
我正在考虑另一种方法,即传递应用程序 stdin
中的所有配置。最终,如果是本地存储的文件,甚至可以 wget https://secure-config-provider/my-config-file.yml | ./my-web-app
,可以做到 cat my-config-file.yml | ./my-web-app
。管道看起来很简单,并且是 OS 过程的原生方式。它看起来非常灵活,而且它分离了如何将配置提供给主机 OS.
的问题
问题是是否符合安全约束。可以安全地假设一旦管道内容被消耗它就永久消失了吗?
我没能 google 任何人尝试这个问题。
将机密写入进程的 stdin
比环境变量更安全 - 如果操作正确。
事实上,这是我所知道的将秘密从一个进程传递到另一个进程的最安全的方式 - 同样如果操作正确 .
当然这适用于所有没有文件系统存在的类文件输入,否则不能被其他进程打开,stdin
只是一个默认情况下可用且易于写入的实例。
无论如何,正如您链接的 post 所描述的那样,环境变量的关键在于,一旦您将某些内容放入环境变量中,它就会泄漏到所有子进程中,除非您注意清理它.
而且,对于其他进程 运行 作为您的用户或任何 privileged/administrative 用户,也可以检查您的 运行进程。
例如,在 Linux 上,查看文件 /proc/*/environ
。每个 运行 进程都存在该文件,您可以作为您的用户检查 运行 任何进程的内容。如果你是root
,你可以查看任何用户的任何进程的environ。
这意味着任何本地代码执行漏洞利用,甚至一些无特权的漏洞,都可以访问您环境变量中的秘密,而且非常简单这样做。仍然比将它们放在文件中要好,但也好不了多少。
但是,当您将内容通过管道传输到进程的 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
这比环境变量更安全还是更不安全? 视情况而定:
如果您在典型的 shell 中调用它,那么 echo
可能是一个“内置”,这意味着 shell 永远不需要执行外部 echo
程序,并且变量在写入 stdin
.
之前保留在其内存中
但是如果你从shell外部调用这样的东西,那么这实际上是一个很大的安全漏洞,因为它会将变量放入执行的外部echo
的命令行中] 程序,在许多系统上,任何其他 运行 进程,甚至其他非特权用户都可以看到它!
因此,只要您了解这一点,并使用正确的功能来确保您正在 直接 从具有流程凭据的任何内容编写,stdin
就是可能是您拥有的最安全的选择。
TL;DR: stdin
可以为您提供更小的数据泄漏“表面积”,这意味着它 可以帮助您 获得更高的安全性,但您是否这样做取决于您使用它的方式以及系统其余部分的设置方式。
就个人而言,我尽可能使用 stdin
来传递秘密数据。
我正在尝试找出 Web 应用程序配置的最佳方法。目标是:
- 可配置性。强制在部署时指定配置。确保配置与代码或可部署工件分开。
- 安全。防止秘密从部署环境中泄露。
- 简单。确保解决方案简单且符合 OS 流程的概念。
- 灵活性。不假设配置的存储位置。
根据12 factor app web application configuration is best provided in environment variables. It is simple and flexible but it looks like there are some security concerns与此相关。
另一种方法是将所有配置作为命令行参数传递。这对 OS 来说又是简单、灵活和自然的,但整个配置随后在主机的进程列表中可见。这可能是也可能不是问题(我不是 OS 专家)但解决方案至少很麻烦。
流行的框架 Dropwizard 采用了一种混合方法,其中命令行参数指定配置文件位置并从那里读取配置。问题是它打破了对我的配置(本地文件)的位置做出假设的灵活性约束。它还使我的应用程序实现文件访问,虽然在大多数 languages/frameworks/libraries 中通常很容易实现,但本质上并不简单。
我正在考虑另一种方法,即传递应用程序 stdin
中的所有配置。最终,如果是本地存储的文件,甚至可以 wget https://secure-config-provider/my-config-file.yml | ./my-web-app
,可以做到 cat my-config-file.yml | ./my-web-app
。管道看起来很简单,并且是 OS 过程的原生方式。它看起来非常灵活,而且它分离了如何将配置提供给主机 OS.
问题是是否符合安全约束。可以安全地假设一旦管道内容被消耗它就永久消失了吗?
我没能 google 任何人尝试这个问题。
将机密写入进程的 stdin
比环境变量更安全 - 如果操作正确。
事实上,这是我所知道的将秘密从一个进程传递到另一个进程的最安全的方式 - 同样如果操作正确 .
当然这适用于所有没有文件系统存在的类文件输入,否则不能被其他进程打开,stdin
只是一个默认情况下可用且易于写入的实例。
无论如何,正如您链接的 post 所描述的那样,环境变量的关键在于,一旦您将某些内容放入环境变量中,它就会泄漏到所有子进程中,除非您注意清理它.
而且,对于其他进程 运行 作为您的用户或任何 privileged/administrative 用户,也可以检查您的 运行进程。
例如,在 Linux 上,查看文件 /proc/*/environ
。每个 运行 进程都存在该文件,您可以作为您的用户检查 运行 任何进程的内容。如果你是root
,你可以查看任何用户的任何进程的environ。
这意味着任何本地代码执行漏洞利用,甚至一些无特权的漏洞,都可以访问您环境变量中的秘密,而且非常简单这样做。仍然比将它们放在文件中要好,但也好不了多少。
但是,当您将内容通过管道传输到进程的 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
这比环境变量更安全还是更不安全? 视情况而定:
如果您在典型的 shell 中调用它,那么 echo
可能是一个“内置”,这意味着 shell 永远不需要执行外部 echo
程序,并且变量在写入 stdin
.
但是如果你从shell外部调用这样的东西,那么这实际上是一个很大的安全漏洞,因为它会将变量放入执行的外部echo
的命令行中] 程序,在许多系统上,任何其他 运行 进程,甚至其他非特权用户都可以看到它!
因此,只要您了解这一点,并使用正确的功能来确保您正在 直接 从具有流程凭据的任何内容编写,stdin
就是可能是您拥有的最安全的选择。
TL;DR: stdin
可以为您提供更小的数据泄漏“表面积”,这意味着它 可以帮助您 获得更高的安全性,但您是否这样做取决于您使用它的方式以及系统其余部分的设置方式。
就个人而言,我尽可能使用 stdin
来传递秘密数据。