保护用于移动访问的 API

信息安全 验证 移动的 网络服务 休息
2021-09-03 02:14:01

我构建了一个不错的 REST/JSON API,其他公司(我们的客户)将其用作 B2B 服务。我们的每个客户都有一个用户名/密码对,我们还使用 HTTPS 并验证服务请求的源 IP。使用服务需要花钱,客户按月收取服务使用费。

现在,一些客户正在构建他们分发给用户(B2C - 最终用户)的移动应用程序。并非我们服务的所有这些最终用户都有服务器,并且他们希望直接从智能手机使用服务(从技术上讲,JSON/REST 没什么大不了的)。

问题是我不确定如何保护服务免受欺诈。什么会阻止第三方开发人员反汇编客户的移动应用程序并复制他们的用户名/密码/任何安全凭证并在他的应用程序中使用?这将允许他使用该服务并向我们的一位合法客户收取使用费!

我很确定这个问题没有完美的加密解决方案,除非最终用户被要求对某些服务器进行身份验证。但情况并非总是如此。

作为最后的手段,我想我可以为 Android / iPhone 分发一个混淆库,这至少会给人一种安全的错觉......

编辑(澄清):

让我试着简化一下场景。

  1. 我有一个不可破解的 Web 服务器,它提供 JSON REST API。
  2. 移动客户端直接访问我的 API。他们的 IP 无法验证。他们正在运行标准操作系统(Android / IOS)。
  3. 不涉及其他服务器。
  4. 我无法访问手机的 IMEI(它被认为是私人的),这对我也没有帮助,因为我不认识最终用户。
  5. 有几个这样的合法移动应用程序,由访问我们 API 的不同公司开发。
  6. 当前的安全性(用户名/密码)很容易被流氓公司破解。所述流氓公司反汇编合法的移动应用程序并将用户名/密码复制到他们的非法应用程序中。他们分发此应用程序和利润(API 使用由他们窃取凭据的公司收取)。

这可以停止吗?

4个回答

您的问题是“这可以停止吗?”,但我觉得系统的任何重要内容都不能/不会真正改变。

如果我理解正确,您是在问(简化):

我有许多客户共享相同的用户名和密码。我可以停止滥用吗?

答案是否定的。您必须决定是否有能力忽略该问题,或实施正确的解决方案。

如果您真的想正确执行此操作,请考虑实施 OAuth 之类的东西,以便您可以为最终用户正确分发单独的身份验证令牌,将它们链接到您的客户端进行计费,撤销访问等。

--

您至少应该允许您的客户(公司)选择使用更好的身份验证方案。因此,例如,您为他们创建一个 API 来为他们的最终用户请求(和撤销)单独的访问令牌。

  • A 公司从他们的服务器请求令牌(这是由他们的应用程序发起的,告诉他们“给我一个令牌”)
  • 你返回token N,记录它所属的公司
  • 如果 Company As 应用程序连接到您的服务,它会发送令牌 N,而不是用户名/密码
  • A 公司可以告诉您的服务“撤销令牌 N”,并且您的服务将不会处理具有该令牌的进一步请求。但是,如果一个令牌被撤销,它不会使所有客户端应用程序不可用。

如果公司不想这样做,他们仍然可以使用他们的用户名/密码继续连接,但他们将对所有由此产生的使用负全部责任。

关键是,如果他们没有其他方式使用该服务,您就不能真正让您的客户对泄露凭证(在移动应用程序场景中不可能做到的事情)负责。

所以我希望我有这个正确的。您想要一种使用有效 API 密钥确认客户端身份的安全方式吗?我认为安全存储 API 密钥主要由开发应用程序的公司负责,而不是您的公司。

您将需要加密和混淆密钥以保护它免受临时黑客的攻击,但我认为您永远无法阻止坚定的黑客。你可以做一些hackery来使二进制文件更难调试,这可能会减少你的应用程序在互联网上浮动的机会。然而,这并不是绝对的安全,除非您的公司正在内部开发应用程序,否则您如何执行这些措施?

因此,作为对您的方案的回答,不,我认为不能在不损害用户体验的情况下有效地阻止它。您可以使用您的 API 对公司进行教育——为他们整理一本小手册,并确保他们有责任确保api 密钥的安全。

