【问题标题】:Rest API security for mobile apps移动应用程序的 Rest API 安全性
【发布时间】:2017-03-20 21:54:23
【问题描述】:

我正在设计一个移动应用程序,该应用程序需要连接到服务器端进程以实现其业务逻辑和数据事务。我正在使用 Spring Boot 用 Ja​​va 编写服务器端代码,我打算创建一个 Rest API 以便移动应用程序连接到服务器。

我目前正在研究确保移动应用与服务器之间连接安全的最佳方式。我想做的是允许移动应用程序上的用户在打开应用程序后登录,并让他们使用该应用程序,只要他们喜欢,并且在一段时间不活动后访问超时。

任何人都可以推荐任何非常简单的阅读吗?我查看过 OAuth2,但这似乎是用于使用其他帐户(如 Google、GitHub 等)登录网络服务。

通过将用户名和密码传递给休息端点并返回某种令牌(GUID)来通过 https (SSL) 登录是否可以接受?然后让客户端(移动应用程序)在每个后续调用中传递该 GUID,以便服务器可以验证调用?在这种情况下,只通过 SSL 做所有事情会更好吗?

我已经进行了相当多的研究,但我似乎无法找到任何与我正在尝试做的事情完全匹配的东西。

希望有人能帮忙

谢谢

