将API请求限制为仅限我自己的移动应用

时间:2014-01-30 19:18:33

标签: android ios security mobile

有没有办法将对我的REST API的帖子请求限制为来自我自己的移动应用二进制文件的请求?此应用程序将在Google Play和Apple App Store上发布,因此应该暗示有人可以访问其二进制文件并尝试对其进行反向工程。

我在考虑涉及应用程序签名的内容,因为每个已发布的应用程序都必须以某种方式签名,但我无法弄清楚如何以安全的方式执行此操作。也许结合获取应用程序签名,加上基于时间的哈希,以及应用程序生成的密钥对和良好的旧安全性,虽然默默无闻?

我正在寻找尽可能失败证明的东西。原因是因为我需要根据手机传感器收集的数据向应用程序提供数据,如果人们可以伪装成我自己的应用程序并将数据发送到我自己的算法未处理的api,它就会失败目的

无论多么复杂,我都愿意接受任何有效的解决方案。锡箔帽解决方案非常受欢迎。

6 个答案:

答案 0 :(得分:17)

用户可以公开应用程序中存储的任何凭据。对于Android,他们可以完全反编译您的应用并轻松检索它们。

如果与服务器的连接不使用SSL,则可以轻松地从网络中嗅探它们。

说真的,任何想要凭据的人都会得到它们,所以不要担心隐藏它们。实质上,您有一个公共API。

存在一些陷阱,管理公共API需要额外的时间。

许多公共API仍然按IP地址跟踪并实施tarpits,以简化任何似乎滥用系统的IP地址的请求。这样,来自同一IP地址的合法用户仍然可以继续,尽管速度较慢。

您必须愿意关闭IP地址或IP地址范围,尽管您可能会在滥用者的同时阻止无辜和正直的用户。如果您的申请是免费的,它可能会给您更多的自由,因为没有预期的服务水平和合同,但您可能希望通过法律协议保护自己。

一般来说,如果你的服务很受欢迎,有人想攻击它,那通常是一个好兆头,所以不要过早担心它,但要保持领先。您不希望应用程序失败的原因是因为用户厌倦了在慢速服务器上等待。

您的另一个选择是让用户注册,这样您就可以在发现滥用行为时使用凭据而不是IP地址进行阻止。

答案 1 :(得分:9)

没有。您正在发布具有公共界面的服务,您的应用程序可能只通过此REST API进行通信。您的应用可以发送的任何内容,其他人也可以发送。这意味着保护访问的唯一方法是以某种方式进行身份验证,即保密。但是,您也在发布您的应用。这意味着您的应用程序中的任何秘密基本上也被赋予了。你无法双管齐下;你不能指望两者都透露你的秘密并保守秘密。

答案 2 :(得分:8)

是的,是公开的

此应用程序将在Google Play和Apple App Store上分发,因此应暗示有人可以访问其二进制文件并尝试对其进行反向工程。

从商店公开之日起,因此,对于应用程序二进制文件敏感的任何内容都必须视为可能受到威胁。

WHO和访问API服务器之间的区别

在深入探讨您的问题之前,我想先消除对什么正在访问API服务器的误解。我写了一系列有关API和移动安全的文章,在Why Does Your Mobile App Need An Api Key?文章中,您可以详细了解什么在访问您的API之间的区别服务器,但我将从此处提取其主要内容:

什么是向API服务器发出请求的东西。它确实是您的移动应用程序的真正实例,还是机器人,自动脚本还是攻击者使用诸如Postman之类的工具手动在您的API服务器上闲逛?

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

考虑,您的API服务器将能够对用户进行身份验证和授权访问数据,并考虑什么作为发出请求的软件代表用户。

因此,如果您未在应用程序中使用用户身份验证,则可以尝试证明正在执行的操作

移动应用程序应该尽可能哑巴

之所以这样,是因为我需要根据手机传感器收集的数据将数据传送到应用程序,并且如果人们可以冒充我自己的应用程序并将数据发送到未经我自己的算法处理的api,它达不到目的。

在我看来,您是说您正在手机上运行算法,以处理来自设备传感器的数据,然后将其发送到API服务器。如果是这样,那么您应该重新考虑这种方法,而只是收集传感器值并将其发送到API服务器,并使其运行算法。

正如我所说,您的应用程序二进制文件中的任何内容都是公开的,因为正如您自己所说,可以对其进行反向工程:

应暗示某人将有权访问其二进制文件并尝试对其进行反向工程。

保留后端的算法将使您无法透露自己的业务逻辑,同时,您可能会拒绝带有不合理的传感器读数的请求(如果可能的话)。这还带给您的好处是,每次调整算法或修复其中的错误时,都不必发布新版本的应用程序。

运行时攻击

我一直在考虑涉及应用程序签名的问题,因为每个发布的应用程序都必须以某种方式进行签名,但是我不知道如何以安全的方式进行操作。

您可以在运行时为保护即将发送到API的请求所做的任何事情,都可以使用Frida之类的工具进行反向工程:

