FastJSON IntegerSerializer 潜在DOS攻击风险问题

背景

近日, 慢雾安全平台的白帽子给公司项目提交了一个安全漏洞:

向某个参数类型为Integer的POST接口提交如 1.00...00 (小数点后约100万个0), 服务端程序处理该请求消耗了约90秒的时间, 耗费了大量的计算资源, 对于服务端程序来说, 这是不可接受的, 攻击者可以利用该漏洞对服务器发起DOS攻击

分析

根据白帽子提供的细心我在测试环境对该问题进行了复现并通过JProfiler分析了请求链路, 结果如下 :

可见, 绝大部分的计算资源用在了将数据解析为BigDecimal. 可是为什么参数类型明明是Integer却被解析成了BigDecimal ?

我结合FastJSON源码做了进一步的分析, 发现FastJSON在解析Integer过程中会先判断数据的格式, 如果数据格式是小数, FastJSON会先将数据解析为BigDecimal , 再通过类型转换把BigDecimal转成Integer, 而正是这样的设计导致了这次的问题.

对比同类库Jackson和GSON, 在将相同数据转换成Integer时并没有以上问题. 我认为这可能是FastJSON在设计时考虑不周的一个点

解决方案

a. 在运维层面, 根据接口实际需要对请求参数大小进行限制, 除数据上传等提交数据较大的接口之外外, 将入参数据大小限制在 10K 内

b. 编写自定义Integer解析器替代默认的Integer解析器, 在将格式为小数的数据解析为Integer时, 用Double替代BigDecimal以规避潜在的安全(DOS)风险, 相关代码如下

c. 在涉及到解析用户提交的数据时, 谨慎使用BigDecimal类型, 当确实需要准确精度保证时, 可以考虑先将小数数据转换为String类型, 在校验数据长度后再将数据转为BigDecimal

这次的问题也给我带来了一些的思考:

使用BigDecimal的优势是能够确保精度不丢失, 但这背后的性能开销和安全风险也是值得我们在开发过程中认真考虑的问题

Show Comments