写点什么

SARIF:DevSecOps 工具与平台交互的桥梁

发布于: 2021 年 03 月 02 日

摘要:静态扫描工具融入在 DevSecOps 的开发过程中,对提高产品的整体的安全水平发挥着重要的作用。为了获取安全检查能力覆盖的最大化,开发团队通常会引入多个安全扫描工具。为了降低各种分析工具的结果汇总到通用工作流程中的成本和复杂性, 业界开始采用静态分析结果交换格式(SARIF)。


1. 引言


从 2012 年 Gartner 的研究报告“DevOpsSec: Creating the Agile Triangle”提出了 DevSecOps 的概念, 到目前 DevSecOps 已经成为构建企业级研发安全的重要模式。 DevSecOps 模式中有些重要的原则:安全左移、默认安全、运行时安全、安全服务自动化/自助化、基础设施即代码(IaC)、持续集成和交付,以及需要组织和文化建设。



在 DevSecOps 的过程中,最重要的一环就是安全工具能够快速集成到自动化平台,保证平台的持续集成和交付,从而提高产品的整体的安全水平。 在整个研发过程中静态安全检查工具是保证代码安全的重要手段,每个安全检查工具因为技术实现上的差异,对不同的安全缺陷有着不同的检查能力,所以稍微大型一些的开发团队, 在开发的时候会引入多个安全扫描工具,以获取安全检查能力覆盖的最大化。 但多工具的集成, 就会对程序员或平台的集成会带来以下问题:


  • 对于开发人员


o 在使用 IDE 的时候, 缺少一个通用的检查工具结果接口和交互接口;


o 需要查看多个检查工具的结果;


  • 对于集成平台


o 需要学习每个工具的输出扫描格式;


o 在扫描报告转入到缺陷跟踪系统的时候, 缺少一个通用的缺陷转换程序;


o 缺少一个通用扫描结果度量方式。



为了解决这些的问题,最初由微软、Micro focus 等几家静态分析软件公司提出了:静态分析结果交换格式(Static Analysis Results Interchange Format (SARIF))。


2. 结构化信息标准促进组织(OASIS)


结构化信息标准促进组织(Organization for the Advancement of Structured Information Standards (OASIS))是一个非营利性的国际财团,推动全球信息社会制定、融合和采用开放标准。OASIS 促进行业共识,并制定网络安全、隐私、云计算、物网、智能电网和其他领域的全球标准。OASIS 开放标准具有降低成本、刺激创新、开拓全球市场和保护自由选择技术的权利的潜力。


OASIS 成员广泛代表公共和私营部门技术领导者、用户和影响者的市场。自 1993 年成立开始,OASIS 已经发展成为了由来自 100 多个国家的 600 多家组织、企业,参与人数超过 5000 人的国际化组织。相比其他组织,OASIS 形成了更多的 Web 服务标准的同时也提出了面向安全、电子商务的标准,同时在针对公众领域和特定应用市场的标准化方面也付出很多的努力。


OASIS 以其管理透明化及工作流程化而著称。OASIS 成员自己设置技术议程,并通过简单的工作流程促进产业达成一致以及统一不同观点。OASIS 的全部工作将是通过公开投票的方式认可,管理层具有责任心并且不受其他因素制约。OASIS 理事会和技术顾问委员会的成员都由民主选举产生,任期 2 年。OASIS 的领导层是由于个人能力而非资金资助、企业背景或特别任命而产生的。


OASIS 现在拥有最受人们广泛接受的 XML 以及 Web 服务标准 2 个信息入口,Cover Pages 和 XML.org。OASIS 的成员分会包括 CGM Open、DCML、LegalXML、PKI 和 UDDI。


OASIS 于 1993 年最初以 SGML 开放组织名义成立。它最初是代表用户和产品提供商致力于推动产品互操作性架构的开发以及支持标准广义标记语言(Standard Generalized Markup Language)。1998 年,组织的名称正式更换为 OASIS 开放组织,以表示其在技术领域的工作已经扩展到可扩展标记语言 (XML)及相关标准以外的范围。


  • OASIS 主要技术成员



OASIS 成立 SARIF 技术委员会

