应先JSON.parse()再白名单校验:定义schema明确字段名、类型及取值范围,遍历schema提取合法属性,同时拦截__proto__等危险键名,前端过滤仅为辅助,后端严格校验才是关键。

直接用 JSON.parse() 解析不可信的 JSON 字符串存在风险,但“过滤不合规的键值对”不是 JSON 解析层的责任——JSON 本身是纯数据格式,没有“合规性”概念。真正要做的,是在解析后对 JavaScript 对象进行**白名单校验与结构清洗**,而非在 JSON 字符串层面“剔除键值对”。
明确校验目标:只保留预期字段和类型
安全过滤的核心是“最小权限原则”:只接受你明确需要的字段名、允许的值类型(如字符串、数字)、以及可接受的取值范围(如 status 只能是 "active" 或 "inactive")。
- 不要尝试用正则去删 JSON 字符串里的字段(易出错、破坏结构、绕过校验)
- 先
JSON.parse()得到对象,再基于预设 schema 过滤属性 - 对每个字段做类型检查 + 内容检查(如长度、正则匹配、枚举值)
使用白名单对象结构做安全提取
定义一个只含合法键名的白名单对象,遍历它来构建干净结果,自动忽略所有未知字段:
function safeParseJSON(jsonStr, schema = {}) {
try {
const raw = JSON.parse(jsonStr);
if (typeof raw !== 'object' || raw === null) return {};
const clean = {};
Object.keys(schema).forEach(key => {
if (key in raw) {
const value = raw[key];
const type = schema[key].type;
const validator = schema[key].validate;
// 类型检查
if (typeof value !== type && !(type === 'number' && typeof value === 'string' && !isNaN(value))) {
return;
}
// 自定义校验(如邮箱、长度、枚举)
if (validator && !validator(value)) return;
clean[key] = value;
}
});
return clean;
} catch (e) {
return {}; // 解析失败,返回空对象或抛出自定义错误
}
}
// 示例调用
const userSchema = {
name: { type: 'string', validate: v => v.length <= 50 },
age: { type: 'number', validate: v => Number.isInteger(v) && v >= 0 && v <= 120 },
role: { type: 'string', validate: v => ['admin', 'user', 'guest'].includes(v) }
};
const unsafeInput = '{"name":"Alice","age":"30","role":"admin","__proto__":"hack","token":"abc123"}';
const safeUser = safeParseJSON(unsafeInput, userSchema);
// → { name: "Alice", age: 30, role: "admin" }(其他字段被自动忽略)
防范原型污染等高危字段
某些键名(如 "__proto__"、"constructor"、"prototype")在旧版 JS 或不当赋值时可能引发原型污染。即使你不用 Object.assign() 或展开运算符直接合并,也应在 schema 校验前做基础黑名单拦截:
立即学习“Java免费学习笔记(深入)”;
- 解析后立即检查对象是否含有危险键名,有则删除
- 推荐用
Object.getOwnPropertyNames()而非for...in,避免继承属性干扰 - 若使用第三方库(如 Lodash),确保版本 ≥4.17.21,已修复相关漏洞
进阶建议:配合 Content-Security-Policy 与后端协同
前端过滤只是最后一道防线:
- 后端必须做严格校验并返回精简数据,前端不应承担主要过滤责任
- 通过 CSP 头限制内联脚本和 eval,降低恶意 JSON 触发 XSS 的可能性
- 对用户可控的 JSON 输入(如配置编辑器),优先使用表单控件而非自由 JSON 文本框


















