封包白名单

基本信息

属性 值
加载器 net.bdew.lib.network.NetworkSecurityLoader
配置节 messageWhitelist
内置配置 assets/bdlib/config/net-filter.cfg
配置文件清单 assets/bdlib/config/files.lst
配置目录 <游戏目录>/config/bdlib
强制开关 enforce(默认 yes)

功能

由于 BD lib 使用 Java 原生序列化反序列化客户端发来的数据,未经限制的反序列化等同于远程代码执行入口。NetworkSecurityLoader 在预初始化阶段建立类名白名单,只允许明确的类被反序列化。

加载流程

NetworkSecurityLoader.loadConfigFiles()(network/NetworkSecurityConfig.scala:23-52)在 BdLib.preInit 中被调用(BdLib.scala:69),执行:

  1. 若 config/bdlib 目录不存在则创建,并写入一个 readme.txt,说明「本目录下所有 .cfg 会在内置配置之后按字母序加载」以及「overrides 目录中的同名文件可覆盖内置配置」(NetworkSecurityConfig.scala:24-35)。
  2. 调用 RecipesHelper.loadConfigs,参数为 modName = "BdLib"、listResource = "/assets/bdlib/config/files.lst"、configDir = BdLib.configDir、resBaseName = "/assets/bdlib/config/"。
  3. 从 messageWhitelist 配置节读出三个值并写入编解码器(NetworkSecurityConfig.scala:45-51):
配置键 写入目标 含义
prefix SerializedMessageCodec.validClassPrefixes ++= 类名前缀匹配,前缀命中即放行
exact SerializedMessageCodec.validClasses ++= 精确类名匹配
enforce SerializedMessageCodec.enforceFilter = 是否强制执行过滤
  1. 最后调用 SerializedMessageCodec.validClassCache.clear() 清空判定缓存。

内置配置

net-filter.cfg 出厂内容为空前缀 + 空精确名单 + 强制开启:

cfg messageWhitelist {
    exact = =[
    ]
    prefix = =[
    ]
    enforce = yes
}

配合 BdLib.scala:65-68 用 addValidClass 预先登记的 4 个类,出厂状态下只有本模组自己的封包能被反序列化。

判定逻辑

SerializedMessageCodec.decode 覆写 ObjectInputStream.resolveClass(network/SerializedMessageCodec.scala:57-75),对每个待解析的类名先查 validClassCache(ConcurrentHashMap),未命中时计算 validClasses.contains(name) || validClassPrefixes.exists(name.startsWith) 并缓存结果。判定失败则记录警告 Received disallowed message component class: {}。

数值

数值名 值
出厂精确类名条目数 0
出厂类名前缀条目数 0
出厂 enforce 值 yes(强制)
代码内预登记的类数 4
内置配置文件数 1(net-filter.cfg,由 files.lst 列出)
判定缓存实现 ConcurrentHashMap

交互

该机制完全自动生效,玩家无需任何操作。其可观察结果如下:

触发 行为
服务端启动 自动创建 config/bdlib 目录与 readme.txt,加载内置配置并应用白名单
附属模组使用 BD lib 网络框架 必须在自己的 .cfg 中用 prefix 或 exact 声明其封包类,否则其封包会被拒绝反序列化
客户端发来未列入白名单的类 记警告 Received disallowed message component class,该封包不被反序列化
管理员向 config/bdlib 添加 .cfg 该文件在内置配置之后按字母序加载,可用于追加白名单条目

相关条目