Google 协议缓冲区C++在面对恶意数据时实现稳定性和安全性
Google Protocol Buffers C++ implementation stability and security in the face of malicious data
对于那些使用Google协议缓冲区C++实现的人来说,它如何处理恶意或格式错误的消息?例如,它会崩溃还是继续运行? 我的应用程序肯定会在某个时候收到恶意数据,我不希望每次收到格式不正确的消息时它都会崩溃。这是我在这个问题上能找到的唯一答案(谷歌邮件列表)。
在代码发布之前,专门针对安全问题进行了审查。至少对于C++和Java实现,有各种保护措施可以防止损坏或恶意数据。protobuf 库提供的整体消息大小也有限制(CodedInputStream::SetTotalBytesLimit);它还提供递归限制,以防止深度嵌套的消息吹毁堆栈。还有其他内部实现细节可以避免内存耗尽等情况(最具体地说是接收指示巨大长度分隔值的消息)。
我在一个非常注重安全的面向Web的应用程序中使用C ++ Google协议缓冲区。
查看生成的代码,所有反序列化工作都委托给每条消息的<Message-Type>::MergePartialFromCodedStream
方法中自动生成的代码。这些方法是通过对数据类型和长度的全面检查生成的,到目前为止我们没有遇到任何问题。
您可能想要自己关闭的一个攻击领域是 protobuf 数据的框架 - 协议缓冲区本身不会将序列化消息的整体大小序列化为任何类型的标准化标头中的流,因此您可能希望(像我一样)将所有协议缓冲区消息包装在一个帧中。就我而言,帧标头仅包含消息大小,这意味着我能够在尝试从线路上读取消息之前确定消息的内存要求,更不用说解码了。
此时可以进行简单的检查,以拒绝消息(或断开连接),如果大小不可行。
可以做进一步的工作来将此帧包装在公钥包络方案中,以防止中间人劫持您的会话(如果这是一个问题)。
消息中的缓冲区溢出(例如字符串太长)不会发生,因为bytes
和string
字段在内部由 std::string
表示,当数据附加到它时,它会自动增加其内存占用量。
然而:
无法保证恶意客户端不会尝试对包含无效数据的有效消息进行编码。例如,如果您的服务器应用程序从数据字符串中获取方法名称,查找其地址并调用它,那么这是一个明显的攻击向量。
在未全面检查是否明确允许操作的情况下,绝不应允许客户端数据查找服务器代码。
一些绝对不能这样做的例子:
- 允许客户端在文本字段中向您发送 SQL
- 允许客户端向您发送命令行,随后您将其传递给
system()
、exec()
、spawn()
等。 - 允许客户端向您发送共享库的名称和其中的函数名称...
等等。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- Google 协议缓冲区C++在面对恶意数据时实现稳定性和安全性