“数据流污点跟踪只传播右端来源时,这个例子的常量写入全部为空标签,也会漏掉两层控制泄漏。加入pc有必要,正确处理敏感升级同样有必要。”
形式陈述
跟踪的是来源集合
在固定变量、全部初始化、无堆和无异常的整数IMP中执行程序。来源全集
这里采用只跟踪数据操作的规则:常量标签为空,读变量取得当前标签,二元运算取操作数标签并集;赋值
sink是检查位置。固定允许来源集合A,最终sink值可通过检查当且仅当
一次执行的数据依赖图
为每个初始值、常量求值、二元运算和赋值结果建立事件节点。读变量引用该名字最近的值节点;二元运算从两个输入值连边,赋值从右端结果连边。只为真正执行的操作建图,边总指向较晚事件,因此有向无环。来源标记放在相应初始值节点上。
不变量:当前值的污点集合,等于沿这张执行数据图反向可达的来源标记集合。常量没有来源前驱,读取得已有集合,二元节点合并两组可达来源,赋值让新节点替换当前名字的旧节点。对事件顺序归纳便得到不变量。
图里没有从条件选择连到分支赋值的边。这个省略定义了本页的分析能力;增加控制信息需要另行规定语义,不能在结论中悄悄补上。
直觉
标签是随值移动的便签
如果字段a标为“表单”,字段b标为“数据库”,则a+b的结果同时带两个便签。把这个结果复制给t,便签一同复制;随后t:=0产生全新的常量值,旧便签被覆盖。一个名字曾经带过标签,并不意味着它永远带着标签。
便签记录哪些读值参与了计算,未必记录哪些输入真正能改变最终答案。计算h-h读取h两次,依赖图仍含h来源;数学上两项却总会抵消。这正是执行依赖与语义敏感性不同的地方。
例子与边界
两个来源和一次覆盖
设a=3、b=4,
t := a + b
u := t - a
t := 0
out := u
第一步t=7,标签
空标签仍可能泄漏秘密
if h then out := 1 else out := 0
两支右端都是常量,因此h=0和h=1时out标签都为空,sink检查都会通过;公开值却分别是0和1。秘密经由“选了哪个赋值”流动,执行数据图没有记录这类边。
动态信息流监测另外维护pc及敏感升级状态,目标是限定双运行之间可观察的差异。两者的差别在于承诺:来源分析返回执行数据来历,安全监测要说明不同秘密运行为何不能产生两个不同的可接受低结果。简单把守卫标签并入被执行赋值,也不足以自动得到后者的定理。
未标记来源和遗漏操作
若h根本未列入来源,out:=h也得到空标签。正确传播不能补救错误的来源配置。若语言扩展为指针读写或数组索引,还必须说明地址依赖、别名和内存粒度如何影响传播;固定名字的规则不能直接覆盖这些新操作。
推论与应用
运行成本和可复算接口
把q个来源存为位集,令
下载解释器用整数位掩码表示来源,sources参数指定每个初始变量的掩码。它不必保存完整事件图即可传播标签;若为了说明原因而存图,还需要按事件节点与边计额外空间。trace=True记录实际赋值和分支,日志每条还存标签掩码,不能视为零成本。
终点要求同时交出值、来源集合及不同秘密的两次结果。三者放在一起,才能发现“sink通过”究竟验证了哪一种政策。
结构迁移
在两来源主例中,将第二句改成u:=b,其余不变。最终值还是4,但标签从if a then out:=u else out:=0,out的标签在两条分支分别为
参考资料
[1] James Clause, Wanchun Li and Alessandro Orso, “Dytan: A Generic Dynamic Taint Analysis Framework”, ISSTA 2007,pp.196–206,§3:来源、传播政策、默认并集和sink;Dytan框架也支持控制流政策,本页只形式化其数据流选择。默认来源并集与sink配置分别对应§3的传播政策和检查位置接口。
[2] Thomas H. Austin and Cormac Flanagan, “Permissive Dynamic Information Flow Analysis”, UCSC-SOE-09-34技术报告,2009,§§1、3:动态标签中的隐式流及朴素升级反例。