摘 要:2017 年颁布的GB/T 34943—2017《C/C++语言源代码漏洞测试规范》、GB/T 34944—2017《Java 语言源代码漏洞测试规范》、GB/T 34946—2017《C#语言源代码漏洞测试规范》等国家标准使代码审计朝着规范化方向发展。然而,当前代码审计工作仍面临部分问题。通过对知名代码审计工具Fortify SCA 的审计规则进行深入研究,文章完成了国标合规性审计应用实验,为代码审计提供了有效的解决方案。
1、国标漏洞覆盖分析
识别并确认工具是否满足要求是国标测试的关键问题之一。其中,国标测试内容主要参考了MITRE公司发布的CWE(Common Weakness Enumeration),同时纳入了部分典型漏洞,为分析工具的国标覆盖性提供了重要线索和支撑。
Fortify SCA 可以按照CWE 分类对漏洞进行报告,但与CWE不存在官方声明的对应关系,仅将其视为一种漏洞分类参考方式。有时一条Fortify SCA 官方规则的分类元中记录了多个CWEID(CWE规则标识),而一个CWEID可能同时在多个规则中出现。本文首先还原了国标与CWE 的对应关系,其次对Fortify SCA规则进行了溯源,通过最大公约数的方式完成了Fortify SCA 的国标覆盖分析。
基于研究所用Fortify的安全规则库,结果表明GB/T 34944—2017标准中列举的代码漏洞存在少量未覆盖的漏洞。
(1)1个行为问题:不可控的内存分配。
(2)2个安全功能问题:①依赖referer 字段进行身份鉴别;②Cookie 中的敏感信息明文存储。
(3)1个Web问题:依赖外部提供的文件名称或扩展名。
(4)1个用户界面错误问题:点击劫持。
2、Fortify SCA 规则解析
在Fortify SCA中,并非所有规则均支持自定义,目前可供自定义的规则包括AliasRule,CharacterizationRule,ControlflowRule,DataflowRule,SemanticRule,Structural-Rule及SuppressionRule。
其中,StructuralRule,DataflowRule及CharacterizationRule等规则的使用频率较高。StructuralRule应用于结构分析器,旨在将目标代码建模为结构树,从而通过BNF范式进行模式匹配,识别代码中的类、函数、字段、代码块、语句和表达式等,进而实现指定漏洞的检测。而CharacterizationRule使用“StructuralMatch”节点识别代码结构,其语法与StructuralRule 一致,可以定义TaintSource/TaintWrite,TaintEntrypoint,TaintTransfer,TaintSink,TaintCleanse等5种污点特征规则,效果等同于数据流规则的Dataflow-SourceRule,DataflowEntryPointRule,DataflowPassthrough-Rule,DataflowSinkRule和DataflowCleanseRule。
3、国标审计规则实现
以国标示例代码为基础,编制漏洞“Cookie中的敏感信息明文存储”的审计规则。观察代码可知,修复方案首先对明文进行加密,然后将其存储至Cookie,其中存在数据流转。因此,可以使用数据流规则定义此类漏洞的审计规则。为了说明规则的定义过程,首先在国标示例代码基础上构建以下目标代码:
public class CookiePlaintextExample {
final static String address="苏州市工业园区苏州华克斯信息科技有限公司";∥
TaintSource
private static String getOrgInfo(){
return address;
}
public String encryptPlainText(String plainText){
try {
…
cipher.ini(t Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedText = cipher.doFinal(plainText.getBytes());
return new String(encryptedText);
} catch( InvalidKeyException e){
}
…
}
public void fixedCookiePlaintext(String address){
String addr = encryptPlainText(address);
Cookie cookie = new Cookie("Address",addr);
}
}
然后,使用CharacterizationRule 定义如下数据流规则(仅展现关键内容):
<CharacterizationRuleformatVersion=< span>"20.2.0"language="java">
</CharacterizationRuleformatVersion=<>
<![CDATA[
FunctionCall fc:fc.name contains "getOrgInfo"
]]>
<![CDATA[
TaintSource(fc,{+BTCPLAINTEXT})
]]>
<CharacterizationRuleformatVersion=< span>"20.2.0"language="java">
</CharacterizationRuleformatVersion=<>
<![CDATA[
FunctionCall call:call.function is
[ Function f:f.constructor or f.name == "init^" and f. enclosingClass is[ Class c:c.name == "javax.servlet.http.Cookie"]]
and call.arguments.length==2 and call.arguments[1] is
[Expression exp:]
]]>
<![CDATA[
TaintSink(exp,[ BTCPLAINTEXT])
]]>
以上规则首先定义污点标识BTCPLAINTEXT(明文标识)与BTCSECRET(加密标识),同时利用一个函数模拟污染数据(即TaintSource)的引入;然后通过结构语法编制发现Cooike对象实例化结构体的语句,并指定汇点标识为“BTCPLAINTEXT”,可以发现标识了BTCPLAINTEXT 的所有Cookie对象实例化的源码结构。至此,对于国标漏洞“Cookie中的敏感信息明文存储”的检测目标初步达成。
4、漏误报问题解析
在对上述代码进行审计时,所编制的“Cookie中的敏感信息明文存储”的检测规则存在漏报和误报等问题。其中,漏报发生在以下源码位置:
…
String addr=encryptPlainText(address);
Cookie cookie=new Cookie("Address",addr);
…
主要原因是函数encryptPlainText 调用了外部加密库,导致数据流分析引擎在此中断,其后的Cookie对象实例化漏洞未被报告。对此,需要在规则包中补充以下TaintTransfer定义,从而确保数据流分析引擎稳定运行。
<CharacterizationRuleformatVersion=< span>"20.2.0"language="java">
</CharacterizationRuleformatVersion=<>
<![CDATA[
FunctionCall call:call.function is
[Function f:f.name is "encryptPlainText"] and call.arguments
[0] is[ Expression inArgument:]
]]>
<![CDATA[
TaintTransfer(inArgument, call, {+BTCSECRET})
]]>
在解决漏报问题后,address数据被先行加密再写入Cookie,若仍有漏洞报告,可能此时存在误报问题。可以通过修改TainSink规则的触发条件予以解决:
<![CDATA[
TaintSink(exp,[ BTCPLAINTEXT && !BTCSECRET])
]]>
以上针对“Cookie中的敏感信息明文存储”漏洞的审计规则核心内容已经完成,通过纳入国标中漏洞相关的描述信息,可以进一步完善该规则。Fortify SCA提供了CustomDescriptionRule等规则,可以较好地满足自定义规则描述信息的需求。利用CustomDescriptionRule,可以自行为漏洞添加Abstract,Explanation,Recommendations,Tips,References,ContentType等描述信息。按照Abstract,Explanation,Recommendations,Tips及References对上述Cookie漏洞的描述信息进行信息编组,可以生成自定义描述格式文件,从而在合规审计中快速甄别被国标定义的漏洞。
5、国标合规审计实验
实验环境如表1所列,本文使用开发工具IntelliJIDEA 2020.1及Oracle JDK 1.8对国标示例代码进行扩展,并确保正确编译;使用命令行工具调用FortifySCA;使用自定义规则(gbt34944ruleplus.xml)完成示例代码的审计。
如图1所示,审计结果如预期般报告了一个漏洞,而示例代码中函数fixedCookiePlaintext()的Cookie使用并没有报告为漏洞,证明通过审计规则的准确定义可以有效减少误报、避免漏报。其中,漏洞修复推荐信息显示为依据国标相关内容定制的漏洞修复建议(图2)。
图1
图2 漏洞修复推荐信息
参考文献:
[1]国家质量监督检验检疫总局,国家标准化管理委员会.GB/T 34944—2017.Java语言源代码漏洞测试规范[S].北京:中国标准出版社,2017.
[2]MICRO FOCUS.Micro Focus Fortify Static Code Analyzer[EB/OL].https:∥www.microfocus.com/documentation/fortify-staticcode-analyzer-and-tools/1810/SCA_Perf_Guide_18.10.pdf.
[1]孟宪勇,张伟.基于Fortify SCA的GB/T 3494X源码审计规则研究与应用[J].计算机应用文摘, 2024, 40(12):41-43.
相关内容:
GB/T 34944-2017 Java语言源代码漏洞测试规范解析
原文始发于微信公众号(华克斯):基于Fortify SCA 的GB/T 3494X 源码审计规则研究与应用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论