【问题标题】:Google Protocol Buffers C++ implementation stability and security in the face of malicious dataGoogle Protocol Buffers C++ 实现面对恶意数据的稳定性和安全性
【发布时间】:2015-03-10 11:40:39
【问题描述】:

对于那些使用 Google Protocol Buffers C++ 实现的人,它如何处理恶意或格式错误的消息?例如,它会崩溃还是继续运行?我的应用程序肯定会在某个时候收到恶意数据,我不希望它在每次收到格式错误的消息时崩溃。这是我在这个问题上能找到的唯一答案 (google mailing list)。

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

【问题讨论】:

  • 使用HMAC 或至少某种形式的校验和。
  • 校验和不能防御恶意。身份验证是,至少使用适当的加密实现。
  • @MSalters 身份验证也不是真正的恶意防御......它只允许您识别(假设您的密钥/证书没有被泄露)谁是恶意的......跨度>
  • @twalberg:是的,但如果只有一个有效的发件人,或者预先知道一小部分,这就足够了。您可能需要额外的机制来在运行时添加有效的源。

标签: c++ security protocol-buffers


【解决方案1】:

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

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

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

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

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

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

但是:

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

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

一些绝对不能做的例子:

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

等等。

【讨论】:

  • 我同意这个答案。我要补充一点:作为一个安全专家,我永远不会断言我的代码是 100% 安全的。但作为大多数 Protobuf C++ 和 Java 库的作者,我可以告诉您,我从未意识到此代码中存在任何安全漏洞。 :)
  • "...协议缓冲区本身不会将序列化消息的整体大小序列化到任何标准化标头中的流中..." 是否会记录 GPB 对象的大小,例如,一个HTTP头?或许我应该先问:GPB 对象是通过 HTTP 交换的吗?
  • @RogerCostello 您可以将其记录在自定义标头、内容长度标头或您希望的任何其他协议中。我通过有线协议、http、总线消息、websockets 等传递 protobuf 消息。
  • @RogerCostello 但是,如果您通过 http 发送 protobuf 消息,您可能需要考虑编码为 base64 或 JSON(哪些协议缓冲区支持开箱即用 - 请参阅 include/protobuf/utils/ 目录)
  • 太棒了!谢谢@Richard Hodges!
猜你喜欢
  • 2013-06-05
  • 1970-01-01
  • 2011-09-15
  • 2011-05-06
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多