JSON注入漏洞:如何有效识别与过滤
引言:被忽视的“数据污染”风险
在Web应用开发中,JSON(JavaScript Object Notation)因其轻量、易解析的特性,已成为前后端数据交互的主流格式,开发者往往更关注JSON数据的“可用性”,却忽略了其“安全性”——当应用未对用户输入的JSON数据进行严格校验时,攻击者可通过构造恶意JSON payload,触发“JSON注入漏洞”,导致敏感信息泄露、权限绕过甚至远程代码执行等严重后果。
本文将系统介绍JSON注入漏洞的原理、常见攻击场景,并重点讲解如何通过技术手段有效识别和过滤这类漏洞,帮助开发者构建更安全的JSON数据处理机制。
JSON注入漏洞:原理与攻击场景
漏洞核心原理
JSON注入的本质是“数据污染”:当应用将用户输入未经处理直接嵌入JSON响应中,且客户端(如浏览器)将响应内容作为JSON解析时,攻击者可通过构造特殊字符(如、\、、等)破坏JSON原有结构,注入恶意数据。  
漏洞产生的两个必要条件:
- 服务端:未对用户输入的JSON字段进行校验或转义,直接将其拼接到JSON响应中;
- 客户端:信任服务端返回的JSON内容,并使用原生JSON解析器(如JSON.parse())解析,未对解析结果进行二次校验。
常见攻击场景
(1)敏感信息泄露
攻击者通过构造包含特殊字符的输入,让服务端返回的JSON结构被“篡改”,从而泄露本应被隐藏的数据。
示例:
假设某API接口通过name参数返回用户信息,服务端代码(伪代码)如下:  
# 伪代码:未校验的用户输入直接拼接到JSON
name = request.GET.get('name')  # 用户输入
response = {"status": "success", "data": {"name": name, "password": "******"}}  
return JsonResponse(response)  
攻击者输入name"},服务端返回的JSON变为:  
{"status": "success", "data": {"name": "name}", "password": "******"}}  
若客户端直接解析,可能导致data字段被截断,甚至触发后续逻辑错误(如访问不存在的属性),更危险的是,若攻击者输入"name":"attacker","password":"stolen",可能覆盖原有数据,伪造用户信息。  
(2)客户端代码执行(XSS)
若客户端将JSON注入的数据直接渲染到HTML中,且未进行转义,可能触发XSS攻击。
示例:
服务端返回JSON:  
{"message": "<script>alert('XSS')</script>"}  
客户端代码:
let data = JSON.parse(response.responseText);
document.getElementById('msg').innerText = data.message; // 直接渲染,触发XSS
(3)逻辑绕过与权限提升
攻击者通过构造嵌套JSON或特殊字段,破坏应用的业务逻辑,实现权限绕过。
示例:
某API通过is_admin字段判断用户权限,服务端代码:  
# 伪代码:用户输入直接控制权限
is_admin = request.POST.get('is_admin')  # 用户输入
response = {"status": "success", "is_admin": is_admin}
攻击者输入true,"privilege":"admin",返回JSON变为:  
{"status": "success", "is_admin": true,"privilege":"admin"}  
若客户端仅检查is_admin是否存在,可能误判攻击者具有管理员权限。  
如何识别JSON注入漏洞
识别JSON注入漏洞的核心思路是:模拟攻击构造,验证服务端对用户输入的处理逻辑,以下是具体方法:
黑盒测试:构造恶意payload进行探测
(1)基础字符探测
尝试在JSON字段中输入以下特殊字符,观察响应是否被正确转义或解析:
- JSON字段分隔符:、、、、、[、];
- 转义字符:\、\"、\\;
- 脚本字符(针对XSS场景):<script>、onerror=、javascript:;
- 边界破坏符:、、"]、[。
示例:
在登录接口的username字段输入"test"},若响应返回的JSON结构异常(如字段截断、报错),可能存在注入漏洞。  
(2)嵌套JSON注入
构造多层嵌套的JSON结构,测试服务端是否会对嵌套字段进行校验。
示例:
{"name":"attacker","payload":{"malicious":"{\"key\":\"value\"}"}}
观察服务端是否解析嵌套的恶意字段,或是否将其原样返回。
(3)盲测与错误回显
若服务端对错误输入返回统一提示(如“参数错误”),可通过对比正常响应与异常响应的差异,判断是否存在注入点。
- 正常输入test,返回{"name":"test"};
- 恶意输入"test,返回{"error":"invalid json"}或{"name":"\"test"}(未转义),可能存在注入。
白盒测试:代码审计
通过代码审计直接定位JSON数据处理逻辑,重点关注以下场景:
(1)用户输入直接拼接到JSON响应
检查代码中是否存在类似以下模式:
// 危险:用户输入未校验直接拼接
let userInput = req.body.field;
let response = {data: userInput}; // 直接赋值
res.json(response);  
或Python:
user_input = request.POST.get('field')
response = {"data": user_input}  # 未校验
return JsonResponse(response)
(2)未使用安全的JSON序列化方法
部分编程语言/框架提供了“安全模式”的JSON序列化方法,若未使用,可能导致注入。
- Python:使用json.dumps()时未设置ensure_ascii=False或未转义特殊字符;
- JavaScript:使用JSON.stringify()时未处理恶意字符(尽管JSON.stringify()会对等字符转义,但需注意嵌套场景)。
(3)客户端未校验JSON解析结果
检查客户端代码是否对服务端返回的JSON进行二次校验,
// 危险:直接解析并渲染 let data = JSON.parse(xhr.responseText); document.write(data.field); // 未校验field内容
自动化工具辅助
- DAST工具:如OWASP ZAP、Burp Suite的“Fuzz”功能,可自动化构造恶意JSON payload,扫描注入点;
- SAST工具:如SonarQube、Checkmarx,通过规则匹配识别“用户输入直接拼接到JSON”的代码模式;
- 专用JSON扫描工具:如jsonlint(校验JSON结构)、jq(命令行JSON处理工具),可辅助分析响应数据的合法性。
如何有效过滤JSON注入漏洞
过滤JSON注入漏洞需从“输入校验”“输出转义”“代码规范”三方面入手,构建“层层防御”机制。
输入层:严格校验用户输入
(1)白名单校验,拒绝非法字符
对用户输入的JSON字段进行白名单校验,仅允许符合预期的字符或格式。
- 字段类型校验:若字段应为数字,则使用isNumeric()校验;若应为字符串,则限制长度、禁止特殊字符(如、\);
- JSON格式校验:使用JSON.parse()(前端)或json.loads()(后端)校验输入是否为合法JSON,若解析失败则直接拒绝。
示例(Python):
import json
def validate_json_input(user_input):
    try:
        data = json.loads(user_input)  # 校验是否为合法JSON
        if not isinstance(data, dict):  # 校验是否为对象类型(根据业务需求调整)
            raise ValueError("Invalid JSON type")
        return data
    except json.JSONDecodeError:
        raise ValueError("Invalid JSON format")
# 使用时
user_input = request.body.get('data')
try:
    validated_data = validate_json_input(user_input)
    # 处理校验后的数据
except ValueError as e:
    return JsonResponse({"error": str(e)}, status=400)
(2)限制输入长度与结构
- 避免接收过长的JSON输入,防止缓冲区溢出或DoS攻击;
- 限制JSON的嵌套层数和字段数量,避免复杂嵌套




 
		 
		 
		 
		
还没有评论,来说两句吧...