Analyzing data flow in Java

💡 原文中文,约12900字,阅读约需31分钟。
📝

内容提要

本文介绍如何使用CodeQL库对Java程序进行数据流分析,涵盖本地数据流、全局数据流和污点跟踪。本地数据流分析单个方法内的数据传递,全局数据流追踪整个程序,污点跟踪扩展了非保值步骤。文章提供了配置类、谓词定义及示例查询,并附有练习题及答案,帮助用户编写自定义数据流查询。

🔎

延伸解读

本地数据流与全局数据流的选择

文章指出,本地数据流分析单个方法内的数据传递,速度快且精度高,适合许多查询;而全局数据流追踪整个程序,功能更强但精度较低且耗时耗内存。实际应用中,应根据分析目标权衡:若问题局限于方法内,优先使用本地数据流;若需跨方法追踪,则需全局数据流。

污点跟踪的实用价值

污点跟踪扩展了数据流分析,能识别非保值步骤,如字符串拼接导致的污点传播。这在安全分析中尤为重要,例如检测远程用户输入是否流入敏感操作。文章示例展示了如何配置污点跟踪,并利用预定义的RemoteFlowSource识别远程可控数据源,有助于发现安全漏洞。

配置类的核心作用

使用全局数据流或污点跟踪时,需自定义配置类,通过重写isSource、isSink等谓词定义数据流的起点和终点。配置类的名称必须唯一,以确保分析正确。此外,可通过isBarrier或isSanitizer限制流经路径,增加分析的精确性。理解这些配置机制是编写有效查询的关键。

Q&A

如何使用CodeQL对Java程序进行本地数据流分析?

本地数据流分析单个方法或可调用内的数据流。使用DataFlow模块,通过localFlowStep或localFlow谓词追踪数据流。例如,DataFlow::localFlow(DataFlow::parameterNode(source), DataFlow::exprNode(sink))可找到从参数到表达式的流。

CodeQL中本地污点跟踪与本地数据流有何区别?

本地污点跟踪扩展了本地数据流,包含非保值步骤,如字符串拼接。例如,若x是污点字符串,则y = temp + ", " + temp也是污点。使用TaintTracking模块的localTaintStep或localTaint谓词。

如何配置全局数据流分析?

通过扩展DataFlow::Configuration类,定义isSource和isSink谓词,并设置唯一名称。然后使用hasFlow谓词执行分析。例如,class MyConfig extends DataFlow::Configuration { ... }。

CodeQL中全局污点跟踪如何配置?

通过扩展TaintTracking::Configuration类,定义isSource和isSink谓词,并可选择isSanitizer和isAdditionalTaintStep。使用hasFlow谓词执行分析。

CodeQL中RemoteFlowSource类有什么用途?

RemoteFlowSource类表示可能被远程用户控制的数据流源,常用于发现安全漏洞。它定义在semmle.code.java.dataflow.FlowSources中,可作为污点跟踪的源。

如何编写查询找到所有硬编码字符串用于创建java.net.URL?

使用本地数据流:import semmle.code.java.dataflow.DataFlow,然后查询StringLiteral流向URL构造函数的第一个参数。例如:DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0)))。

CodeQL中如何定义自定义流源?

可以定义一个类继承DataFlow::ExprNode或MethodAccess,并在isSource谓词中匹配特定方法。例如,GetenvSource类匹配System.getenv调用。

🏷️

标签

➡️

继续阅读