2022-08-08 22:58:42
安全解析包含函数和正则表达式的JSON对象需通过递归转换字符串并严格验证,无通用工具直接支持,需手动处理类型转换与安全风险。
一、核心问题与解决方案JSON标准规范仅支持string、number、boolean、null、array和object六种数据类型,函数(function)和正则表达式(RegExp)无法直接序列化为合法JSON。强行解析会导致数据丢失或错误,且可能引发安全漏洞(如代码注入)。解决方案:
通过递归遍历JSON对象,将函数和正则表达式转为字符串,同时保留其他数据类型:
function sanitizeJson(json: any): any { if (typeof json === 'function') { return json.toString(); // 转为函数定义字符串(如 "function() {...}") } else if (json instanceof RegExp) { return json.toString(); // 转为正则字符串(如 "/pattern/flags") } else if (Array.isArray(json)) { return json.map(sanitizeJson); // 递归处理数组 } else if (typeof json === 'object' && json !== null) { const sanitized = {}; for (const key in json) { sanitized[key] = sanitizeJson(json[key]); // 递归处理对象 } return sanitized; } else { return json; // 直接返回原始类型(string/number等) }}关键点:
将字符串还原为函数或正则表达式时,需额外处理并严格验证:
函数还原:
使用eval()或new Function()存在高风险(可能执行恶意代码)。
安全建议:仅在完全信任数据来源时使用,或通过预定义白名单限制函数逻辑。
示例(高风险,慎用):function parseFunction(str: string): Function { return new Function(`return ${str.slice(str.indexOf('{') + 1, str.lastIndexOf('}'))}`);}
正则表达式还原:
通过RegExp构造函数解析字符串,但需验证格式合法性。
示例:function parseRegExp(str: string): RegExp { const regexStr = str.slice(1, str.lastIndexOf('/')); const flags = str.slice(str.lastIndexOf('/') + 1); return new RegExp(regexStr, flags);}
安全警告:
输入验证:
存储前检查数据是否包含函数或正则表达式,拒绝非法输入。
使用白名单机制限制可接受的字符串格式。
访问控制:
限制对JSON解析接口的访问权限,防止未授权操作。
替代方案:
若可能,避免在JSON中存储函数和正则表达式,改用描述性字符串(如正则模式字符串)或ID引用外部定义。
日志与监控:
记录所有JSON解析操作,便于追踪异常行为。
通过递归转换和谨慎的反向解析,可在控制风险的前提下处理包含函数和正则表达式的JSON对象,但需以安全为首要原则。