将您自己的脚本注入黑盒进程。挂钩任何功能,监视加密API或跟踪私有应用程序代码,不需要任何源代码。编辑,点击保存,立即查看结果。全部没有编译步骤或程序重新启动。

您建议的解决方案

安全性完全是防御层,因此您应该添加法律所能承受和要求的范围(例如欧洲的GDPR),因此,任何有针对性的解决方案都是攻击者需要绕过的另一层,并且取决于技能和时间是您愿意花在您的移动应用程序上的,这可能会使他们无法继续前进,但是最终所有这些都可以绕开。

也许是获得应用程序签名,基于时间的哈希值,加上应用程序生成的密钥对以及良好的旧安全性(尽管晦涩难懂)的组合?

即使您使用存储在硬件受信任执行环境中的密钥对,攻击者所需要做的就是使用一种检测框架来挂钩使用密钥的代码功能,以提取或操作参数,并函数的返回值。

Android Hardware-backed Keystore

片上系统(SoC)中受信任执行环境的可用性为Android设备提供了向Android OS,平台服务甚至第三方应用程序提供硬件支持的强大安全服务的机会。

虽然它可以被击败,但我仍然建议您使用它,因为不是所有的黑客都具备技巧或愿意花时间在上面,我建议您阅读this series有关移动的文章API安全技术,以了解与您描述的技术互补/相似的技术。本文将教您如何使用API​​密钥,用户访问令牌,HMAC和TLS固定来保护API以及如何绕过它们。

可能更好的解决方案

如今,我看到开发人员正在使用Android SafetyNet来证明正在做什么正在向API服务器发送请求,但是他们不明白这并不是要证明移动应用程序是什么正在执行请求,而是旨在证明设备的完整性,我在my answer上更详细地讨论了与ios devicecheck等效的Android 问题。那我应该使用它吗?是的,您应该这样做,因为这是另一层防御,在这种情况下,您会告诉您除非已绕过SafetyNet,否则您的移动应用程序未安装在有根设备中。

有什么方法可以将发帖请求限制为仅来自我自己的移动应用二进制文件的REST API吗?

通过实现Mobile App Attestation概念,您可以让API服务器具有高度的信心,使其确实只接受来自您真正的应用程序二进制文件的请求,我在this answer中对此进行了详细描述问题如何保护移动应用程序的API REST?,特别是保护API服务器可能的更好解决方案部分。 >

您要参加“额外里程”吗?

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

对于APIS

OWASP API Security Top 10

OWASP API安全项目旨在通过强调不安全API中的潜在风险并说明如何减轻这些风险来为软件开发人员和安全评估人员提供价值。为了实现此目标,OWASP API安全项目将创建和维护“十大API安全风险”文档,以及用于创建或评估API的最佳实践的文档门户。

对于移动应用

OWASP Mobile Security Project - Top 10 risks

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

OWASP - Mobile Security Testing Guide

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

答案 3 :(得分:2)

正如其他答案和评论所暗示的那样,您无法真正限制API访问仅适用于您的应用,但您可以采取不同的措施来减少尝试。我相信最好的解决方案是使用自定义标头向您的API发送请求(当然来自本机代码),例如" App-Version-Key" (此密钥将在编译时决定)并让您的服务器检查此密钥以确定它是应该接受还是拒绝。此外,使用此方法时,您应该使用HTTPS / SSL,因为这样可以通过查看网络上的请求来降低人们看到您密钥的风险。

关于Cordova / Phonegap应用程序,我将创建一个插件来执行上述方法。完成后我会更新此评论。

答案 4 :(得分:2)

尽管这是一篇老文章,但我认为我应该在这方面分享Google的更新。

您实际上可以确保您的Android应用程序正在使用SafetyNet mobile attestation APIs调用API。这会增加网络调用的开销,并阻止您的应用程序在有根设备中运行。

我没有找到与iOS的SafetyNet类似的东西。因此,就我而言,我首先在登录API中检查了设备配置,并对Android和iOS采取了不同的措施。对于iOS,我决定在服务器和应用程序之间保留一个共享密钥。由于iOS应用程序难以逆向工程,因此我认为这种额外的密钥检查会增加一些保护。

当然,在两种情况下,您都需要通过HTTPS进行通信。

答案 5 :(得分:1)

你无能为力。因为当你让一些人可以调用你的API时。你能做的最多就是:

既然你只想要你的应用程序(带有特定的包名和签名)来调用你的API,你就可以实际获得apk的签名密钥,并且在每个API调用中发送都是切断的,如果可以,你就回复请求。 (或者您可以拥有一个令牌API,您的应用程序会在应用程序的每个开头调用它,然后将该令牌用于其他API - 尽管令牌必须在几个小时不使用后失效)

然后你需要预测你的代码,这样就没有人看到你发送的内容以及你如何加密它们。如果你做了一个很好的加密反编译就很难做到。

即使是apk的签名也可以通过一些艰难的方式进行嘲弄,但它是你能做到的最好的。