在开放 API 世界中,令牌是门钥匙(颁发给任何拥有有效客户端 ID 和秘密的人)。
我喜欢这个比喻:)
代币重要性
令牌允许拥有它们的任何人访问资源。因此,它们与密码一样重要。
更重要的是,因为它们控制对 API 的访问,因此使用被盗令牌的自动攻击可以在几秒钟、几分钟或几小时内过滤掉该 API 背后的所有数据,具体取决于数据的大小,如果速率限制或其他类型的防御措施到位,这就是一个名称,数据泄露,以及 GDPR 下的罚款可能是巨额,甚至可能使公司倒闭或陷入严重困境。
使用刷新令牌访问令牌
示例:想要访问您的 API 的第 3 方原生应用。该应用程序使用“客户端 ID 和机密”请求“访问令牌”。此访问令牌将用于后续 API 调用。
关注点:通常“访问令牌”具有较长的 TTL。当它们存储在移动应用程序/客户端移动设备中时,如果有人获得访问权限,他们将能够使用此访问令牌和 API URI 重放来自不同来源的 API 调用。
访问令牌应该至少是短暂的,客户端、移动应用或网络应用绝不应该是请求它被发布的人,而是它们各自的后端应该是向 OAUTH 请求它的人提供者,并使用刷新令牌机制来继续发行短期令牌,应该在几分钟的范围内。这种方法限制了恶意请求重复使用受损令牌的时间。
因此,我建议您改用刷新令牌,这将使访问令牌保持短暂的生命周期,而刷新令牌可以长期存在,但在小时范围内,而不是几天、几周或几年。
刷新令牌流程示例:
来源: Mobile API Security Techniques - part 2
注意:虽然上图属于一系列以移动 API 为背景的文章,但它们包含的大量信息也适用于为 Web 应用程序和第三方客户端提供服务的 API。
通过使用刷新令牌方法,当客户端请求因短期访问令牌过期而失败时,客户端需要请求新的短期访问令牌。
这里的重要一点是刷新令牌不应发送到浏览器或移动应用程序,只能发送短期访问令牌,因此您的第三方客户端必须将刷新令牌保密,也就是在他们的后端,因此他们不得从 javascript 或他们的移动应用程序发送刷新令牌,而是必须将短期访问令牌的任何更新委托给他们的后端。
这是一个很好的改进,但它只识别 谁 发出请求,而不是 什么 发出请求,因此您的 API 会继续运行而无法完全信任他们收到的请求来自可信来源。
哦,等等……谁和什么让我很困惑。嗯,你不是唯一的,这确实是开发人员之间的常见误解。
谁和what的区别在于访问API服务器。
这在我写的this article中有更详细的讨论,我们可以在这里阅读:
what 是向 API 服务器发出请求的事物。它真的是您的移动应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 之类的工具手动绕过您的 API 服务器?
谁是移动应用的用户,我们可以通过多种方式进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流。
如果引用的文字不足以让您理解差异,那么请继续阅读本文的整个部分,因为如果没有很好地理解这一点,您很容易在您的 API 服务器中应用不太有效的安全措施,并且客户。
API 重放攻击
对于 API 调用,您如何防止此类重放攻击(当访问令牌被第三方应用程序泄露时)?
这是一个非常需要解决的问题,因为您的 API 需要知道 什么 发出请求,而现在似乎只能知道请求是代表一些谁。
有关缓解 API 重放攻击的更深入方法,请阅读我在另一个问题中给出的this answer 中的缓解重放攻击部分:
因此,您可以让客户端使用请求 url、用户身份验证令牌、您的临时令牌和时间戳创建一个 HMAC 令牌,这些令牌也应该出现在请求标头中。然后,服务器将从请求中获取相同的数据并执行它自己的 HMAC 令牌计算,并且只有在它自己的结果与请求中的 HMAC 令牌标头匹配时才继续请求。
有关实际操作中的实际示例,您可以阅读this blog series 的第 1 部分和第 2 部分,了解移动应用上下文中的 API 保护技术,其中还包含一个模拟移动应用的网络应用。
它有一些 HMAC 实现的代码示例,所以我真的建议你看一看,但请记住,HMAC 只会让它更难破解,而不是不可能。
因此,当访问令牌属于 Web 应用程序时,这是一个非常难以解决的问题,但对于使用移动应用程序证明解决方案的移动应用程序来说,这是可行的,这在另一个 this section 中有所描述我写的文章,我将引用以下文字:
为了了解向 API 服务器发送请求的原因,移动应用证明服务将在运行时以高可信度识别您的移动应用存在、未被篡改/重新打包、未运行在有根设备中,尚未被检测框架(Frida、xPosed、Cydia 等)挂钩,并且不是Man in the Middle Attack (MitM) 的对象。这是通过在后台运行 SDK 来实现的,该 SDK 将与在云中运行的服务进行通信,以证明移动应用程序和运行它的设备的完整性。
为了在移动应用使用 API 时保护您的 API,我建议您阅读我为问题 如何保护移动应用的 API REST? (如果嗅探请求为您提供“密钥”)。对于网络应用程序,我建议您阅读my answer 中的网络应用程序部分到问题如何保护 REST-API?。
存储访问令牌
您遵循哪些安全做法来允许您的消费者/客户安全地存储“访问令牌”?
在网络应用程序中,提取任何令牌只需点击 F12 并查找它们,但在移动应用程序中,您需要对它们进行逆向工程。
对于移动应用程序,您可以通过查看存储库android-hide-secrets 来了解隐藏它们的几种方法,其中最有效的是使用原生C 代码,利用Android 提供的JNI/NDK 接口。您可以在 repo currency-converter-demo 和 shipfast-api-protection-demo 的应用程序中看到更多使用这种方法的实际使用演示应用程序。例如,参见here 如何使用JNI/NDK 方法从C code 加载配置。但请记住,虽然这使得对移动应用程序二进制文件进行静态逆向工程以提取机密非常困难,但它并没有为攻击者提供任何安全性来使用和检测框架来挂钩从返回机密的代码中C 代码,或者执行中间人攻击以拦截移动应用程序和后端之间的请求,从而掌握您保护得如此好的秘密。
移动应用程序可以通过使用移动应用程序证明解决方案来解决这个问题,使其代码中完全没有任何秘密,因此,如果您阅读了我之前提供的link,用于在移动应用程序使用时保护您的 API,那么您将更加熟悉移动应用证明的工作原理,并且能够更好地理解为什么您可能希望让您的客户像这样使用您的 API:
因此,您的 API 将与 API 部分中已有的 API 并排放置,访问它的秘密不再属于公共领域,而是安全地存储在反向代理保险库中。需要注意的是,绿色密钥是由云中的移动应用证明服务在运行时提供的,移动应用不知道是有效还是无效的 JWT 令牌。如果您还没有完成,请阅读我已经提供给其他答案的link,以便您更详细地了解证明的工作原理。
总之,这种方法不仅有利于您的 API,还可以提高客户移动应用的整体安全性。
加倍努力
像往常一样,如果不推荐 OWASP 基金会的出色工作,我无法完成与安全相关的答案:
The Web Security Testing Guide:
OWASP Web 安全测试指南包括用户可以在自己的组织中实施的“最佳实践”渗透测试框架和描述测试最常见 Web 应用程序和 Web 服务安全问题的技术的“低级”渗透测试指南。
The Mobile Security Testing Guide:
移动安全测试指南 (MSTG) 是一本用于移动应用安全开发、测试和逆向工程的综合手册。