因为静态分析工具在安全保障中的重要地位,越来越多的静态分析工具的主要厂商 CA Technologies, Cryptsoft, FireEye, GrammaTech, Hewlett Packard Enterprise (HPE), Micro Focus, Microsoft, New Context, Phantom, RIPS, SWAMP, Synopsys, U.S. DHS, U.S. NIST 等等都在推进静态分析工具的通用数据格式的标准。 2017 年 10 月 12 日, OASIS 成立了 SARIF 技术委员会为静态分析制定国际互操作性标准。SARIF 技术委员会汇集了主要软件公司、网络安全提供商、政府、安全协调专家、程序员和顾问,就一种数据格式达成一致,该格式将由整个行业的工具解析。目标是通过聚合来自多个工具的数据,使软件开发人员更容易评估其程序的质量和安全性。


在接下来的 2018 年,SARIF 就获得了 OASIS 的年度 Open Standards Cup 的杰出新计划(Outstanding New Initiative)。


3. SARIF 规范简介


  • SARIF 的目标:


o 全面捕获常用静态分析工具生成的数据范围;


o 分析工具直接输出的一种有用的格式,并且是可以将任何分析工具的输出转换成的有效交换格式;


o 适用于与分析结果管理相关的各种方案,并且可扩展用于新方案;


o 降低将各种分析工具的结果汇总到通用工作流程中的成本和复杂性;


o 捕获有助于评估项目是否符合公司政策或符合认证标准的信息;


o 采用广泛使用的序列化格式,可以使用现成的工具进行解析;


o 表示各种编程工件的分析结果,包括源代码和目标代码。


  • 规范描述的范围:


o 单个日志文件中包含多个不同分析工具的运行结果;


o 执行每次运行的分析工具,包括:


§ 工具名称


§ 工具版本


o 分析工具的调用,包括:


§ 命令行


§ 开始时间和结束时间


o 被分析的文件,包括:


§ Uniform Resource Identifier(URI)


§ Multipurpose Internet Mail Extensions(MIME 类型)


§ 嵌套文件,例如压缩存档中包含的文件,例如 ZIP 文件。


o 执行的分析规则


o 有关产生的每个分析结果的信息,包括:


§ 结果的位置


§ 违反的规则


§ 违规的严重性


§ 代码中与结果相关的执行路径


§ 相对于结果的调用堆栈


§ 该问题的可能修补程序


o 分析工具产生的通知,包括:


§ 进度消息


§ 配置信息


  • 不包含在规范范围


o 用于访问、操纵或管理 SARIF 文件中包含的信息的任何应用程序编程接口(API)的定义或实现;


o 用于查看或以其他方式与 SARIF 文件中包含的信息进行交互的任何体验的定义或实现。


目前这个版本有 200 多页。按照由浅入深的方式,介绍将分为基础和进阶两个部分。此篇为基础部分,将完成规范中的基本概念和初步使用的介绍。 后续的进阶部分,将完成深层次用户的需求实现。


4. SARIF 基础


SARIF 文件是以一种以面向对象(Object Model)的方式构成 json 文件。 这样的设计便于工具通过对象的方式对应到 json 的各个组成部分。 SARIF 的 json 文件格式通过格式文件 sarif-2.1.0-rtm.4.json 定义, 当前版本是 2.1.0。


我们先来看一个 ESLint 扫描结果的一个 SARIF 的例子。


  • 代码(simple-example.js):


var x = 42


  • ESLint 检查命令:


eslint --format sarif simple-example.js --output-file simple-example.sarif


  • SARIF 格式输出的检查结果




直接看这个报告,还是很容易直接读懂的。


4.1. SARIF schema 的基本组成


下图为 SARIF 的 schema 定义文件的视图:



从 SARIF 的 schema 的结构。 我们可以看到:


  • 第 7 行(“type”: “object”,), 定义了一个节点名为类型的对象;

  • 第 8-45 行,定义了这个对象的属性包(“properties”)中有的 5 个子节点:$schema,version,runs,inlineExternalProperties,properties;

  • 第 47 行, "required"节点,定义了这个对象的属性节点中必须有的节点:version, runs;

  • 第 16-19 行,给出了节点 version 的定义,其中 17 行节点 description 给出了这个节点 version 的描述;18 行告诉了 version 的取值是个枚举值,并且只有一个可能的取值:2.1.0;

  • 第 21-29 行,给出了节点 runs 的定义:


o 22 行,description 给出了这个节点的描述:一组运行结果;


o 23 行,给出了这个节点的类型是数组(array),每一个运行结果就是这个数组中的一个结果;


o 24 行,数组最小可以为 0;也就是说可以没有运行结果;


o 25 行,结果的内容可以不唯一;


o 26 行,每个数组元素的组成定义;


