本文详细介绍了如何利用CodeQL静态分析工具检测C++代码中未处理的错误返回值,通过构建自定义查询包、定义错误类型类、实现本地和全局污点跟踪等技术手段,高效识别潜在安全漏洞。
使用CodeQL检测未处理的错误代码
当开发者发现代码库中存在未处理的错误代码时,手动排查往往效率低下。以Kubernetes的CVE-2018-1002105漏洞为例,错误处理不当可能导致攻击者通过API建立后门连接。Trail of Bits团队采用CodeQL进行变体分析,批量检测此类问题。
构建CodeQL数据库
首先需要使用CodeQL CLI创建分析数据库:
1
codeql database create -l cpp -c 'MSBuild.exe <solution>.sln' <solution>.codeql
设置自定义查询包
创建qlpack.yml文件定义查询包依赖:
1
2
3
name : <some snazzy QL pack name>
version : 0.0.1
libraryPathDependencies : [ codeql-cpp]
检测未处理错误
定义CustomError类型捕获返回CustomErrorType的函数调用:
1
2
3
4
5
class CustomError extends FunctionCall {
CustomError () {
this . getUnderlyingType () . getName () = "CustomErrorType"
}
}
基础查询语句定位所有错误返回点:
1
2
3
4
5
6
from
CustomError ce
select
ce.getLocation(),
"Unhandled error code in ", ce.getEnclosingFunction().getName(),
"Error code returned by ", ce.getTarget().getName()
定义错误处理逻辑
通过本地污点跟踪判断错误是否被处理:
1
2
3
4
5
6
7
8
predicate isChecked() {
exists (IfStmt is |
TaintTracking::localTaint(
DataFlow::exprNode(this),
DataFlow::exprNode(is.getCondition().getAChild*())
) or
// 类似处理while/switch语句
}
优化查询结果
排除三种误报情况:
错误被直接返回
错误作为函数参数传递
错误赋值给成员变量
对应CodeQL实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
predicate isReturnValue() {
exists (ReturnStmt rs |
TaintTracking::localTaint(/*...*/)
)
}
predicate isPassedToFunction() {
exists (FunctionCall fc |
TaintTracking::localTaint(/*...*/)
)
}
predicate isAssignedToMemberVar() {
exists (MemberVariable mv, MemberFunction mf |
mf = this.getEnclosingFunction() and
mf.canAccessMember(mv, mf.getDeclaringType()) and
TaintTracking::localTaint(/*...*/)
)
}
全局污点跟踪分析
定义全局污点配置类:
1
2
3
4
5
6
7
8
9
10
class GuardConfiguration extends TaintTracking :: Configuration {
override predicate isSource ( DataFlow :: Node source ) {
source . asExpr () . ( FunctionCall ) . getUnderlyingType () . getName () = "CustomErrorType"
}
override predicate isSink ( DataFlow :: Node sink ) {
exists ( IfStmt is | sink . asExpr () = is . getCondition () . getAChild * ())
// 其他分支语句处理
}
}
最终该技术在真实项目中发现了150+个需要修复的问题点。CodeQL使我们能够将漏洞模式编码为可重复使用的查询,确保同类错误不会再次出现。
Licensed under CC BY-NC-SA 4.0