注册
web

别再无脑用 `JSON.parse()` 了!这个安全漏洞你可能每天都在触发


你以为只是解析个字符串?其实黑客已经在你服务器上跑脚本了!



在前端和 Node.js 开发中,JSON.parse() 几乎无处不在:


const data = JSON.parse(localStorage.getItem('user'));
const config = JSON.parse(req.body.payload);
const settings = JSON.parse(fs.readFileSync('config.json'));

简洁、直接、好用——但极其危险


如果你没有对输入做任何校验就调用 JSON.parse(),你正在为应用打开一扇“任意代码执行”的后门。


今天,我们就来揭开 JSON.parse() 背后的安全雷区,并告诉你如何用更安全、更现代的方式处理 JSON 数据。




危险场景一:原型污染(Prototype Pollution)


这是 JSON.parse() 最臭名昭著的安全漏洞之一。


虽然原生 JSON.parse() 本身不会执行代码,但它会忠实地还原对象结构——包括 __proto__constructor.prototype 这类特殊属性。


来看一个真实攻击载荷:


const userInput = '{"__proto__":{"isAdmin":true}}';
const obj = {};
JSON.parse(userInput, (key, value) => {
obj[key] = value;
return value;
});
console.log({}.isAdmin); // true!全局对象被污染!

如果这段代码出现在你的登录逻辑、权限校验或配置合并中,攻击者就能:



  • 绕过身份验证(isAdmin: true);
  • 注入恶意属性(如 exec: 'rm -rf /');
  • 篡改全局行为,导致服务崩溃或数据泄露。


尤其在使用 Lodash、merge、assign 等工具库时,风险更高!





危险场景二:拒绝服务(DoS)


恶意构造的 JSON 字符串可导致内存爆炸CPU 耗尽


// 深度嵌套攻击
const evil = '{"a":{"a":{"a":{"a":{"a":{"a": ... }}}}}}';

// 或超大数组
const evil2 = '[1,1,1,...,1]' // 1000 万个元素

调用 JSON.parse(evil) 可能:



  • 占用数 GB 内存;
  • 阻塞事件循环数秒;
  • 直接触发 OOM(Out of Memory)崩溃。

在 API 接口或 Webhook 处理中,这等于把“关机按钮”交给了攻击者。




正确姿势:安全解析 JSON 的三重防护


第一步:限制输入大小


在解析前先检查字符串长度:


function safeParse(str, maxSize = 1024 * 100) { // 100KB
if (typeof str !== 'string' || str.length > maxSize) {
throw new Error('Input too large');
}
return JSON.parse(str);
}

第二步:禁用危险键(如 __proto__


使用 reviver 函数过滤敏感属性:


function secureJSONParse(str) {
return JSON.parse(str, (key, value) => {
if (key === '__proto__' || key === 'constructor') {
throw new Error('Disallowed key in JSON');
}
return value;
});
}

第三步(推荐):用 Zod / Joi 做运行时校验


这才是现代 JS 工程的最佳实践!


import { z } from 'zod';

const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
isAdmin: z.boolean().optional(),
});

function parseUser(jsonStr: string) {
const raw = secureJSONParse(jsonStr);
return UserSchema.parse(raw); // 自动校验 + 类型推导
}

优势:



  • 类型安全(配合 TypeScript 完美);
  • 自动过滤多余字段
  • 明确拒绝非法结构
  • 防止原型污染、字段注入等攻击



特别提醒:Node.js 中的额外风险


在服务端,如果你从以下来源解析 JSON,风险更高:



  • HTTP 请求体(req.body
  • 文件读取(用户上传的 JSON 配置)
  • Redis / 数据库存储的序列化数据
  • 第三方 Webhook 回调

务必在解析前做来源校验 + 结构校验 + 大小限制三重保险!




结语


JSON.parse() 不是“坏 API”,但它是一把没有保险的枪

在现代 Web 开发中,信任任何用户输入 = 自毁程序


下次当你写下 JSON.parse(someString) 时,请自问:



“我确定这个字符串来自可信源吗?它的结构真的安全吗?”



如果答案不确定,请立即切换到 Zod / Joi + 安全解析函数 的组合。


转发给那个还在裸用 JSON.parse() 的队友吧!




各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!


作者:前端Hardy
来源:juejin.cn/post/7613514109237805098

0 个评论

要回复文章请先登录注册