【问题标题】:How to manage API keys for npm packages that require key on the client-side code?如何管理需要客户端代码密钥的 npm 包的 API 密钥?
【发布时间】:2021-12-17 06:57:44
【问题描述】:

关于如何安全地处理 API 密钥是一场激烈的辩论。

几乎我们所有人都知道,将它们存储在服务器端而不暴露在客户端应用程序中是最好的解决方案。

我们的客户可以向我们的 API 发送请求,我们的 API 可以充当代理向第三方 API 发送/接收数据,并将响应返回给我们的客户。

但是,您可以将一些第三方 SDK 集成到您的客户端应用中,并且它们也有自己的 API 密钥。

例如,Zoom 有适用于 Web、Android、iOS、Windows 等的 SDK,或者 Pusher 有 Pusher Key。

当您想使用这些库时,您不能向您的 API 发送请求以隐藏 API 密钥。您必须在客户端代码中初始化这些库(例如反应)。

来自Zoom 的示例,用于在您的网络应用程序中加入会议:

client.join({
    apiKey: apiKey,
    signature: signature,
    meetingNumber: meetingNumber,
    password: password,
    userName: userName
})

保护客户端 SDK 和库的 API 密钥的最佳做法是什么?

【问题讨论】:

  • 您链接的文档指出apiKey 是“Zoom JWT 应用程序 API 密钥”,the Zoom JWT docs 说,“应该由服务器端应用程序唯一生成并作为承载令牌包含在每个请求的标头中。”假设您的网络应用程序应该向您的 API(知道您的 Zoom API 密钥)询问可用于代表您发出请求的不记名令牌。无需将您的 Zoom API 密钥存储在您的网络应用程序中。需要明确的是,实际的 Zoom API 密钥仅用于对 apiKey 参数中传递的 JWT 进行签名。

标签: security client-side api-key


【解决方案1】:

您究竟想保护什么?我假设您希望避免有人滥用您的 API 密钥,但您应该问问自己,您想要保护哪些安全风险或威胁?

您还应该了解您处理的是哪种 API 密钥,因为并非所有这些密钥都用于相同的用例,并且可能“提供”不同级别的安全性。 例如,您可以拥有personal access token 形式的 API 密钥(例如,在 GitHub 中),其中令牌直接与用户/员工相关联并且应该被视为机密,或者您可能拥有 API 密钥以机器令牌的形式,它与您的组织或存储库(例如仍在 GitHub 中)相关联,并且可以配置不同的权限(只读、读写)。

根据客户端本身的可能性,API密钥也可以配置和限制到一些客户端。 例如,一些 Google Maps API 允许您配置一个受信任的来源,允许它使用您的特定 API 密钥执行请求,但是这种保护通过检查请求的引用标头来工作,并且它可能被任意客户端欺骗。浏览器仍应遵守约定并发送正确的引荐来源网址,以保护您免受想要在其网站上使用您的 API 密钥的人的侵害。

移动应用程序领域的另一个例子:有些供应商允许您将 API 密钥绑定到特定的包名称,然后供应商的 SDK 在运行时对其进行验证,但是这种保护通常作为许可机制,避免开发者免费配置带有泄露 API 密钥的 SDK。

通常情况下,如果 API 密钥旨在用于公共客户端,那么 API 的开发人员已经考虑到泄露的威胁,您不应该受到影响。这意味着您将承担巨额 API 使用费用或速率限制/使用配额限制(但最好自己检查一下!)。

一般规则是始终检查您尝试配置的应用程序的开发人员文档,并了解如何为您的用例创建适当的 API 密钥,以及是否可以从您的“泄露”客户。此外,如果 API 密钥允许您配置权限,请记住遵循最小权限原则。

另一个黄金法则是始终对您的实施进行威胁建模:

  • API 密钥有哪些功能?
  • 如果攻击者访问 API 密钥,他们能做的最糟糕的事情是什么?
  • 我是否在保护自己免受这些威胁?如何?我可以在后端放置更多控件或监视器(即高使用率通知等)吗?

最后,如果您的 API 密钥需要保密,那么您不得在公共客户端上使用它,无论它多么隐蔽。总会有至少一个人能够检索它(也不要依赖客户端检查!)。在这种情况下,您可能想要拥有自己的后端服务,负责使用 API 密钥查询 API 以及对您的客户/用户进行身份验证和授权,并实施额外的安全措施,如速率限制。

我发现非常有帮助的一件事是始终记录任何生成/使用的 API 密钥及其功能,以及泄露它们的威胁以及一些将风险降至最低的预防措施。

