Google 协议缓冲区C++在面对恶意数据时实现稳定性和安全性

Google Protocol Buffers C++ implementation stability and security in the face of malicious data

本文关键字:实现 稳定性 安全性 数据 恶意 缓冲区 协议 C++ 面对 Google      更新时间:2023-10-16

对于那些使用Google协议缓冲区C++实现的人来说,它如何处理恶意或格式错误的消息?例如,它会崩溃还是继续运行? 我的应用程序肯定会在某个时候收到恶意数据,我不希望每次收到格式不正确的消息时它都会崩溃。这是我在这个问题上能找到的唯一答案(谷歌邮件列表)。

在代码发布之前,专门针对安全问题进行了审查。至少对于C++和Java实现,有各种保护措施可以防止损坏或恶意数据。protobuf 库提供的整体消息大小也有限制(CodedInputStream::SetTotalBytesLimit);它还提供递归限制,以防止深度嵌套的消息吹毁堆栈。还有其他内部实现细节可以避免内存耗尽等情况(最具体地说是接收指示巨大长度分隔值的消息)。

我在一个非常注重安全的面向Web的应用程序中使用C ++ Google协议缓冲区。

查看生成的代码,所有反序列化工作都委托给每条消息的<Message-Type>::MergePartialFromCodedStream方法中自动生成的代码。这些方法是通过对数据类型和长度的全面检查生成的,到目前为止我们没有遇到任何问题。

您可能想要自己关闭的一个攻击领域是 protobuf 数据的框架 - 协议缓冲区本身不会将序列化消息的整体大小序列化为任何类型的标准化标头中的流,因此您可能希望(像我一样)将所有协议缓冲区消息包装在一个帧中。就我而言,帧标头仅包含消息大小,这意味着我能够在尝试从线路上读取消息之前确定消息的内存要求,更不用说解码了。

此时可以进行简单的检查,以拒绝消息(或断开连接),如果大小不可行。

可以做进一步的工作来将此帧包装在公钥包络方案中,以防止中间人劫持您的会话(如果这是一个问题)。

消息中的缓冲区溢出(例如字符串太长)不会发生,因为bytesstring字段在内部由 std::string 表示,当数据附加到它时,它会自动增加其内存占用量。

然而:

无法保证恶意客户端不会尝试对包含无效数据的有效消息进行编码。例如,如果您的服务器应用程序从数据字符串中获取方法名称,查找其地址并调用它,那么这是一个明显的攻击向量。

在未全面检查是否明确允许操作的情况下,绝不应允许客户端数据查找服务器代码。

一些绝对不能这样做的例子:

  1. 允许客户端在文本字段中向您发送 SQL
  2. 允许客户端向您发送命令行,随后您将其传递给system()exec()spawn()等。
  3. 允许客户端向您发送共享库的名称和其中的函数名称...

等等。