污点分析:一滴输入如何穿过整个程序

TL;DR

理解污点追踪、数据流、source、sink 和 sanitizer,掌握 AI 代码安全检查的基本思路。

用 source、sink 和 sanitizer 解释污点追踪,理解静态分析如何检查用户输入是否流向危险操作。

污点分析:一滴输入如何穿过整个程序

污点分析:一滴输入如何穿过整个程序

安全工具经常使用一个很形象的概念:污点。用户输入、请求参数、环境变量或外部文件,都可以被标记成“可能不可信”。如果这份数据一路流入 SQL 执行、命令执行、文件路径或 HTML 输出等危险位置,工具就会发出提醒。这个过程叫 taint tracking,中文常译为污点追踪或污点分析。

三个角色:source、sink 和 sanitizer

Source 是污点的来源,比如 HTTP 参数。Sink 是需要特别谨慎的终点,比如拼接 SQL 的函数。Sanitizer 是清洗或验证步骤,例如参数化查询、路径规范化和输出转义。安全分析要判断的不是“输入有没有出现过”,而是它是否在抵达危险点前经过了足够可靠的处理。

重要的是,数据不一定以原样传播。一个字符串可能被放进对象,再从对象属性取出;也可能经过函数调用、数组拼接和格式转换。优秀的分析器会构建数据流图,尽量跟踪这些传播关系,同时承认某些动态行为无法被静态准确预测。

它为什么适合检查 AI 生成代码

AI 很容易生成“看起来合理”的输入处理代码。它可能知道要做校验,却把校验放在了错误位置;也可能只检查了前端,后端仍然把未验证数据交给危险函数。污点分析提供了一条比“模型说已经安全”更机械的检查路径:从输入出发,看是否存在未经过防护的危险流向。

这不是说工具会自动发现所有漏洞。分析器需要知道哪些函数是来源、终点和清洗器;自定义框架、反射、模板和代码生成可能造成漏报。它也可能报告需要人工确认的误报。

一个实用的协作方法

让 AI 新增上传、搜索、导出或管理功能时,要求它同时列出所有外部输入和最终使用位置。再用静态分析或安全规则验证这些路径。这样,模型负责解释意图,污点分析负责检查数据是否越过了不该越过的边界。

CodeQL 对 JavaScript 和 TypeScript 的数据流与污点追踪有清晰示例,可阅读官方指南

KEEP READING