Skip to content

污点跟踪

作者: 杨广亮
更新日期: 2026-01-07
版权声明: 本文档遵循 CC BY-NC-SA 4.0 协议

污点跟踪(Taint Analysis)是在数据流分析上的扩展,用于追踪指定数据在程序中的流动,被广泛用于检测数据隐私泄露、安全漏洞等。其核心思想是,把感兴趣的数据源(Source)打上标记(污点Taint),观察和追踪其流向和传播,检查有污点的数据最终是否达到了敏感或危险指令,也被称为汇聚点(Sink)。如果污点数据最终达到Sink,那么可能存在安全问题。Source和Sink之间的数据流也被称为污点流(Taint Flow)。

因此,对于污点分析而言,它有三大要素:污点源(Source)、污点汇聚点(Sink)、污点传播(Propagation)。本章节将分别予以介绍。

污点源(Source)

污点源(Source)是指感兴趣或者不可信数据的来源,即"脏数据"是从哪里来,常见的污点源包括:

  • 用户数据:如用户名、密码、手机号、地理位置等
  • 文件数据:如存放在本地的密码文件、数据库文件等
  • 可被攻击者控制的数据:如程序入口函数的参数、网络数据等

污点汇聚点(Sink)

污点汇聚点(Sink)是指危险操作的位置,即指"脏数据"不能流到的地方,常见的污点汇聚点:

  • 数据库查询:如SELECT、UPDATE、DELETE等
  • 文件操作:如读取文件、写入文件等
  • 命令执行:如执行操作系统命令、调用系统函数等
  • 网络请求:如发送HTTP请求、发送邮件等

当污点数据流到Sink,就可能有安全风险。

污点传播(Propagation)

污点传播(Propagation)是指污点如何在程序中扩散,即污点传播的规则,常见的污点传播规则有:

  • 赋值传播:右值的污点会污染左值
  • 字符串操作:如字符串拼接、字符串截取、字符串替换等
  • 容器操作:如List、Map、Set等容器操作
  • 函数调用:如调用系统函数或第三方库函数,可能导致污点传播

与污点传播规则相对应的是污点清洗规则(Taint Removal Rules),即对污点进行清洗,使其不再污染其他变量。

污点分析算法

污点分析是在数据流分析的基础上,实现对污点的跟踪,其算法步骤如下:

算法:污点分析
输入:程序代码、数据流、污点源Source、污点汇聚点Sink、污点传播规则PropagationRules、污点清洗规则RemovalRules
输出:发现Source到Sink的污点流Taint flows

1. 初始化:
   TaintSet = ∅  // 存储所有被污染的变量或堆对象

2. 遍历每条语句:
    for each 语句 stmt:

        case stmt of:

            // 情况1:污点源
            x = source():
                // 标记x为污点
                TaintSet.add(x)
                // [可选] x的指向集也可以打污点
                TaintSet.add(pts(x))  

            // 情况2:污点传播
            stmt ∈ PropagationRules:
                // 应用污点传播规则
                apply_propagation_rule(stmt)

            // 情况3:污点清洗
            stmt ∈ RemovalRules:
                // x不再是污点
                TaintSet.remove(x) 
                // [可选] x的指向集也可以清除污点
                TaintSet.remove(pts(x)) 

            // 情况4:污点汇聚点
            sink(x):
                if x in TaintSet:
                    // ⚠️ 发现漏洞!
                    warning(x, stmt)  
                    // 收集Taint Flow
                    collect_taint_flow(x, stmt)

3. 返回所有发现的taint flows

污点分析应用

[01] // 有漏洞的代码
[02] public void login(UrlRequest request, Connection conn) {
[03]     // Step 1: username 是污点源
[04]     String username = request.getParameter("username");  // [SOURCE]
[05]     
[06]     // Step 2: query 被污染(污点传播)
[07]     String query = "SELECT * FROM users WHERE name='" + username + "'";  // [TAINTED]
[08]     
[09]     // Step 3: 污点流到了危险的地方(污点汇聚点)
[10]     conn.executeQuery(query);  // [SINK] 
[11] }

上述代码中存在一个SQL注入漏洞。漏洞位置为第7行,污点分析的具体情况如下:

漏洞类型:       SQL注入
污点源:        [04] request.getParameter("username") 
污点汇聚点:     [10]stmt.executeQuery(query)
污点路径:       username -> query -> executeQuery

总结

污点分析在软件安全检测被广泛应用,是程序分析在安全领域中重要的工具。