保护API不被篡改?

信息安全 api 休息 保护 网络套接字 篡改
2021-08-14 11:47:30

我正在使用 websocket 构建一个通过 JSON 序列化数据的 API。该应用程序本身是一个聊天应用程序。我想出了以下结构来发送我的数据:

{date: '2020-05-31', time: '14:28:05', text: "Hey!", to: '<id:int>', from: '<id:int>'}

用户基本上通过浏览器发送消息,并在 websocket 服务器中接收。from: 'id'来自发送数据的用户,而to: 'id'将来自正在发送数据的用户。

看到这里,我有一种非常不好的感觉。我的想法; 理论上,使用该应用程序的用户将进行身份验证,这就是他获得身份的地方。然后接收者将有另一个 id,这与经过身份验证的 id 不同(显然)。然后服务器会查找该 ID 并发送消息,但我不确定这是否安全。

我认为必须正确处理某些方面以保护应用程序免受任何攻击者的侵害:

  • 如果攻击者决定篡改“ from:id”以便它可以从任何用户向任何人发送任意消息怎么办?
  • 如果攻击者利用“to:id”字段构建了一个向数百万条消息发送垃圾邮件的脚本怎么办?

是否可能还有另一个我不关心的安全问题?

4个回答

如果攻击者决定篡改“from:id”以便它可以从任何用户向任何人发送任意消息怎么办?

创建会话,并使用会话标识符作为标识符,而不是直接使用用户 ID。例如,让用户发送凭据,并在成功验证后返回一个(短期)会话句柄,该句柄可用于未来的消息中。

验证会话存在且处于活动状态,并将其映射回用户服务器端。

如果攻击者利用“to:id”字段构建了一个向数百万条消息发送垃圾邮件的脚本怎么办?

速率限制用户服务器端。例如,禁止每分钟向十个以上不同的用户发送消息。这可能不会打扰合法用户,但会妨碍垃圾邮件发送者的努力。显然可能需要调整限制 - 并且可能会根据行为为受信任的用户提高限制,并在收到来自用户的垃圾邮件报告时降低限制。

基本上,您必须将用户的每个输入都视为潜在恶意。

Vidarlo 已经在他的回答中提到了两个安全问题以及如何防止它们。

我还要补充一点,内容本身(“文本:”)可能包含恶意代码(例如 javascript 片段)。确保此代码不在接收端执行。

而且我还会检查时间是否正确。根据您的应用程序,验证时间戳可能很有用,甚至是必要的。

如果攻击者决定篡改“from:id”以便它可以从任何用户向任何人发送任意消息怎么办?

不要在你的 API 中使用 from:id。相反,您已经从用户身份验证的会话中知道它,并且用户首先将其传输给您的理由为零。如果没有什么可以传输,就没有什么可以篡改的。

在那张纸条上,也扔掉日期和时间。您已经知道何时收到消息并且不需要用户告诉您。如果您的应用程序 + API 有一些离线/计划/积压消息的概念,您只需要这些。

如果攻击者利用“to:id”字段构建了一个向数百万条消息发送垃圾邮件的脚本怎么办?

那是相当古老的,甚至是具有不同的经典问题,就像旧的解决方案一样。最简单的方法之一是引入超时:后端会记住用户何时发送消息,并且在一段时间过去之前他无法发送任何内容。一些更复杂的解决方案仍然可以归结为在一段时间内将用户限制为一定数量的消息,但会使用逐渐变大的延迟,随着更多消息的发送而逐渐减少。搜索“节流”或“速率限制”以获得一些例子和想法。

以下是如何解决这些问题的另一种观点。我假设正确实施了身份验证和会话管理。

如果攻击者决定篡改“from:id”以便它可以从任何用户向任何人发送任意消息怎么办?

如果您在创建时为每个“聊天室”生成一个唯一的(长的、随机的、很难猜到的,例如会话标识符)标识符,并确保所有各方都乐于加入该聊天室,您可以改用它用户标识符和控制每个用户可以向哪些聊天室发送消息,以确保其他人无法将内容发送到其他人的私人聊天;因此,来自用户 X 和 Y 的消息将被发送到聊天室 A,应用程序会将它们发送出去。用户 Z 未被允许进入,因此应用程序拒绝传递消息。

如果攻击者利用“to:id”字段构建了一个向数百万条消息发送垃圾邮件的脚本怎么办?

确保消息不能发送到用户标识符,并努力使用户标识符难以猜测。