0

0

Python 怎么检测并防止 JSON 炸弹攻击(超大嵌套)

冰川箭仙

冰川箭仙

发布时间:2026-01-23 19:31:45

|

390人浏览过

|

来源于php中文网

原创

应通过封装解析函数递归计数+异常捕获,或使用pydantic的recursion_limit配置与字符串长度、对象/数组数量预检组合限深防爆。

python 怎么检测并防止 json 炸弹攻击(超大嵌套)

JSON 解析时如何识别嵌套过深的结构

Python 默认的 json.loads() 不限制嵌套深度,遇到恶意构造的超深嵌套(比如 1000 层字典套字典),会触发 RecursionError 或耗尽内存。但这个错误往往出现在解析中途,无法提前拦截——你得在解析前或解析中主动设防。

关键不是等它崩,而是控制解析器行为:

  • json.loads()parse_float / parse_int 等钩子函数,在每次进入新对象或数组时计数嵌套层级
  • 更稳妥的是改用 json.JSONDecoder 并重写 scan_once(不推荐)或直接用第三方库如 json5ijson 流式解析 + 手动限深
  • 最实用方案:封装一层解析函数,用递归计数 + 异常捕获兜底

用自定义 JSONDecoder 控制最大嵌套深度

Python 标准库允许传入自定义 json.JSONDecoder 实例,通过覆盖其内部方法实现深度控制。虽然不能直接 hook 到“进入对象”时刻,但可以利用 object_hookparse_constant 配合线程局部变量来跟踪——不过更轻量的做法是用递归解析器替代。

一个简单可靠的模式:

立即学习Python免费学习笔记(深入)”;

import json
from contextlib import contextmanager

@contextmanager def limited_depth(max_depth=100): orig = json._default_decoder.parse_object depth = [0]

def parse_object(s_and_o, **kw):
    depth[0] += 1
    if depth[0] > max_depth:
        raise ValueError(f"JSON nested too deep: {depth[0]} > {max_depth}")
    try:
        return orig(s_and_o, **kw)
    finally:
        depth[0] -= 1

json._default_decoder.parse_object = parse_object
try:
    yield
finally:
    json._default_decoder.parse_object = orig

使用

try: with limited_depth(50): data = json.loads('{"a": {"b": {"c": ... }}}') # 超过 50 层就抛 ValueError except ValueError as e: print(e)

⚠️ 注意:json._default_decoder 是私有 API,Python 版本升级可能失效;生产环境建议用 jsonspydantic 做 schema 级校验,而非 patch 内部函数。

蚂蚁PPT
蚂蚁PPT

AI在线智能生成PPT

下载

用 pydantic v2 做安全反序列化(推荐生产用)

如果你已用 pydantic 定义数据结构,它默认会对嵌套做软限制,并支持显式配置递归深度。v2 中可通过 model_validate_json() + context 控制解析行为:

  • model_validate_json() 支持 context 参数,可传入自定义解析上下文
  • 结合 BaseModel.model_config = {'recursion_limit': 64} 可约束模型内字段递归展开深度
  • 真正起作用的是底层 json.loads() 调用前的预检 —— 所以仍需配合字符串长度、键数量等基础过滤

示例:

from pydantic import BaseModel
import json

class Payload(BaseModel): data: dict

先粗筛:限制原始 JSON 字符串长度和对象/数组数量

def safe_load_json(raw: str) -> dict: if len(raw) > 1_048_576: # 1MB 上限 raise ValueError("JSON too large") if raw.count('{') > 1000 or raw.count('[') > 1000: raise ValueError("Too many objects/arrays") return json.loads(raw)

再进 pydantic 校验

try: payload = Payload.model_validate_json( safe_load_json(user_input), context={'max_nesting': 50} ) except (ValueError, TypeError, json.JSONDecodeError) as e: raise ValueError("Invalid or unsafe JSON") from e

为什么只限深度还不够?还得卡长度和键数

单纯限制嵌套深度防不住“宽炸弹”:比如一层里塞 10 万个 key,每个 value 是长字符串,照样吃光内存。JSON 炸弹本质是让解析器分配大量小对象,最终 OOM。

必须组合策略:

  • 原始字符串长度上限(len(raw) )
  • 统计 {[ 出现次数,间接反映对象/数组总数
  • 解析后检查结果大小:sys.getsizeof(result) 或递归计算元素个数(慎用,可能再被炸)
  • Web 框架层前置过滤:FastAPI 的 Body(..., max_length=1024*1024),Flask 的 request.get_data(cache=False, limit=1024*1024)

最易忽略的一点:很多服务把 JSON 当作可信输入,直接 json.loads(request.body),连长度都不验。其实第一道防线永远是 HTTP 层的 Content-Length 和 body 读取限制。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

772

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

663

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

765

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

699

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1385

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

570

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

751

2023.08.11

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 15.2万人学习

Django 教程
Django 教程

共28课时 | 3.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号