【问题标题】:Prevent Length-Based Message Framing tampering?防止基于长度的消息帧篡改?
【发布时间】:2019-03-03 06:49:49
【问题描述】:

对于基于 TCP 的网络应用程序,我使用基于长度的消息帧传输数据。很简单,一个包长这样:

[Length][Data]

Length 是一个 Int32,告诉我即将到来的原始数据的长度。

我阅读了 Int 并像这样创建了一个 byte array

//Read Int
activePacketLength = (Int32)(bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24));
packetBuffer = new byte[activePacketLength]; //Create buffer

然后我读到我读了 x 个字节。它工作正常,但如果一些有趣的用户给我发这样的东西怎么办:

0xFF 0xFF 0xFF 0x7F 0x01 0x02 0x03 ... {and so on}

我的代码将创建一个新的byte array,大小为int.MaxValue (~ 2GB),并且会读取数据直到我得到一个OutOfMemoryException 左右...

什么是防止回火的好方法?我可以实施大小限制(例如,每个数据包 1MB,高于此值的所有内容都会丢弃客户端并阻止它),但是否有更多“标准”解决方案不会让人觉得很 hacky?

【问题讨论】:

  • 实际上,四个 0xFF 字节会在您转换为已签名的 Int32 时产生 -1。无论如何,发送那将是一个错误的客户端。您可以防范明显超出范围的值,但我不会太担心。
  • 是的,我第一次使用 UInt。我会改变问题:) 所以你认为我应该限制它并根据我的需要调整值?

标签: c# networking tcp


【解决方案1】:

由于您无法阻止客户端发送您认为无效的数据,因此您必须检查数据是否无效。这包括将帧的长度(以及因此长度前缀的值)限制为非恶意客户端所期望的最大大小。如果身份验证是协议的一部分,那么最好有两个限制:一个用于未经过身份验证的客户端的小限制,它应该只允许身份验证所需的帧大小,然后对经过身份验证的客户端设置一个更大的限制。

【讨论】:

  • 这是一个好主意,有不同的限制。我想我会以这种方式实现它,即使这种方法对我来说感觉“业余”,但这只是我,我认为没有其他解决方案。感谢您的回答!
猜你喜欢
  • 2017-04-30
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
相关资源
最近更新 更多