【讨论】:

    【解决方案2】:

    你的问题

    当您想使用这些库时,您不能向您的 API 发送请求以隐藏 API 密钥。您必须在客户端代码中初始化这些库(例如反应)。

    保护客户端 SDK 和库的 API 密钥的最佳做法是什么?

    您发现自己是一个非常难以解决的问题(但在某种程度上并非不可能),因为一旦 API 密钥在客户端,它就是公开的。因此,无论您隐藏得多么好,始终可以在浏览器或移动应用上检索它。

    网络应用

    在浏览器上获取 API 密钥非常简单,只需打开开发人员工具并在网络选项卡中查找您有兴趣提取 API 密钥的请求,然后单击它以检查请求标头。

    移动应用

    在移动设备中,从移动应用程序中提取 API 密钥更加费力,但许多人可能认为这并不难。

    JNI/NDK - 在原生 C 代码中隐藏 API 密钥

    例如,您可以通过 JNI/NDK 隐藏 C 本机代码中的 API 密钥:

    使用 Android Studio 2.2 及更高版本,您可以使用 NDK 将 C 和 C++ 代码编译为本机库,然后使用 IDE 的集成构建系统 Gradle 将其打包到您的 APK 中。然后,您的 Java 代码可以通过 Java 本机接口 (JNI) 框架调用本机库中的函数。

    这种方法旨在保护 AP/i 密钥不被通过静态二进制分析从您的移动应用程序二进制文件中提取出来,例如 this repoblog post 我写道:

    在本文中,我们将使用 Android Hide Secrets 研究存储库,它是一个使用多种不同技术隐藏 API 密钥的虚拟移动应用程序。

    通过中间人攻击提取隐藏在本机 C 代码中的 API 密钥

    在上面的博文中,隐藏在 JNI/NDK 接口源代码中的 API 密钥无法通过静态二进制分析提取,但正如我在文章 Steal that Api Key with a Man in the Middle Attack 中演示的那样,通过中间人攻击很容易提取:

    为了帮助演示如何窃取 API 密钥,我在 Github 中构建并发布了适用于 Android 的 Currency Converter Demo 应用程序,它使用了我们在之前的 Android Hide Secrets 应用程序中使用的相同 JNI/NDK 技术来@ 987654329@.

    因此,在本文中,您将学习如何设置和运行中间人攻击,以拦截您控制的移动设备中的 https 流量,从而窃取 API 密钥。最后,您将了解如何缓解中间人攻击。

    通过证书固定防止中间人攻击

    防止中间人攻击的第一件事是使用证书固定,我在文章Securing HTTPS with Certificate Pinning中写了如何做到这一点:

    为了演示如何使用证书固定来保护您的移动应用和 API 服务器之间的 https 流量,我们将使用我在上一篇文章中使用的同一 Currency Converter Demo 移动应用。

    在本文中,我们将了解什么是证书固定、何时使用、如何在 Android 应用中实现它,以及它如何防止中间人攻击。

    我现在看到你脸上的笑容,但不会太久,因为可以绕过证书固定。

    绕过证书固定

    您可以在不固定或在运行时使用检测框架禁用它的情况下重新打包移动应用程序。

    重新打包移动应用程序以绕过固定

    当您拥有正确的工具并且开源充满了这些工具时,这并不难实现。我在Bypassing Certificate Pinning文章里写了怎么做

    在本文中,您将学习如何重新打包移动应用程序以使其信任自定义 ssl 证书。这将允许我们绕过证书固定。

    使用 Instrumentation Framework 绕过固定

    这是我的首选方法,我的首选仪表框架是 Frida,猜猜看,我还有一篇标题为 How to Bypass Certificate Pinning with Frida on an Android App 的文章向您展示如何做到这一点:

    今天我将展示如何使用 Frida 检测框架在运行时挂钩到移动应用程序并检测代码以执行成功的中间人攻击,即使移动应用程序已经实现了证书锁定。

    绕过证书固定并不太难,只是有点费力,并且允许攻击者详细了解移动应用程序如何与其 API 通信,然后使用相同的知识来自动化攻击或围绕它构建其他服务。

    可能的解决方案

    您可以采用一系列不同的方法和技术来保护您的 API 服务器和移动应用程序,但优先使用跨移动/网络应用程序和 API 服务器的安全解决方案。

    要使用的解决方案取决于您的威胁模型、预算和资源,我将在下面为您提供一些选项。

    对于移动应用

    我建议您阅读 this answer 我提出的问题如何保护移动应用程序的 API REST?,尤其是强化和屏蔽移动应用程序部分保护 API 服务器可能更好的解决方案

    对于网络应用程序

    您可以学习一些有用的技术来帮助您的 API 后端尝试仅响应来自您所期望的什么的请求,您的真正网络应用程序,为此我邀请您阅读 @987654335 @ 问题从应用程序调用中保护 api 数据,特别是专门用于保护 API 服务器的部分。

    你想加倍努力吗?

    在回答安全问题时,我总是喜欢参考 OWASP 基金会的出色工作。

    对于 APIS

    OWASP API Security Top 10

    OWASP API 安全项目旨在通过强调不安全 API 中的潜在风险并说明如何降低这些风险,为软件开发人员和安全评估人员提供价值。为了实现这一目标,OWASP API 安全项目将创建和维护一份 API 安全风险前 10 名文档,以及一个文档门户,用于在创建或评估 API 时提供最佳实践。

    对于移动应用

    OWASP Mobile Security Project - Top 10 risks

    OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

    OWASP - Mobile Security Testing Guide:

    移动安全测试指南 (MSTG) 是一本用于移动应用安全开发、测试和逆向工程的综合手册。

    对于网络应用程序

    The Web Security Testing Guide:

    OWASP Web 安全测试指南包括用户可以在自己的组织中实施的“最佳实践”渗透测试框架和描述测试最常见 Web 应用程序和 Web 服务安全问题的技术的“低级”渗透测试指南。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-16
      • 2020-09-28
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多