【问题讨论】:

    标签: java ios rest ssl mobile


    【解决方案1】:

    我通常做的是制作一个 JSON 网络令牌 (https://jwt.io/),然后自己处理会话。

    JWT 非常好,因为您只需要在服务器端定义一个密钥。只要您的客户能够传递您制作的字符串(例如在标头内),并且只要没有人可以检索您的密钥,您就可以确定您在创建令牌时推送的每个数据都是由您生成的。 (不要犹豫,用最强的加密算法)

    【讨论】:

    • 感谢您的帖子,这似乎正是我要找的东西
    【解决方案2】:

    对于安全连接,请使用 TLS 1.2 级别的 HTTPS。然后将服务器证书固定在应用程序中,这将防止 MITM 攻击。

    传递用户名和密码是安全的。您可以返回一个有时间限制的令牌,以便需要/希望进行进一步的身份验证。

    使用 HTTPS,除了 URL 的地址部分之外的所有内容都被加密。但要小心查询字符串,它可能会出现在服务器日志中。

    【讨论】:

      【解决方案3】:

      OAUTH2 不仅适用于网页

      任何人都可以推荐任何非常简单的阅读吗?

      我查看过 OAuth2,但这似乎是用于使用其他帐户(如 Google、GitHub 等)登录网络服务。

      No OAUTH2 不仅适用于 Web 应用程序也适用于移动应用程序,您阅读this article 以获得更深入的解释,但我将把文章介绍留给您:

      与单页应用程序一样,移动应用程序也无法保持客户端机密的机密性。因此,移动应用程序还必须使用不需要客户端密码的 OAuth 流。当前的最佳实践是在启动外部浏览器的同时使用授权流程,以确保本机应用程序无法修改浏览器窗口或检查内容。如果该服务支持 PKCE,那么就会为移动和本机应用程序流增加一层安全性。

      链接的文章非常简短,您需要按照接下来的章节来了解全文。

      不要滚动您自己的身份验证/授权解决方案

      通过将用户名和密码传递给休息端点并返回某种令牌(GUID)来通过 https (SSL) 登录是否可以接受?然后让客户端(移动应用程序)在每个后续调用中传递该 GUID,以便服务器可以验证调用?

      虽然您可以做到,但我强烈建议您使用已经建立的 OAUTH2 或 OPENID 连接解决方​​案,因为它们是由该领域的专家开发和维护的,并经过数百万使用它们的网络和移动应用程序的实战测试。这使得任何人都可以在自己的内部解决方案中更快地识别和修复安全问题。

      OAuth2

      OAuth 2.0 是用于授权的行业标准协议。 OAuth 2.0 取代了 2006 年创建的原始 OAuth 协议所做的工作。OAuth 2.0 专注于客户端开发人员的简单性,同时为 Web 应用程序、桌面应用程序、移动电话和客厅设备提供特定的授权流程。该规范及其扩展正在IETF OAuth Working Group 内开发。

      OpenID Connect

      OpenID Connect 1.0 是 OAuth 2.0 协议之上的简单身份层。它允许客户端根据授权服务器执行的身份验证验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终​​用户的基本配置文件信息。 OpenID Connect 执行许多与 OpenID 2.0 相同的任务,但以 API 友好的方式执行,并且可用于本机和移动应用程序。 OpenID Connect 定义了健壮签名和加密的可选机制。虽然 OAuth 1.0a 和 OpenID 2.0 的集成需要扩展,但在 OpenID Connect 中,OAuth 2.0 功能与协议本身集成。

      因此,对于您的身份验证/授权需求,我建议您使用 OpenID 连接解决方​​案,该解决方案在后台利用 OAuth2。

      始终需要 SSL?

      在这种情况下只通过 SSL 做所有事情会更好吗?

      SSL 必须始终用于一切,在任何情况下都不得使用 http,因为一旦您允许 http 请求,您就容易受到中间人攻击,我强烈建议您阅读this article from一位知名的安全研究员 Troy Hunt 了解即使是静态网站也必须使用 https,他在很大程度上解释了为什么并命名了非常重要的攻击媒介,这些攻击媒介可能会损害不使用 https 的应用程序,例如 WiFi 热点劫持、DNS 劫持、路由器漏洞利用、中国大炮等。

      通过证书固定改进 SSL

      使用 https 进行通信是适用于任何类型的应用程序的方式,但开发人员必须意识到,控制安装应用程序的设备的攻击者可以通过安装自定义证书的中间人攻击来监视 https 流量在设备中安装了 mobiel 应用程序,从而使他能够通过这种方式了解移动应用程序如何与 API 服务器通信,以便对来自同一 API 的滥用进行自动攻击。

      Certificate Pinning

      固定是将主机与其预期的 X509 证书或公钥相关联的过程。一旦知道或看到主机的证书或公钥,证书或公钥就与主机相关联或“固定”到主机。如果可以接受多个证书或公钥,则程序会保存一个 pinset(取自 Jon Larimer 和 Kenny Root Google I/O talk)。在这种情况下,所宣传的身份必须与 pinset 中的元素之一匹配。

      您可以阅读this article,通过代码示例了解实现证书锁定有多容易,在操作方面维护起来有多困难,并通过视频了解攻击者如何绕过通过证书锁定客户端使用 Xposed 框架。

      xPosed

      Xposed 是一个模块框架,可以在不触及任何 APK 的情况下改变系统和应用的行为。这很棒,因为这意味着模块可以在不同版本甚至 ROM 上工作而无需任何更改(只要原始代码没有太大更改)。它也很容易撤消。

      编辑:

      现在,您可以使用移动证书固定生成器来帮助您在移动应用中实施证书固定:

      这将为您提供适用于 Android 和 iOS 的即用型固定配置:

      寻找解决方案

      在向您指出一个可能的解决方案之前,我想明确区分开发人员经常不知道或认为是同一事物的两个概念之间的区别...

      访问 API 服务器的对象和对象的区别

      WHO 是移动应用程序的用户,您可以通过多种方式进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流。

      现在您需要一种方法来识别 什么 正在调用您的 API 服务器,而这里的事情变得比大多数开发人员想象的要棘手。 WHAT 是向 API 服务器发出请求的东西,它真的是您真正的移动应用程序,还是机器人、自动脚本或攻击者使用 Postman 之类的工具手动绕过您的 API 服务器?

      为了识别什么,开发人员倾向于求助于 API 密钥,通常他们将其硬编码在他们的移动应用程序的代码中,有些人会加倍努力并在运行时计算它移动应用程序因此成为动态秘密,而不是前一种方法,即嵌入在代码中的静态秘密。

      一些移动 API 安全技术

      我已经进行了相当多的研究,但我似乎无法找到任何与我正在尝试做的事情完全匹配的东西。

      您可以先阅读this series 有关移动 API 安全技术的文章,了解如何使用 Https、证书固定、APi 密钥、HMAC、OAuth2 和其他技术来保护您的移动应用程序和 API 之间的通信通道服务,以及如何绕过它们。

      要解决 什么 访问您的移动应用程序的问题,您需要使用我上面提到的关于移动 API 安全技术的系列文章中提到的一个或所有解决方案,并接受它们可以只会使对您的 API 服务器的未经授权的访问更难绕过,但并非不可能。

      使用移动应用证明解决方案可以采用更好的解决方案,使 API 服务器知道只接收来自真正移动应用的请求。

      可能的更好解决方案

      使用移动应用证明解决方案将使 API 服务器能够知道什么正在发送请求,从而允许仅响应来自真正的移动应用的请求,同时拒绝来自不安全的所有其他请求来源。

      移动应用证明服务的作用是在运行时通过在后台运行 SDK 来保证您的移动应用没有被篡改或没有在根设备中运行,该 SDK 将与在云中运行的服务进行通信以证明移动应用程序和正在运行的设备的完整性。

      成功证明移动应用程序的完整性后,会发布一个短期 JWT 令牌,并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。如果移动应用证明失败,JWT 令牌会使用 API 服务器不知道的秘密进行签名。

      现在,应用程序必须在每个 API 调用中发送请求标头中的 JWT 令牌。这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和过期时间时服务请求,并在验证失败时拒绝它们。

      一旦移动应用程序不知道移动应用程序证明服务使用的秘密,即使应用程序被篡改、在有根设备中运行或通过正在成为中间人攻击的目标。

      这是一个不会发生误报的积极模型,因此 API 服务器能够拒绝请求,而不会阻止您的移动应用的合法用户。

      Mobile App Attestation 服务已作为 SAAS 解决方案存在于Approov(我在这里工作),它为多个平台提供 SDK,包括 iOS、Android、React Native 等。集成还需要对 API 服务器代码进行小检查,以验证云服务发布的 JWT 令牌。此检查对于 API 服务器能够决定服务哪些请求和拒绝哪些请求是必要的。

      结论

      正确保护移动应用和 API 服务器是一项由多层防御组成的任务,您必须将它们放在一起才能保护它。

      使用多少层取决于您要保护的数据、它对业务的价值、在数据泄露中泄露时可能造成的损害以及您可能会受到执法部门的处罚,例如 GDPR 在欧洲。

      【讨论】:

      • 即使使用 Oauth 进行身份验证,应用服务器也需要将 cookie 或 jwt 发送给用户,以便能够识别用户的后续调用。如何防止窃取 cookie 或 jwt?
      • 您需要阅读Improve SSL with Certificate PinningResearching a SolutionA Possible Better Solution 部分并点击文章的链接,以便更好地了解不同的方法及其权衡取舍。帮助您在后端识别 WHAT 正在发出 API 请求。我可以告诉你,证书固定是任何移动应用程序都必须具备的。对于网络应用,您需要使用 reCaptcha 和指纹解决方案来帮助您在后端识别 什么 发出请求。
      【解决方案4】:

      再次感谢这些回复。我一直在使用 server.ssl.key-store 参数实现我的服务以在 https 下运行,它看起来工作正常。我使用 keytool.exe 创建了一个信任库,并使用该信任库运行了我的 SpringBoot 应用程序(嵌入了 Tomcat)。我可以打开一个浏览器到我的 REST 端点(这次使用 https,而不是 http),浏览器要求进行身份验证,当我输入我的用户详细信息时,它会将它们与我的 db 用户进行匹配,并允许我查看来自服务器的响应。

      但有一个问题,如果我可以使用任何旧浏览器访问 REST 端点并输入我的用户名和密码,那么在服务器端 (Java) 建立信任存储有什么意义?最终,不会通过浏览器访问这个 REST 端点,而是使用移动应用程序以编程方式访问它,所以我假设我将使用用户名和密码通过 https 登录。我认为我需要在客户端获得某种证书才能进行通信,或者它不是这样工作的吗?

      再次感谢

      【讨论】:

        猜你喜欢
        • 2019-11-07
        • 2017-06-24
        • 2016-12-11
        • 1970-01-01
        • 2013-02-22
        • 1970-01-01
        • 1970-01-01
        • 2013-11-27
        • 1970-01-01
        相关资源
        最近更新 更多