针对恶意数据平衡速度和安全性的建议 [英] Recommendations for balancing speed and safety against malicious data

查看:69
本文介绍了针对恶意数据平衡速度和安全性的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,



我正在游戏客户端和服务器应用程序之间编写通信协议。我已经写了一些方法来从接收到的字符串构造一个数据包。



std :: map< int,PacketType> packetRegistry

PacketPlayerMove有ID 0

PacketPlayerChat有ID 1



所以如果 0,则从客户端收到ab12cd34ef56ab78,100,0,250 ,它的数据包ID为0,因此是PacketPlayerMove。其余参数作为std :: vector< string>传递给构造函数。这最终会在3D空间中的位置(100,0,250)处生成具有玩家ID ab12-cd34-ef56-ab78的PacketPlayerMove,并且这将被广播给其他玩家以移动世界中相应的玩家模型。



但是,我自然不能相信收到的字符串不是恶意的。我已经实现了一个检查,以确保数据包ID在packetRegistry中,但是我不确定是否应该费心去查看参数计数,长度,数据类型,或者格式的正则表达式等等。收到如巨大的字符串,可能会崩溃服务器。你会怎么推荐我处理这个?



我尝试了什么:



----------------------------------------------- -------------

Hello,

I'm writing a communications protocol between a game client and server application. I've written some methods to construct a packet from a received string.

std::map<int, PacketType> packetRegistry:
PacketPlayerMove has ID 0
PacketPlayerChat has ID 1

So if 0,ab12cd34ef56ab78,100,0,250 is received from the client, it's packet ID 0 and therefore a PacketPlayerMove. The remaining arguments are passed to the constructor as a std::vector<string>. This ends up producing a PacketPlayerMove with player ID ab12-cd34-ef56-ab78 at location (100, 0, 250) in 3D space, and this gets broadcast to the other players to move the corresponding player model in the world.

However, naturally I can't trust the received string to not be malicious. I've already implemented a check to ensure the packet ID is in the packetRegistry, but I'm not sure whether I should bother to check the parameter count, lengths, data types, perhaps regex for format, etc, in the event something nasty is received such as a huge string which could crash the server. How would you recommend I deal with this?

What I have tried:

------------------------------------------------------------

推荐答案

检查数据是必要的,以避免未定义的行为甚至让您的应用程序崩溃。我猜你正在使用UDP,因为你正在播放。然后数据可能不一致(很少但可能会发生)。



我建议不要使用字符串而是使用原始数据。这避免了与字符串(速度)之间的转换,并使数据包通常更小。您还可以提供校验和来删除无效数据包。



这样的数据包可能看起来像

Checking the data is necessary to avoid undefined behaviour or even letting your application crash. I guess that you are using UDP because you are broadcasting. Then data may be inconsistent (rare but may happen).

I suggest to not use strings but raw data instead. That avoids conversions to and from string (speed) and makes the packets usually smaller. You can also provide a checksum to drop invalid packets.

Such a packet might for example look like
typedef struct {
    uint32_t type; // Fixed packet type identifier
    uint32_t length; // Total length of packet
    uint32_t checksum; // Checksum over all following data
    uint32_t version; // Version: structure can be extended
    //uint32_t flags; // Optional flags defining which data are present
    uint32_t id;
    uint32_t loc_x;
    uint32_t loc_y;
    uint32_t loc_z;
    uint32_t name_len;
    uint8_t name[1]; // Placeholder for name
} net_packet_t;

如果你有要传递多个字符串(或任何其他具有可变长度的数据),请为长度值旁边的每个偏移值添加。然后你可以用它来定位下一个字段。

If you have to pass multiple strings (or any other data with variable length), add for each an offset value beside the length value. Then you can use that to locate the next field.


这篇关于针对恶意数据平衡速度和安全性的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