【问题标题】:Why is it safe to store API keys in DigitalOceans API "Environment Variable" option when using "App Platform"?为什么在使用“应用平台”时将 API 密钥存储在 DigitalOceans API“环境变量”选项中是安全的?
【发布时间】:2021-04-15 13:51:48
【问题描述】:

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

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

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

所以,我搜索了一下,发现人们说 .env 文件不是存储 API 密钥的安全地方。然而在DigitalOcean documentation 上却说:

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

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

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

期待您的见解。

【问题讨论】:

    标签: javascript node.js security backend digital-ocean


    【解决方案1】:

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

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

    阐述:

    第 2 点和第 3 点:

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

    根据@phmmmer 在this post

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

    2. 环境变量的来源 如果您使用的是初始化脚本,并且变量存储在该初始化脚本中,则 变量当然可以通过阅读该脚本获得。

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

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

    如果进程通过sh -c 'cd /foo/bar; POP=tart /my/executable' 之类的方式启动,那么该 sh 进程将在 ps 中可见: 如果进程是通过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```
    

    第 4 点:

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

    第 5 点:

    您的应用程序可以使用所有秘密管理器的 API 来使用这些秘密。除了内存之外,您的秘密不会存储在本地任何地方。是的。你也可以加密你的记忆,你可以在this post阅读更多内容

    第 6 点:

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

    所以回答你的问题:

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

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

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

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

    我将一些帖子用作此答案的参考:

    1. 5 ways to manage serverless secrets, ranked best to worst
    2. A comprehensive guide to managing secrets in your Terraform code
    3. DigitalOcean: How to Use Environment Variables in App Platform

    【讨论】:

      【解决方案2】:

      同意之前的帖子。一个好的做法是考虑“如果您的系统受到威胁,它们会在您的系统上作为 ROOT 运行”。如果您可以使用 sudo 执行任何操作 - 假设他们也可以。

      我想补充的一点是养成为 dev/test/prod/ 和每个本地开发人员使用唯一 API 密钥的习惯。我知道这似乎很明显,但我见过很多情况,人们在 prod 中做得很好,但在 dev 中重复使用相同的 API 密钥,甚至允许开发人员在本地机器上使用相同的 prod API 密钥而不是它受到同样严格的保护。

      此外,如上所述使用 IAM 可以很好地确保限制访问,但如果您走这条路,请确保您愿意让自己更难在 Azure、AWS、GCP 环境之间移动。

      【讨论】:

        猜你喜欢
        • 2021-07-24
        • 2021-06-10
        • 2020-06-30
        • 2018-08-10
        • 2016-10-12
        • 2021-09-27
        • 1970-01-01
        • 2020-12-06
        • 2023-01-09
        相关资源
        最近更新 更多