• 注册
  • SPTarkov 动态 SPTarkov 动态 关注:243 内容:59

    EFT internals research: Response caching

  • 查看作者
  • 打赏作者
  • 当前位置: ODDBA社区 > SPTarkov 动态 > 正文
  • 3
  • SPTarkov 动态
  • SPT主创
    初窥堂奥
    VIP2
    SPTarkov项目组

    Hello everyone!

    Today, I would like to cover 4 aspects of EFT's internals in 4 different articles: secured comminucation, payload encryption, response caching and file integrity scanning. These articles are mostly aimed at SuperMod author and anyone else interested in making modding more secure.

    In this article, I'll explain how a somewhat misunderstood system actually functions. Implementing it correctly helps tremendously in speeding up game loading.

    Response caching

    Since the early days of EFT (before 0.11.0, which is more than 5 years ago!) BSG had the idea that sending over large requests often is expensive. Because of this, the data send by the server was stored on the client and verified by the server. However, with everything EFT, this got exploited to oblivion when hackers realised EFT was far more lax in validation than it should've been.

    Since 0.12.9 or so, they by default no longer use this system. The code still persists in the game, so the server can still use it! The great thing about it is that loading into the game and after a raid is much faster.

    After working more than 4 years on this project, this sytem also marks the first time EFT actually properly implements a standard. Somewhat shocking, honestly.

    How it works in more detail is as follows:

    – Sending a request that should be cached but isn't? The HTTP header “If-None-Match” is set to empty.
    – Sending a request that should be cashed and is? The HTTP header “If-None-Match” is “123456” (what the hash is)

    The hash format send is CRC32.

    – If the server responds with HTTP code: 304 and no payload, the client will start to load the cache.
    – If the server responds with HTTP code: 200, and a payload containing {“err”:0,”errmsg”:null,”data”:{/*…*/},”crc”:123456}, it will load the data from the response and regenerate the cache file.

    Cache files are RFC1950 compressed with an XOR encryption key (13) on top. The filenames are MD5 hashes of the full request path (example: https://prod.escapefromtarkov.com/client/items). Since AKI and the research server use other endpoints, cache generated is not compatible.

    Previously it was assumed that sending {“err”:0,”errmsg”:null,”data”:{/*…*/},”crc”:0} was the way to go and that the hash should be ADLER32. While it works, this is not the proper implementation because the client still has to parse the payload from the server.ADLER32 has a chance of generating invalid hashes.


    The code for this server-side is suprisingly easy to write.

            public void Set(string data)
            {
                Data = data;

                // hash
                var bytes = Encoding.UTF8.GetBytes(Data);
                Hash = _crc32.ComputeHash(bytes);

                // set crc in cached response
                Data = Data.Remove(Data.Length 1);
                Data += “,\”crc\”:” + Hash + “}”;
            }

    In the place where we store the data, regenerate the hash whenever the data is loaded or modified.

            public override async Task Run(Context context)
            {
                var table = Database.Instance.Items;

                if (context.GetCrc() == table.Hash)
                {
                    SendCached(context);
                }
                else
                {
                    await SendText(context, table.Data);
                }
            }

    Whenever we receive a request, check the hash. Is the hash the same? Just return the status code. Otherwise, send the full response.

            protected void SendCached(Context context)
            {
                using (var response = context.Response)
                {
                    response.StatusCode = 304;
                    response.Close();
                }
            }

    …as seen here!

    Wait a second, that's it?

    Yup, that's it! Introducing support for this in AKI wouldn't be too difficult either, but not within the aim of the server. Problem is that in AKI, mods might do tricky things with requests that can invalidate the hash while it's being send. Not ideal! This is why I design my research server in a way this isn't possible.

    Future work

    There is an interesting obervation to be made: not all requests that previously were cached, are today. For example, customization info used to be. It might be interesting to re-enable caching for them and see how much loading time gain there will be.

    登堂入室

    what?

    回复
    炉火纯青
    2021

    哇好厉害大佬佩服 [s-13]

    回复
    炉火纯青
    VIP4
    2021

    不明觉厉

    回复

    请登录之后再进行评论

    登录
  • 签到
  • 任务
  • 发布
  • 模式切换
  • 偏好设置
  • 帖子间隔 侧栏位置: