TypeScript中替代new Function()/eval()实现上下文条件校验咨询
安全解析字符串条件的可行方案
1. 自定义白名单表达式解析器
自己实现轻量的解析逻辑,只允许预设的安全语法:
- 先做词法拆分,识别以下类型的token:
- 属性访问:
context.xxx或嵌套的context.level1.level2 - 逻辑/比较操作符:
!!、&&、||、>、<、===、!==等 - 字面量:数字、字符串、布尔值
- 属性访问:
- 遍历token时严格限制:
- 所有属性访问必须指向传入的
context对象,禁止访问全局变量或调用函数 - 仅允许预设的操作符,禁止赋值、函数调用、
new等危险操作
- 所有属性访问必须指向传入的
- 核心逻辑示例:
- 处理
!!context.id:先递归获取context.id的值,再执行两次取反运算 - 处理
context.ten >9 && context.level1.level2 === 'test':先计算第一个比较表达式,结果为真时再计算第二个,实现短路求值
- 处理
- 优势:完全可控,无安全风险;劣势:需要覆盖所有支持的语法场景,开发量较大
2. 沙箱化表达式求值库(轻量定制版)
基于安全求值的核心思路封装库,避免使用new Function():
- 核心是自己实现表达式的解析与执行,而非依赖JS引擎的动态编译能力
- 只暴露
context对象作为唯一的访问上下文,支持常见的逻辑、比较、属性访问语法 - 可以只保留业务需要的语法子集,比如去掉不必要的位运算、三元表达式等,进一步降低风险
- 优势:比从头开发省时间,覆盖多数常见场景;劣势:需确保封装的逻辑无安全漏洞
3. AST遍历执行方案
将表达式解析为抽象语法树(AST),遍历执行时做安全校验:
- 把字符串表达式转换为AST节点(比如
context.ten >9会拆分为属性访问节点、比较节点、数字字面量节点) - 遍历AST时严格过滤:
- 仅允许访问
context的属性节点,禁止任何全局对象访问 - 仅允许预设的操作符节点,禁止函数调用、赋值、
eval等危险节点
- 仅允许访问
- 示例:处理嵌套属性
context.level1.level2时,逐层从context中取值,遇到不存在的属性返回undefined - 优势:语法支持更全面,可扩展性强;劣势:需要理解AST结构,开发复杂度较高
关键校验规则
- 禁止任何动态代码执行操作,包括函数调用、全局变量访问、赋值语句
- 处理属性访问时,需判断路径是否存在,避免报错
- 覆盖所有测试场景:逻辑短路、双重取反、多条件组合、嵌套属性、空值判断等
内容的提问来源于stack exchange,提问作者Sumanth
相关产品推荐
相关产品推荐

