Nodejs引擎能力评价体系
graph LR
L1H1["SAST污点追踪引擎能力评估(Nodejs)"]==>L2H1["完整度"]
L2H1["完整度"]==>L3H1["常规污点链路的完整度"]
L3H1["常规污点链路的完整度"]==>L4H1["污点来源识别能力(source)"]
L4H1["污点来源识别能力(source)"]==>L5H1["是否支持污点自定义"]
L5H1["是否支持污点自定义"]==>L6H1["作用域自定义"]
L6H1["作用域自定义"]==>L7H1["模块/文件级别自定义"]
L7H1["模块/文件级别自定义"]==>L8H1["case0155A+case0155BB"]
L6H1["作用域自定义"]==>L7H2["函数级别自定义"]
L7H2["函数级别自定义"]==>L8H2["case0155A+case0155B"]
L5H1["是否支持污点自定义"]==>L6H3["变量自定义"]
L6H3["变量自定义"]==>L7H3["case0155A "]
L5H1["是否支持污点自定义"]==>L6H4["模糊匹配"]
L6H4["模糊匹配"]==>L7H4["this.ctx.queryconst { ctx } =thisctx.query"]
L7H4["this.ctx.queryconst { ctx } =thisctx.query"]==>L8H4["case0156"]
L4H1["污点来源识别能力(source)"]==>L5H5["污点适配框架--依据框架自动选择污点"]
L5H5["污点适配框架--依据框架自动选择污点"]==>L6H5["暂无case"]
L3H1["常规污点链路的完整度"]==>L4H6["污点传播跟踪能力(propagator)"]
L4H6["污点传播跟踪能力(propagator)"]==>L5H6["传播场景写法支持(AST)"]
L5H6["传播场景写法支持(AST)"]==>L6H6["表达式"]
L6H6["表达式"]==>L7H6["污点变量通过赋值表达式传递"]
L7H6["污点变量通过赋值表达式传递"]==>L8H6["case011"]
L6H6["表达式"]==>L7H7["污点变量传递过程中包含一元表达式"]
L7H7["污点变量传递过程中包含一元表达式"]==>L8H7["前缀表达式写法"]
L8H7["前缀表达式写法"]==>L9H7["case012"]
L7H7["污点变量传递过程中包含一元表达式"]==>L8H8["后缀表达式写法"]
L8H8["后缀表达式写法"]==>L9H8["case012"]
L6H6["表达式"]==>L7H9["污点变量传递过程中包含二元表达式"]
L7H9["污点变量传递过程中包含二元表达式"]==>L8H9["中缀表达式写法"]
L8H9["中缀表达式写法"]==>L9H9["case013"]
L6H6["表达式"]==>L7H10["污点变量传递过程中包含三元表达式"]
L7H10["污点变量传递过程中包含三元表达式"]==>L8H10["三元表达式的true条件"]
L8H10["三元表达式的true条件"]==>L9H10["case014"]
L7H10["污点变量传递过程中包含三元表达式"]==>L8H11["三元表达式的false条件"]
L8H11["三元表达式的false条件"]==>L9H11["case015"]
L6H6["表达式"]==>L7H12["污点变量通过函数调用表达式传递"]
L7H12["污点变量通过函数调用表达式传递"]==>L8H12["case016"]
L6H6["表达式"]==>L7H13["污点变量通过new表达式传递"]
L7H13["污点变量通过new表达式传递"]==>L8H13["case017"]
L6H6["表达式"]==>L7H14["污点变量通过对象表达式传递"]
L7H14["污点变量通过对象表达式传递"]==>L8H14["case018"]
L6H6["表达式"]==>L7H15["污点变量通过对象中的属性传递"]
L7H15["污点变量通过对象中的属性传递"]==>L8H15["case019"]
L6H6["表达式"]==>L7H16["污点变量通过数组/Map/集合中的元素传递"]
L7H16["污点变量通过数组/Map/集合中的元素传递"]==>L8H16["case0110、case0111"]
L5H6["传播场景写法支持(AST)"]==>L6H17["语句"]
L6H17["语句"]==>L7H17["if语句"]
L7H17["if语句"]==>L8H17["污点变量在if的条件中进行传递"]
L8H17["污点变量在if的条件中进行传递"]==>L9H17["case0112"]
L7H17["if语句"]==>L8H18["污点变量在if的true分支语句中进行传递"]
L8H18["污点变量在if的true分支语句中进行传递"]==>L9H18["case0113"]
L7H17["if语句"]==>L8H19["污点变量在if的false分支语句中进行传递"]
L8H19["污点变量在if的false分支语句中进行传递"]==>L9H19["case0114"]
L6H17["语句"]==>L7H20["return语句"]
L7H20["return语句"]==>L8H20["污点变量通过yield返回赋值传递"]
L8H20["污点变量通过yield返回赋值传递"]==>L9H20["case0115"]
L7H20["return语句"]==>L8H21["污点变量通过return返回赋值传递"]
L8H21["污点变量通过return返回赋值传递"]==>L9H21["case0116"]
L6H17["语句"]==>L7H22["switch语句"]
L7H22["switch语句"]==>L8H22["污点变量在swicth的判断表达式中传递"]
L8H22["污点变量在swicth的判断表达式中传递"]==>L9H22["case0117"]
L7H22["switch语句"]==>L8H23["污点变量在case语句中传递"]
L8H23["污点变量在case语句中传递"]==>L9H23["case0118"]
L7H22["switch语句"]==>L8H24["污点变量在default语句中传递"]
L8H24["污点变量在default语句中传递"]==>L9H24["case0119"]
L6H17["语句"]==>L7H25["for语句"]
L7H25["for语句"]==>L8H25["污点变量在for的init语句中传递"]
L8H25["污点变量在for的init语句中传递"]==>L9H25["case0120"]
L7H25["for语句"]==>L8H26["污点变量在for的条件语句中传递"]
L8H26["污点变量在for的条件语句中传递"]==>L9H26["case0121"]
L7H25["for语句"]==>L8H27["污点变量在for的update语句中传递"]
L8H27["污点变量在for的update语句中传递"]==>L9H27["case0122"]
L7H25["for语句"]==>L8H28["污点变量在for的body中传递"]
L8H28["污点变量在for的body中传递"]==>L9H28["case0123"]
L7H25["for语句"]==>L8H29["污点变量在for in/of语句的对象中传递"]
L8H29["污点变量在for in/of语句的对象中传递"]==>L9H29["case0124、case0125"]
L6H17["语句"]==>L7H30["while语句"]
L7H30["while语句"]==>L8H30["污点在while的条件语句中传递"]
L8H30["污点在while的条件语句中传递"]==>L9H30["case0126"]
L7H30["while语句"]==>L8H31["污点在while的语句块中传递"]
L8H31["污点在while的语句块中传递"]==>L9H31["case0127"]
L7H30["while语句"]==>L8H32["do_while语句,在do语句块中传递"]
L8H32["do_while语句,在do语句块中传递"]==>L9H32["case0128"]
L6H17["语句"]==>L7H33["try语句"]
L7H33["try语句"]==>L8H33["污点在try语句块中传递"]
L8H33["污点在try语句块中传递"]==>L9H33["case0129"]
L7H33["try语句"]==>L8H34["污点在catch语句块中传递"]
L8H34["污点在catch语句块中传递"]==>L9H34["case0130"]
L7H33["try语句"]==>L8H35["污点在finally语句块中传递"]
L8H35["污点在finally语句块中传递"]==>L9H35["case0131"]
L6H17["语句"]==>L7H36["Declaration语句"]
L7H36["Declaration语句"]==>L8H36["污点变量传递过程中进入自定义类"]
L8H36["污点变量传递过程中进入自定义类"]==>L9H36["普通定义类"]
L9H36["普通定义类"]==>L10H36["case0116 "]
L8H36["污点变量传递过程中进入自定义类"]==>L9H37["匿名类"]
L9H37["匿名类"]==>L10H37["case0132 "]
L7H36["Declaration语句"]==>L8H38["污点变量传递过程中进入自定义函数"]
L8H38["污点变量传递过程中进入自定义函数"]==>L9H38["普通函数"]
L9H38["普通函数"]==>L10H38["case0132 "]
L8H38["污点变量传递过程中进入自定义函数"]==>L9H39["匿名函数"]
L9H39["匿名函数"]==>L10H39["var a = function(param){ sink(param)}a(taint)"]
L10H39["var a = function(param){ sink(param)}a(taint)"]==>L11H39["case0133"]
L8H38["污点变量传递过程中进入自定义函数"]==>L9H40["立即执行函数"]
L9H40["立即执行函数"]==>L10H40["(function (param){ sink(param)})(taint)"]
L10H40["(function (param){ sink(param)})(taint)"]==>L11H40["case0134"]
L8H38["污点变量传递过程中进入自定义函数"]==>L9H41["箭头函数"]
L9H41["箭头函数"]==>L10H41["res = param => sink(param)"]
L10H41["res = param => sink(param)"]==>L11H41["case0135"]
L8H38["污点变量传递过程中进入自定义函数"]==>L9H42["闭包函数"]
L9H42["闭包函数"]==>L10H42["func foo(){ var a=taint; func bar(){ sink(a); }}"]
L10H42["func foo(){ var a=taint; func bar(){ sink(a); }}"]==>L11H42["case0136"]
L5H6["传播场景写法支持(AST)"]==>L6H43["多节点类型嵌套"]
L6H43["多节点类型嵌套"]==>L7H43["语句与表达式结合"]
L7H43["语句与表达式结合"]==>L8H43["类/函数定义赋值给对象"]
L8H43["类/函数定义赋值给对象"]==>L9H43["const a = function() { console.log('Hello, world!');};"]
L9H43["const a = function() { console.log('Hello, world!');};"]==>L10H43["case0133 "]
L7H43["语句与表达式结合"]==>L8H44["export 直接导出函数"]
L8H44["export 直接导出函数"]==>L9H44["case0137"]
L7H43["语句与表达式结合"]==>L8H45["moduleExports 导出匿名类/函数"]
L8H45["moduleExports 导出匿名类/函数"]==>L9H45["case0138"]
L7H43["语句与表达式结合"]==>L8H46["…"]
L6H43["多节点类型嵌套"]==>L7H47["表达式与表达式结合"]
L7H47["表达式与表达式结合"]==>L8H47["一元/二元/三元表达式嵌套"]
L8H47["一元/二元/三元表达式嵌套"]==>L9H47["一元表达式结合二元表达式"]
L9H47["一元表达式结合二元表达式"]==>L10H47["b=a+++a;"]
L10H47["b=a+++a;"]==>L11H47["case0139"]
L8H47["一元/二元/三元表达式嵌套"]==>L9H48["二元表达式结合二元表达式"]
L9H48["二元表达式结合二元表达式"]==>L10H48["(a+b)+(c+d)"]
L10H48["(a+b)+(c+d)"]==>L11H48["case0140"]
L8H47["一元/二元/三元表达式嵌套"]==>L9H49["三元表达式与一元/二元/三元表达式嵌套"]
L9H49["三元表达式与一元/二元/三元表达式嵌套"]==>L10H49["a?(c?d+e:f):++b"]
L10H49["a?(c?d+e:f):++b"]==>L11H49["case0141"]
L7H47["表达式与表达式结合"]==>L8H50["函数调用与一元/二元/三元表达式结合"]
L8H50["函数调用与一元/二元/三元表达式结合"]==>L9H50["case0142、case0143、case0144"]
L7H47["表达式与表达式结合"]==>L8H51["函数调用与对象属性结合"]
L8H51["函数调用与对象属性结合"]==>L9H51["case0145"]
L7H47["表达式与表达式结合"]==>L8H52["函数调用与数组/Map/集合结合"]
L8H52["函数调用与数组/Map/集合结合"]==>L9H52["case0146"]
L7H47["表达式与表达式结合"]==>L8H53["对象属性与数组/Map/集合结合"]
L8H53["对象属性与数组/Map/集合结合"]==>L9H53["case0147"]
L7H47["表达式与表达式结合"]==>L8H54["函数调用表达式连续调用"]
L8H54["函数调用表达式连续调用"]==>L9H54["a.b().c()"]
L9H54["a.b().c()"]==>L10H54["case0148 "]
L7H47["表达式与表达式结合"]==>L8H55["函数调用表达式嵌套调用"]
L8H55["函数调用表达式嵌套调用"]==>L9H55["a(b(c(sink(taint))))"]
L9H55["a(b(c(sink(taint))))"]==>L10H55["case0149 "]
L7H47["表达式与表达式结合"]==>L8H56["..."]
L6H43["多节点类型嵌套"]==>L7H57["语句与语句结合"]
L7H57["语句与语句结合"]==>L8H57["return语句与函数定义语句结合"]
L8H57["return语句与函数定义语句结合"]==>L9H57["return function inner(){ sink(taint);}"]
L9H57["return function inner(){ sink(taint);}"]==>L10H57["case0150 "]
L7H57["语句与语句结合"]==>L8H58["内部函数"]
L8H58["内部函数"]==>L9H58["case0136"]
L7H57["语句与语句结合"]==>L8H59["内部类"]
L8H59["内部类"]==>L9H59["内部类中this调用"]
L9H59["内部类中this调用"]==>L10H59["case0151 "]
L8H59["内部类"]==>L9H60["内部类外new实例调用"]
L9H60["内部类外new实例调用"]==>L10H60["case0152 "]
L7H57["语句与语句结合"]==>L8H61["... "]
L3H1["常规污点链路的完整度"]==>L4H62["污点触发跟踪能力(sink)"]
L4H62["污点触发跟踪能力(sink)"]==>L5H62["是否支持自定义sink"]
L5H62["是否支持自定义sink"]==>L6H62["sink函数的参数级别"]
L6H62["sink函数的参数级别"]==>L7H62["case0157A+case0157B "]
L5H62["是否支持自定义sink"]==>L6H63["函数级别"]
L6H63["函数级别"]==>L7H63["指定对象直接调用"]
L7H63["指定对象直接调用"]==>L8H63["this.ctx.app.curl()"]
L8H63["this.ctx.app.curl()"]==>L9H63["case0158"]
L6H63["函数级别"]==>L7H64["对象重新赋值后调用"]
L7H64["对象重新赋值后调用"]==>L8H64["const app=this.ctx.appapp.curl()"]
L8H64["const app=this.ctx.appapp.curl()"]==>L9H64["case0159"]
L6H63["函数级别"]==>L7H65["二三方包方法追踪"]
L7H65["二三方包方法追踪"]==>L8H65["require引入,进行对象赋值后调用"]
L8H65["require引入,进行对象赋值后调用"]==>L9H65["const serialize = require('node-serialize');serialize.unserialize(payload);"]
L9H65["const serialize = require('node-serialize'); \n serialize.unserialize(payload);"]==>L10H65["case0160 "]
L7H65["二三方包方法追踪"]==>L8H66["import引入后调用"]
L8H66["import引入后调用"]==>L9H66["import * as ns from 'xxx'ns.unserialize() import {unserialize} from 'node-serialize'unserialize(taint)import {unserialize as ns} from 'node-serialize'ns(taint)"]
L9H66["import * as ns from 'xxx'ns.unserialize() \n import {unserialize} from 'node-serialize'unserialize(taint) \n import {unserialize as ns} from 'node-serialize'ns(taint)"]==>L10H66["case0161,case0162,case0163 "]
L4H62["污点触发跟踪能力(sink)"]==>L5H67["是否支持sink点非严格匹配"]
L5H67["是否支持sink点非严格匹配"]==>L6H67["*.ctx.curl()"]
L6H67["*.ctx.curl()"]==>L7H67["case0164 "]
L2H1["完整度"]==>L3H68["特殊链路跟踪能力"]
L3H68["特殊链路跟踪能力"]==>L4H68["类属性set后使用"]
L4H68["类属性set后使用"]==>L5H68["case0153"]
L3H68["特殊链路跟踪能力"]==>L4H69["模板字符串"]
L4H69["模板字符串"]==>L5H69["a = 'xxx ; xxx'b = `select * from ${a}`;"]
L5H69["a = 'xxx ; xxx'b = `select * from ${a}`;"]==>L6H69["case0165"]
L3H68["特殊链路跟踪能力"]==>L4H70["解构赋值"]
L4H70["解构赋值"]==>L5H70["数组解构赋值"]
L5H70["数组解构赋值"]==>L6H70["const arr = [1, 2, 3];const [a, b, c] = arr;"]
L6H70["const arr = [1, 2, 3];const [a, b, c] = arr;"]==>L7H70["case0166 "]
L4H70["解构赋值"]==>L5H71["对象解构赋值"]
L5H71["对象解构赋值"]==>L6H71["const obj = { x: 1, y: 2 };const { x, y } = obj;"]
L6H71["const obj = { x: 1, y: 2 };const { x, y } = obj;"]==>L7H71["case0167 "]
L4H70["解构赋值"]==>L5H72["嵌套解构赋值"]
L5H72["嵌套解构赋值"]==>L6H72["const arr = [[1, 2], [3, 4]];const [[a, b], [c, d]] = arr;"]
L6H72["const arr = [[1, 2], [3, 4]];const [[a, b], [c, d]] = arr;"]==>L7H72["case0168 "]
L4H70["解构赋值"]==>L5H73["别名"]
L5H73["别名"]==>L6H73[" const obj = {x:1,y:{z:3,u:taint}}; const {x,y:{z:c,u:e}} = obj; const res = sink (e);"]
L6H73[" const obj = {x:1,y:{z:3,u:taint}}; const {x,y:{z:c,u:e}} = obj; const res = sink (e);"]==>L7H73["case0169 "]
L3H68["特殊链路跟踪能力"]==>L4H74["展开运算符"]
L4H74["展开运算符"]==>L5H74["对象赋值"]
L5H74["对象赋值"]==>L6H74["const params={ a:a, b:b, c:taint}const newParmas = { ...params, };sink(newParmas)"]
L6H74["const params={ a:a, b:b, c:taint}const newParmas = { ...params, };sink(newParmas)"]==>L7H74["case0170 "]
L4H74["展开运算符"]==>L5H75["函数传参"]
L5H75["函数传参"]==>L6H75["const params={ a:a, b:b, c:taint}sink({...params})"]
L6H75["const params={ a:a, b:b, c:taint}sink({...params})"]==>L7H75["case0171 "]
L3H68["特殊链路跟踪能力"]==>L4H76["类constructor赋值成员属性"]
L4H76["类constructor赋值成员属性"]==>L5H76["成员变量"]
L5H76["成员变量"]==>L6H76["case0172"]
L4H76["类constructor赋值成员属性"]==>L5H77["成员函数/类"]
L5H77["成员函数/类"]==>L6H77["case0151"]
L3H68["特殊链路跟踪能力"]==>L4H78["父类与子类/super"]
L4H78["父类与子类/super"]==>L5H78["case0173"]
L3H68["特殊链路跟踪能力"]==>L4H79["无源码非sink函数"]
L4H79["无源码非sink函数"]==>L5H79["javascript原生"]
L5H79["javascript原生"]==>L6H79["case0174"]
L4H79["无源码非sink函数"]==>L5H80["prototype"]
L5H80["prototype"]==>L6H80["case0175"]
L4H79["无源码非sink函数"]==>L5H81["二三方包函数"]
L5H81["二三方包函数"]==>L6H81["case0176"]
L3H68["特殊链路跟踪能力"]==>L4H82["链式调用"]
L4H82["链式调用"]==>L5H82["var res=foo.bar0().bar1().bar2()"]
L5H82["var res=foo.bar0().bar1().bar2()"]==>L6H82["case0177"]
L3H68["特殊链路跟踪能力"]==>L4H83["装饰器"]
L4H83["装饰器"]==>L5H83["类装饰器"]
L5H83["类装饰器"]==>L6H83["case0178"]
L3H68["特殊链路跟踪能力"]==>L4H84["prototype增加成员"]
L4H84["prototype增加成员"]==>L5H84["function Person(){ this.getName = function(){ return taint ; }}Person.prototype.aaa = function () { return taint;}let p = new Person();sink(p.aaa());"]
L5H84["function Person(){ this.getName = function(){ return taint ; }}\n Person.prototype.aaa = function () { return taint;}\nlet p = new Person();\n sink(p.aaa());"]==>L6H84["case0179"]
L3H68["特殊链路跟踪能力"]==>L4H85["链路中非单个source、sink"]
L4H85["链路中非单个source、sink"]==>L5H85["单污点来源传播至n个sink点——n条链路"]
L5H85["单污点来源传播至n个sink点——n条链路"]==>L6H85["case0180"]
L4H85["链路中非单个source、sink"]==>L5H86["n个污点来源传播至单sink点——n条链路"]
L5H86["n个污点来源传播至单sink点——n条链路"]==>L6H86["case0181"]
L4H85["链路中非单个source、sink"]==>L5H87["无污点传播过程,source直接传入sink "]
L5H87["无污点传播过程,source直接传入sink "]==>L6H87["case0182"]
L3H68["特殊链路跟踪能力"]==>L4H88["异步编程方式"]
L4H88["异步编程方式"]==>L5H88["async/await 异步操作函数"]
L5H88["async/await 异步操作函数"]==>L6H88["case016等"]
L4H88["异步编程方式"]==>L5H89["promise异步处理"]
L5H89["promise异步处理"]==>L6H89["case0183"]
L4H88["异步编程方式"]==>L5H90["promisify异步处理"]
L5H90["promisify异步处理"]==>L6H90["case0184"]
L4H88["异步编程方式"]==>L5H91["普通回调函数"]
L5H91["普通回调函数"]==>L6H91["case0185"]
L3H68["特殊链路跟踪能力"]==>L4H92["sink点作为函数参数传入函数被调用"]
L4H92["sink点作为函数参数传入函数被调用"]==>L5H92["function a(param,func){ func(param)}"]
L5H92["function a(param,func){ func(param)}"]==>L6H92["case0186"]
L3H68["特殊链路跟踪能力"]==>L4H93["?.与??"]
L4H93["?.与??"]==>L5H93["case0196、case0197"]
L2H1["完整度"]==>L3H94["ts特有语法"]
L3H94["ts特有语法"]==>L4H94["强类型定义"]
L4H94["强类型定义"]==>L5H94["类型注解"]
L5H94["类型注解"]==>L6H94["let res=(a: number,b: number): number=>a+b;let y: number = res;"]
L6H94["let res=(a: number,b: number): number=>a+b;\n let y: number = res;"]==>L7H94["case0187 "]
L4H94["强类型定义"]==>L5H95["类型断言"]
L5H95["类型断言"]==>L6H95["let z = 'hello' as string;let w = <string> 'world';"]
L6H95["let z = 'hello' as string;let w = <string> 'world';"]==>L7H95["case0188 "]
L4H94["强类型定义"]==>L5H96["联合类型"]
L5H96["联合类型"]==>L6H96["var val:string|number "]
L6H96["var val:string|number "]==>L7H96["case0189 "]
L4H94["强类型定义"]==>L5H97["交叉类型"]
L5H97["交叉类型"]==>L6H97["case0190"]
L3H94["ts特有语法"]==>L4H98["接口与实现"]
L4H98["接口与实现"]==>L5H98["case0191"]
L3H94["ts特有语法"]==>L4H99["混入"]
L4H99["混入"]==>L5H99["class S implements A, B {...}"]
L5H99["class S implements A, B {...}"]==>L6H99["case0192"]
L3H94["ts特有语法"]==>L4H100["泛型"]
L4H100["泛型"]==>L5H100["case0193"]
L3H94["ts特有语法"]==>L4H101["重载"]
L4H101["重载"]==>L5H101["function add(a: number, b: number): number;function add(a: string, b: string): string;function add(a: string, b: number): string;function add(a: number, b: string): string;function add(a: Combinable, b: Combinable) { if (typeof a === 'string' || typeof b === 'string') { return a.toString() + b.toString(); } return a + b;}"]
L5H101["function add(a: number, b: number): number; \n function add(a: string, b: string): string; \n function add(a: string, b: number): string; \n function add(a: number, b: string): string; \n function add(a: Combinable, b: Combinable) { \n if (typeof a === 'string' || typeof b === 'string') { return a.toString() + b.toString(); } return a + b;}"]==>L6H101["case0194"]
L3H94["ts特有语法"]==>L4H102["命名空间"]
L4H102["命名空间"]==>L5H102["//a.tsnamespace Test { export interface a { do(param); }}//b.ts/// <reference path = 'a.ts' /> namespace Test { export class TestA implements a { public do(param) { return sink(param); } }}//c.ts/// <reference path = 'a.ts' /> /// <reference path = 'b.ts' /> function foo(test: Test.a, x: string){ test.do(x)}foo(new Test.TestA(),taint);"]
L5H102["//a.ts \n namespace Test { export interface a { do(param); }} \n//b.ts \n /// <reference path = 'a.ts' /> \n namespace Test { export class TestA implements a { public do(param) { return sink(param); } }} \n //c.ts \n /// <reference path = 'a.ts' /> \n /// <reference path = 'b.ts' /> \n function foo(test: Test.a, x: string){ test.do(x)} \nfoo(new Test.TestA(),taint);"]==>L6H102["case0195"]
L3H94["ts特有语法"]==>L4H103["针对类型不细粒度枚举 "]
L1H1["SAST污点追踪引擎能力评估(Nodejs)"]==>L2H104["准确度"]
L2H104["准确度"]==>L3H104["Source/Sink准确度"]
L3H104["Source/Sink准确度"]==>L4H104["Source作用域"]
L4H104["Source作用域"]==>L5H104["case021A+case021B"]
L3H104["Source/Sink准确度"]==>L4H105["Sink函数参数"]
L4H105["Sink函数参数"]==>L5H105["case022A+case022B"]
L3H104["Source/Sink准确度"]==>L4H106["source/sink内容不准确"]
L4H106["source/sink内容不准确"]==>L5H106["case023A+case023B+case023BB"]
L2H104["准确度"]==>L3H107["污点对象跟踪粒度 "]
L3H107["污点对象跟踪粒度 "]==>L4H107["对象级别"]
L4H107["对象级别"]==>L5H107["case024A,case024B"]
L3H107["污点对象跟踪粒度 "]==>L4H108["属性/元素级别 "]
L4H108["属性/元素级别 "]==>L5H108["对象属性"]
L5H108["对象属性"]==>L6H108["单层简单对象部分属性为污点"]
L6H108["单层简单对象部分属性为污点"]==>L7H108["case025A、case025B、case025AA、case025BB、\n case025AAA、case025BBB、case025AAAA、case025AAAAA、case025BBBBB "]
L4H108["属性/元素级别 "]==>L5H109["数组/Map/集合元素"]
L5H109["数组/Map/集合元素"]==>L6H109["单维数组/Map/集合中部分元素为污点"]
L6H109["单维数组/Map/集合中部分元素为污点"]==>L7H109["sink(a[1])"]
L7H109["sink(a[1])"]==>L8H109["case026A、case026B、case027A、case027B"]
L5H109["数组/Map/集合元素"]==>L6H110["多维数组/Map/集合中部分元素为污点"]
L6H110["多维数组/Map/集合中部分元素为污点"]==>L7H110["sink(a[0][1])"]
L7H110["sink(a[0][1])"]==>L8H110["case028A、case028B"]
L5H109["数组/Map/集合元素"]==>L6H111["传递元素不确定"]
L6H111["传递元素不确定"]==>L7H111["sink(a[b+c])"]
L7H111["sink(a[b+c])"]==>L8H111["case029AB"]
L4H108["属性/元素级别 "]==>L5H112["字符串中字符"]
L5H112["字符串中字符"]==>L6H112["字符串中部分字符为污点(使用整个字符串)"]
L6H112["字符串中部分字符为污点(使用整个字符串)"]==>L7H112["不将字符串算作数组是由于Javascript基础数据类型中String类型为基本数据类型,而数组算引用数据类型,两者本就不同。"]
L7H112["不将字符串算作数组是由于Javascript基础数据类型中String类型为基本数据类型,\n 而数组算引用数据类型,两者本就不同。"]==>L8H112["case0210AB"]
L2H104["准确度"]==>L3H113["不可达链路(路径敏感)"]
L3H113["不可达链路(路径敏感)"]==>L4H113["不涉及复杂求解问题"]
L4H113["不涉及复杂求解问题"]==>L5H113["数据流不可达"]
L5H113["数据流不可达"]==>L6H113["固定值直接赋值"]
L6H113["固定值直接赋值"]==>L7H113["var a=taintvar a=0sink(a)"]
L7H113["var a=taintvar a=0sink(a)"]==>L8H113["case0211B"]
L5H113["数据流不可达"]==>L6H114["固定值通过变量间接赋值"]
L6H114["固定值通过变量间接赋值"]==>L7H114["var b=0var a=taintvar a=bsink(a)"]
L7H114["var b=0var a=taintvar a=bsink(a)"]==>L8H114["b的定义又会有很多场景,不进行展开"]
L5H113["数据流不可达"]==>L6H115["固定数组/Map/集合"]
L6H115["固定数组/Map/集合"]==>L7H115["const a = [ '1', '2', '3']sink(a[taint])"]
L7H115["const a = [ '1', '2', '3']sink(a[taint])"]==>L8H115["case0213B、case0214B"]
L5H113["数据流不可达"]==>L6H116["对象属性set赋值为非污点"]
L6H116["对象属性set赋值为非污点"]==>L7H116["case0215B "]
L4H113["不涉及复杂求解问题"]==>L5H117["多个return语句"]
L5H117["多个return语句"]==>L6H117["{ ... return 0; return sink(taint);}"]
L6H117["{ ... return 0; return sink(taint);}"]==>L7H117["case0216B "]
L3H113["不可达链路(路径敏感)"]==>L4H118["涉及复杂求解问题"]
L4H118["涉及复杂求解问题"]==>L5H118["逻辑求解...不继续细化"]
L5H118["逻辑求解...不继续细化"]==>L7H118["var abc=ctx.request \nvar url='http://baidu.com' \nif(test){ url=abc test=false} \n if(!test){ ctx.curl(url)}"]
L7H118["var abc=ctx.requestvar url='http://baidu.com' \n if(test){ url=abc test=false} \n if(!test){ ctx.curl(url)}"]==>L8H118["case0217B、case0218B"]
L4H118["涉及复杂求解问题"]==>L5H119["表达式求解...不继续细化"]
L5H119["表达式求解...不继续细化"]==>L6H119["case0219B"]
L1H1["SAST污点追踪引擎能力评估(Nodejs)"]==>L2H120["兼容性"]
L2H120["兼容性"]==>L3H120["语言兼容性"]
L3H120["语言兼容性"]==>L4H120["Javascript"]
L4H120["Javascript"]==>L5H120["CommonJs规范"]
L4H120["Javascript"]==>L5H121["ECMAScript规范(ES6及以上)"]
L3H120["语言兼容性"]==>L4H122["Typescript"]
L2H120["兼容性"]==>L3H123["sdk平台兼容性"]
L3H123["sdk平台兼容性"]==>L4H123["macos-arm"]
L3H123["sdk平台兼容性"]==>L4H124["macos-x64"]
L3H123["sdk平台兼容性"]==>L4H125["linux"]
L3H123["sdk平台兼容性"]==>L4H126["windows"]
L2H120["兼容性"]==>L3H127["数据兼容性"]
L3H127["数据兼容性"]==>L4H127["是否可接收外部数据作为source、sink"]
L1H1["SAST污点追踪引擎能力评估(Nodejs)"]==>L2H128["性能"]
L2H128["性能"]==>L3H128["扫描耗时(变更不同机器配置,依据相同靶场来测试)"]
L1H1["SAST污点追踪引擎能力评估(Nodejs)"]==>L2H129["接入成本"]
L2H129["接入成本"]==>L3H129["服务接口调用"]
L2H129["接入成本"]==>L3H130["sdk接入"]