为什么在使用“应用程序平台”时将 API 密钥存储在 DigitalOceans API“环境变量”选项中是安全的?

Doh*_*h09 2 javascript security backend node.js digital-ocean

我正在设置一个 NodeJS 后端,它需要保存一些 API 密钥来联系其他 Firebase 来对用户进行身份验证。

我已经能够发布后端并成功从其上的 API 端点获取 HTTP 回复。我使用 Express 来运行 NodeJS API。

现在我希望 NodeJS API 充当我的用户和数据库接触点。但我不确定在哪里安全地存储该项目的 API 密钥。因为我对这种类型的安全性比较陌生。

因此,我用 Google 搜索了一下,发现人们说 .env 文件不是存储 API 密钥的安全位置。然而,在DigitalOcean 文档中,它说了以下内容:

环境变量是存储敏感信息(例如 API 密钥)或需要从应用程序中的任何位置全局访问的信息(例如版本号或硬编码路径)的绝佳位置。

所以我的问题是,为什么 DigitalOcean 会说在环境变量中存储 API 密钥是安全的,而许多其他消息来源却说它不安全。这是因为危险在于文件的可访问性,而 DigitalOcean 以某种方式保护该文件吗?我注意到他们有一个“秘密”布尔框,您可以勾选它,它表示它不会出现在控制台中。但对于普通人来说,它是否也是完全无法接触的呢?

我主要关心的是防止黑客或恶意的人访问 API 密钥。我不担心拥有合法访问权限的人会滥用它,只担心没有合法访问权限的人会滥用它。

期待您的见解。

Avi*_* Lo 8

我将按照以下顺序对存储秘密的安全性进行排名(从不太安全到最安全):

  1. 将它们直接存储在代码中(真的非常糟糕)
  2. 将它们存储在环境变量中
  3. 将它们存储在磁盘上的文件中
    • 可以设置访问权限,例如谁可以读取它
    • 如果将内容加载到环境变量中,则与Point 2
  4. 将它们存储在对象存储中(AWS S3、Google Cloud Storage)
  5. 使用秘密管理器(AWS、GCP Secret Manager)存储它们
  6. 使用 IAM(实际上并不是存储秘密的地方,而是一种控制谁可以使用上述方法访问秘密的方法)。

详细说明:

第 2 点和第 3 点:

points 2 and 3如果您的系统受到损害,两者之间的区别就会变得模糊。在这种情况下,如果攻击者具有 root 访问权限,他/她可以读取/写入/删除/更改所有内容,因此point 3将会失败。对于point 2,攻击者可以通过 3 种方法访问环境变量:

根据这篇文章中的@phmmmer

  1. 进程的运行环境 当进程运行时,可以通过 >> 访问该进程的环境变量/proc/$PID/environ。但是,只有拥有该进程的用户或 root 才能访问该文件。

  2. 环境变量的来源 如果您使用 init 脚本,并且变量存储在该 init 脚本中,那么当然可以通过读取该脚本来获取这些变量。

或者,如果环境变量来自其他地方,那么无论它在哪里。

  1. 'ps' 输出 是的,我知道我说的是 2,在任何像样的系统中,它都会是 2。但是,如果管理员不知道他在做什么,则可以打开第三条大道。

如果进程是通过类似的方式启动的sh -c 'cd /foo/bar; POP=tart /my/executable',那么该 sh 进程将在 ps 中可见:


$ ps ax | grep POP phemmer   3085  14   5  0.0  0.0 SN         00:00
sh -c cd /; POP=tart sleep 10```
Run Code Online (Sandbox Code Playgroud)

第4点:

您可以将机密作为对象存储在对象存储中,并在部署期间或启动期间下载它们。大多数对象存储都提供日志记录功能,因此您还可以监控您的秘密的使用方式以及谁在使用它们。注意:当且仅当您正确配置 IAM 权限时Point 4才好。否则,它与 没有什么不同,尽管现在您是从远程位置获取文件。Point 2

第5点:

您的应用程序可以调用秘密管理器的 API 来使用秘密。除了内存中之外,您的秘密不会存储在本地任何地方。是的。您也可以加密您的内存,您可以在这篇文章中阅读更多内容

第6点:

IAM 或身份和访问管理用于在正确的时间向正确的人员/用户/应用程序授予对正确资源的正确访问权限。它不是秘密存储,但可用于管理对秘密存储的访问。

所以,回答你的问题:

"Environment variables are excellent places to store sensitive information"DO 可能夸大其词。但它们确实提供的不仅仅是将敏感信息存储在环境变量中并将其留在那里。

在您问题中提到的文档的下一篇文章中,DO 确实提供了有关环境变量的某些级别的访问控制和加密: "How to Use Environment Variables in App Platform"

  1. 运行时变量
    • 在应用程序创建期间
    • 创建应用程序后
  2. 构建时间变量
  3. 环境变量中的可绑定变量
    • 应用程序范围的变量
    • 特定于组件的变量

因此,当人们说使用环境变量存储敏感信息不安全时,大多数人谈论的是没有访问控制和加密的普通环境变量。在这种情况下,将 API 密钥存储在那里绝对不安全。应使用普通的环境变量来存储端口号、生产环境或其他非敏感信息等信息。

以下是我用作此答案参考的一些帖子:

  1. 管理无服务器机密的 5 种方法(按最佳到最差排名)
  2. 管理 Terraform 代码中机密的综合指南
  3. DigitalOcean:如何在应用程序平台中使用环境变量