o 27 行,数组元素的定义参考定义组节点 definitions 下的 run 的定义;


  • 第 41-44 行,定义了这个对象的扩展属性通过 key,value 的方式定义,具体的定义参考定义组节点 definitions 下的 propertyBag 的定义;

  • 第 49-3369(到结束)行,通过定义组节点 definitions 定义了 52 个基础对象:address, artifact, artifactChange 等,包括前面提到的 run 和 propertyBag;

  • SARIF 就是通过这 52 个基础对象,以及这些基础对象的组合,并通过属性包的 key,value 方式完成各种扩展信息的定义, 从而形成了了一个适应各种静态扫描分析工具报告的规范化;


4.2. SARIF 对象定义(definitions)的基本规则


  • 通过定义组节点 definitions 定义了 52 个基础对象, 完成对象的定义的描述;

  • 通过基本类型(type)定义每个属性的类型;类型有:object, string,number, integer, boolean, array;对于 array 类型,后面需要跟 items,来说明数组元素的信息;

  • 通过 enum 来枚举属性的值;例如: “enum”: [ “none”, “note”, “warning”, “error” ]

  • 通过参考引用的方式完成相似类型的定义描述,避免了反复定义和定义的统一性,归一性;例如:"$ref": “#/definitions/propertyBag”,表明该对象是参考定义组 definitions 下的 propertyBag;

  • 通过 anyOf,required 属性定义对象中必须存在的属性, 默认情况下,属性不是必须的;

  • 每一个对象都有一个 properties 属性,通过属性包的方式中 key,value 的方式完成对象扩展信息定义的需要;


4.3. 定义举例:消息(message)


  • message 在 definitions 中的定义:




  • description:对象的描述,用于封装提供给用户读取的信息;

  • type: 对象;

  • additionalProperties: 没有辅助属性信息;

  • properties:属性集


o text:字符型,纯文本字符串;


o markdown:字符型,markdown 格式的字符串;


o id: 字符型,信息的编号;


o arguments:字符串数组,用于替代 message 中的参数;


o properties:属性集,通过 key,value 的方式扩充,参考定义组节点 definitions 下的 propertyBag 的定义;


  • anyOf: 至少 text 或 id 必须;其他属性可选;

  • 例子:



5. SARIF 报告的基本结构


5.1. 工具的定义(runs.tool.driver)


在扫描结果(runs)的定义中,tool 节点是必须的,tool 中 driver 是必须的,而 driver 中也只有 name 是必须的,也就是说除了工具的名字是必须的,其他的属性都是可选的。这也可以看出来,这个报告也可以做的非常的简单,只强制定义了一些非常必要的信息。


  • 运行结果组 runs 下的数组元素是参考定义组节点 definitions 下的 run 的定义;

  • run 属性中的必须节点 tool 的定义是参考定义组节点 definitions 下的 tool 的定义;

  • tool 属性中的必须节点 driver 的定义是参考定义组节点 definitions 下的 toolComponent 的定义;工具可以通过 tool.driver 完成工具的各种基本信息的定义;

  • 对与工具的其他扩展组件(例如各种插件),可以通过 tool.extensions 完成定义,extensions 是个数组类型,每个数组元素也是参考定义组节点 definitions 下的 toolComponent 的定义;

  • 通过 toolComponent,可以定义:


o 组件的基本信息:


§ 工具的名字(name),全名(fullName),版本(version),交付时间(releaseDateUtc);


§ 组件所属组织(organization),产品(product)和产品组(productSuite)信息;


§ 下载地址(downloadUri),组件的参考信息地址(informationUri);


o 组件的语言信息:


§ 使用语言(language);


§ 多语言支持(globalMessageStrings);


§ 本地化的信息版本(localizedDataSemanticVersion);


o 关联组件(associatedComponent);


o 组件的扩展信息通过属性包(properties)实现;


  • 举例:



5.2. 规则的定义(run.tool.driver.rules)


定义组节点 definitions 下的 toolComponent 中定义了 rules 节点。规则(rules)的定义是一个数组类型,每个规则的定义参考定义组节点 definitions 下的 reportingDescriptor 的定义,reportingDescriptor 定义中:


  • id 是必须的;

  • 名字(name),guid(guid),长、短描述(shortDescription,fullDescription);

  • 以前版本的相关信息(deprecatedIds,deprecatedGuids,deprecatedNames);

  • 规则的信息(messageStrings),通过参考定义组节点 definitions 下的 multiformatMessageString 实现多语言支持;

  • 规则的默认配置(defaultConfiguration);

  • 规则的帮助信息(helpUri,help), help 通过参考定义组节点 definitions 下的 multiformatMessageString 实现多语言支持;

  • 规则的扩展信息通过属性包(properties)实现;

  • 举例:



5.3. 扫描内容的定义(run.artifacts)


定义组节点 definitions 下的 run 的下面有一个 artifacts 节点,artifacts 是一个数组节点类型,每个数组元素参考定义组节点 definitions 下的 artifact 的定义。artifact 包括:


  • 描述(description);

  • 位置信息(location,parentIndex,offset);

  • 内容信息(contents,encoding,sourceLanguage,length);

  • 改动信息(hashes,lastModifiedTimeUtc);

  • 扩展信息(properties);


5.4. 扫描结果的定义(run.results)


定义组节点 definitions 下的 run 的下面有一个 results 节点,results 是一个数组节点类型,每个数组元素参考定义组节点 definitions 下的 result 的定义。result 包括:


  • result 节点下面只有 message 是必选项,以确保结果有信息输出;

  • 规则信息:


o ruleId:规则的编号;


o ruleIndex: 规则的索引编号;


o rule: rule 的定义参考定义组节点 definitions 下的 reportingDescriptor 的定义, 同规则的那部分;


  • 缺陷类型:


o kind: {“notApplicable”, “pass”, “fail”, “review”, “open”, “informational”};


o level: {“none”, “note”, “warning”, “error”};


o rank: -1.0 <= rank <= 100.0;


  • 缺陷位置:


o analysisTarget:参考定义组节点 definitions 下的 artifact 的定义;


o locations:是一个数组节点类型,每个数组元素参考定义组节点 definitions 下的 location 的定义。location 包括:


§ id: 在一个缺陷内 location 的唯一值;


§ physicalLocation: 参考定义组节点 definitions 下的 physicalLocation 的定义。 physicalLocation 包括:


§ address:通过地址域的相对或者绝对偏移量来表示问题位置;


§ artifactLocation:文件的方式表示缺陷的位置;


§ address 和 artifactLocation 是最少二选一的;


§ region: 指定文件的区域;有以下三种方式:


§ 通过代码行、列:startLine, startColumn, endLine, endColumn 来指定区域;


§ 通过字符偏移量:charOffset,charLength 来指定区域;


§ 通过字节偏移量:byteOffset, byteLength 来指定区域;可以用于二进制位置定位;


§ snippet:代码片段, 参考定义组节点 definitions 下的 artifactContent 定义;


o 缺陷标识:


§ guid: 缺陷的标识 GUID;


§ correlationGuid:根据缺陷特征生成的 GUID;


§ occurrenceCount:同样缺陷特征在本次扫描中出现的次数;


§ partialFingerprints: 部分缺陷特征;


§ fingerprints: 缺陷特征指纹;


o 缺陷追踪信息:


§ stacks:缺陷的栈信息一个数组节点类型,每个数组元素参考定义组节点 definitions 下的 stack 的定义。statck 包括:


§ frames:代表按调用顺序排列的,按相反时间顺序排列的一系列调用,这些调用构成了调用堆栈。frames 是 statck 中一个必须的节点,frames 一个数组节点类型,每个数组元素参考定义组节点 definitions 下的 stackFrame 的定义。stackFrame 包括:


§ location: 位置信息,参考定义组节点 definitions 下的 location 的定义;


§ module: 包含此堆栈框架代码的模块的名称;


§ threadId:堆栈框架的线程编号;


§ parameters:函数调用的参数信息, 是一个数组节点,每个数组元素表示一个参数;


  • 举例:



5.5. 小结


SARIF 通过下面的结构,构成了一个扫描工具扫描结果的基本框架。



6. 总结


  • 本篇的前半部分介绍了 SARIF 的需求的提出,以及成为结构化信息标准促进组织(OASIS)的 SARIF 技术委员会的一个标准;

  • 后半部分介绍了 SARIF 的基本概念,以及扫描结果的基本框架;

  • 下篇将介绍对于复杂的静态分析工具报告需求的实现。


7. 参考



本文分享自华为云社区《DevSecOps 工具与平台交互的桥梁 -- SARIF 入门》,原文作者:Uncle_Tom 。


点击关注,第一时间了解华为云新鲜技术~


发布于: 2021 年 03 月 02 日阅读数: 92
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
SARIF:DevSecOps工具与平台交互的桥梁