最后,您还可以实现一些缓解功能。例如:

  1. 允许公司定义自己的硬性限制。假设公司 A 知道上个月他们下载了 N 个应用程序,因此希望将他们对您的 API 的访问限制为每天或每小时 X 个请求。
  2. 监控每个时间段内每家公司的任何请求高峰。
  3. 定义可能发生的潜在欺诈活动的程序步骤。
  4. 重新键入,重新键入和重新键入。

失败的目标(它发生在最好的情况下)是尽量减少损失。

祝你好运。

您对您的客户将他们的用户名/密码嵌入他们分发给所有用户的移动应用程序持怀疑态度是正确的。正如您已经正确识别的那样,一些攻击者很容易反汇编该移动应用程序,从移动应用程序中提取用户名/密码,并在他们自己的应用程序中使用它。不幸的是,您的客户是决定是否这样做的人,但费用由您承担。所以,这是一种外部性,你需要一些方法来使成本、风险和激励措施更好地协调一致。我在下面有一些关于如何做到这一点的建议。

一般来说,我看到了两个可行的解决方案:

  • 风险转移。对于每个客户端,限制您将从该客户端接受的请求数量。告诉客户,他们有责任确保他们的用户名/密码安全,所有使用此用户名/密码到达的请求都将计入他们的限制,如果到达的请求太多,他们的帐户可能会被禁用。告诉他们,如果他们将自己的用户名/密码嵌入到移动应用程序中,那么不法分子可能会窃取用户名/密码并使用它来发出许多请求,从而导致他们的帐户被禁用并且他们的移动应用程序停止工作. 让他们决定是否愿意冒险。

  • 合同要求。告诉您的客户他们被禁止与他人分享他们的用户名/密码,并且不允许他们将他们的用户名/密码嵌入到其他人可以下载的应用程序中。告诉他们,如果您检测到任何违反此政策的行为,他们的帐户可能会被禁用,并且可能会向他们收取由此对您的服务器造成的任何费用。

    如果您的客户想要创建一个移动应用程序,请告诉您的客户,与其在移动应用程序中嵌入他们自己的用户名/密码,不如在他们自己的服务器上代理此类请求。换句话说,客户端应该设置一个知道客户端的用户名/密码的服务器,但是这个用户名/密码不应该嵌入到移动应用程序中。客户端的移动应用程序应向客户端的服务器进行身份验证,向服务器发送请求,然后服务器应将请求转发给您并将响应转发回移动应用程序。他们的服务器应该验证最终用户(例如,要求移动应用程序的每个最终用户在他们的服务器上创建一个帐户,使用他们自己的用户名/密码)。他们的服务器应该对每个用户施加带宽限制,

您还可以允许客户在这两个选项之间进行选择:例如,在有限带宽帐户(具有风险转移)或无限带宽帐户(要求不要将用户名/密码嵌入其他人可以访问的应用程序中)之间进行选择)。

我希望这是有道理的。这可能有点令人困惑,因为存在三方——您、您的客户和您客户的最终用户——每一方都有自己的兴趣和关注点。我希望我已经充分区分了这三者。

我认为您将在移动端面临的问题之一是 IP 地址验证。通常,由电信公司分配的移动 IP 地址将被净网。网络IP会使服务器端采用的IP验证机制失效。

在 Android 和 Iphone 上实施该解决方案;我认为方法应该是:

  1. 将 SSL 模式下的客户端服务器身份验证也扩展到客户端证书验证。我的意思是让客户端和服务器都使用证书来建立安全的 SSL 会话。
  2. 以需要 PIN 以及 IMEI 和 IMSI 号码组合的方式交付包含客户端证书(移动)的 PFX/P12。这样,攻击者就很难拒绝同一个会话。
  3. 在服务器上实施一些人工智能,检测使用相同客户端证书启动的两个或多个并发会话,这将让您知道发生了一些妥协,服务器可以立即将证书列入黑名单或撤销证书以供进一步使用。

我相信虽然我们正在讨论移动环境;除了 IP 验证,风险也存在于 PC 环境中。将来,如果您遇到客户提出的一些错误计费问题,您也可以在 PC 环境中采用或迁移到基于签名和基于客户端证书的实施。