php - 如何识别调用 API 端点的应用或网站?
问题描述
我们正在制作一个API
。PHP
我们希望API
端点只能由某些指定的应用程序和网站调用(而不是通过Postman或任何类似软件)。我们已经尝试通过调用发送一些身份验证密钥,但是有些工具甚至可以用于获取整个代码signed APK
(在 whatsApp 的 apk 上测试),因此密钥可能会泄露。
因此,我们正在尝试确定是否有一种方法可以向我们识别呼叫者应用程序或网站,API endpoint
然后我们将验证身份PHP
并提供response
相应的信息。
有什么办法可以做到这一点?如果没有,那么还有其他解决方法吗?
提前致谢。
解决方案
挑战
我们希望 API 端点只能由某些指定的应用程序和网站调用(而不是通过 Postman 或任何类似软件)。
好吧,你让自己面临了一个巨大的挑战,而且是一个非常需要解决的挑战。
在我深入研究细节之前,我可以说保护只服务于移动应用程序的 API 比同时服务于移动应用程序和 Web 应用程序的 API 更容易。
作为剧透警报,我可以说对于 Web 应用程序,API 服务器最好的机会是使用人工智能来防御没有真正的请求,而对于移动应用程序,当 API 服务器能够证明时,解决方案会更有效和简单发出请求的移动应用程序是真实且未经修改的应用程序。
逆向工程
Web 构建方式的性质使得在客户端内省代码变得非常容易,也就是说,您只需点击F12
或右键单击即可查看页面的页面源代码,从而轻松对任何自卫代码进行逆向工程或将用于识别应用程序的任何秘密提取到 API 服务器。
对于移动应用程序来说,这并不容易,但也不是那么难,因为我们有优秀的开源工具来帮助我们,比如移动安全框架 (MoBSF),它在一个 Web 界面下聚合了多个工具,这将使它成为轻而易举地逆向工程并提取签名 APK 的源代码和秘密,就像您使用 What's App 实现的那样:
We have tried to send some authentication key with the call but there are tools which can be used to get the entire code even from a signed APK(tested on the apk of whatsApp), so the key could get leaked.
正如我在本文中所展示的,移动应用程序中的秘密很难通过静态二进制分析来提取:
在本文中,我们将使用Android Hide Secrets研究存储库,它是一个虚拟移动应用程序,使用多种不同的技术隐藏 API 密钥。
上面的文章展示了如何使用原生JNI/NDK接口隐藏C
代码中的秘密,因此很难提取,但是你不能通过静态分析来做到这一点,你可以通过MiTM Proxy攻击动态地做到这一点,正如我在另一篇文章中所描述的:
为了帮助演示如何窃取 API 密钥,我在 Github 上构建并发布了适用于 Android 的Currency Converter Demo应用程序,它使用了我们在早期 Android Hide Secrets 应用程序中使用的相同 JNI/NDK 技术来隐藏 API 密钥.
访问 API 服务器的人与访问者之间的区别
因此,我们试图弄清楚是否有一种方法可以将调用者应用程序或网站识别到我们的 API 端点,然后我们将在 PHP 中验证身份并相应地给出响应。
因此,借助所有这些工具和对应用程序进行逆向工程的轻松访问,API 服务器很难区分谁在请求中和什么在执行请求,并理解谁和什么之间的区别对开发人员至关重要能够为其 API 服务器和应用程序定义安全策略。一旦这是一个经常被开发人员误解的概念,我建议您阅读我写的一篇文章的这一部分,该部分对其进行了更详细的解释,并从哪里引用:
向 API 服务器发出请求的内容是什么。它真的是您的移动应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 之类的工具手动绕过您的 API 服务器?
谁是移动应用程序的用户,我们可以通过多种方式进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流。
因此,将谁视为您的 API 服务器将能够对数据进行身份验证和授权访问的用户,并将其视为代表用户发出请求的软件,例如 Postman 或 cURL。
消除这种差异后,您现在可以更好地决定如何处理 API 服务器和应用程序的安全性。
识别请求中的谁和什么
有什么办法可以做到这一点?如果没有,那么还有其他解决方法吗?
要识别请求中的Who,您可以使用传统的身份验证和授权机制,或者使用OAuth2或OpenID Connect。
要识别请求中的What是挑战所在,因为您的 API 服务器需要区分Who和What,并且一些高级方法将使用用户行为分析 (UBA)来实现这一点。
UBA 解决方案的一个示例是 [Google reCAPTCHA V3 ],它不需要用户交互,并为 API 服务器给出请求来自人类的可能性的分数。
虽然这可以尽最大努力将人类与机器区分开来,但它不能提供非常高的信心,即您不会在误报中运行,但 UBA 的解决方案是您为 Web 应用程序提供服务的 API 服务器的最佳机会
对于服务于移动应用程序的 API 服务器,我们可以利用移动应用程序证明概念来有效地了解请求的内容,我建议您阅读我为问题How to secure an API REST for移动应用?,这将建议您有一个看起来像这样的最终解决方案:
阅读我链接的答案以了解移动应用程序证明将如何允许从移动应用程序中删除机密,并让您的 API 服务器高度自信地知道什么在执行请求。
你想加倍努力吗?
在回答安全问题时,我总是喜欢参考 OWASP 基金会的出色工作。
对于网络应用
OWASP Top 10 是一个强大的 Web 应用程序安全意识文档。它代表了对 Web 应用程序最关键的安全风险的广泛共识。项目成员包括来自世界各地的各种安全专家,他们分享了他们的专业知识来制作此列表。
OWASP Web 安全测试指南包括一个“最佳实践”渗透测试框架,用户可以在他们自己的组织中实施它和一个“低级”渗透测试指南,描述了测试最常见的 Web 应用程序和 Web 服务安全问题的技术。
对于移动应用
OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。
移动安全测试指南 (MSTG) 是移动应用安全开发、测试和逆向工程的综合手册。
对于 APIS
OWASP API 安全项目旨在通过强调不安全 API 的潜在风险并说明如何减轻这些风险,为软件开发人员和安全评估人员提供价值。为了促进实现这一目标,OWASP API 安全项目将创建和维护一个前 10 名 API 安全风险文档,以及一个文档门户,用于在创建或评估 API 时提供最佳实践。
链接参考
谷歌验证码 V3:
reCAPTCHA 是一项免费服务,可保护您的网站免受垃圾邮件和滥用。reCAPTCHA 使用高级风险分析引擎和自适应挑战来防止自动化软件在您的站点上参与滥用活动。它在让您的有效用户轻松通过的同时做到这一点。
...帮助您检测网站上的滥用流量,而不会产生任何用户摩擦。它会根据与您的网站的交互返回一个分数,并为您提供更多的灵活性来采取适当的行动。
Gartner 定义的用户行为分析 (UBA) 是一个关于检测内部威胁、有针对性的攻击和金融欺诈的网络安全流程。UBA 解决方案着眼于人类行为模式,然后应用算法和统计分析从这些模式中检测出有意义的异常——表明潜在威胁的异常。UBA 不是跟踪设备或安全事件,而是跟踪系统的用户。Apache Hadoop 等大数据平台正在增加 UBA 功能,允许它们分析 PB 级的数据以检测内部威胁和高级持续性威胁。
Mobile Security Framework 是一个自动化的一体化移动应用程序 (Android/iOS/Windows) 渗透测试框架,能够执行静态分析、动态分析、恶意软件分析和 Web API 测试。
OAuth 2.0 是行业标准的授权协议。OAuth 2.0 取代了 2006 年创建的原始 OAuth 协议所做的工作。OAuth 2.0 专注于客户端开发人员的简单性,同时为 Web 应用程序、桌面应用程序、移动电话和客厅设备提供特定的授权流程。该规范及其扩展正在IETF OAuth 工作组内开发。
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 功能与协议本身集成。
使用 Android Studio 2.2 及更高版本,您可以使用 NDK 将 C 和 C++ 代码编译为原生库,并使用 IDE 的集成构建系统 Gradle 将其打包到您的 APK 中。然后,您的 Java 代码可以通过 Java 本机接口 (JNI) 框架调用本机库中的函数。
推荐阅读
- postgresql - 聚合函数 bool_or() 是否有等效的 PostgresSQL 窗口函数(或替代过程)?
- kotlin - SerializationComponentRegistrar 与此版本的编译器不兼容
- node.js - node-postgres 池管理
- python - 执行 for 循环后列表值更改
- java - Hibernate 源代码中的 volatile 屏障将“与其他线程同步状态”。如何?
- asynchronous - 如何以任何特定顺序使用 Vuex 设置异步进程
- ruby-on-rails - 使用 Ruby on Rails 的 Sendgird 事务性电子邮件和模板
- python-3.x - 将用于实时人脸识别的 k 近邻 (KNN) 算法与 OpenCV 集成
- mysql - MySQL:`GROUP BY` 不包括某些相等的列
- java - 为什么 javaws.exe 每次更新都会移动到不同的文件夹?