CWE 视图层级关系解析:节点关系查询
摘要:本文重点关注 CWE 之间的关系。
本文分享自华为云社区《CWE视图层级关系的解析 之 CWE节点关系的查询》,作者: Uncle_Tom。
1. CWE 转换成 SQLite 表
依据《CWE视图层级关系的解析 之 CWE节点的存储和定义》 中对 CWE 在 xml 文件中存储的结构和定义的描述。我们将 CWE 存储在 xml 文件中的信息转换到数据库中。数据库采用了轻量级的 SQLite。
1.1. 存储 CWE 信息的数据库表
根据 CWE 的结构定义,提取了我们需要的主要信息,进行数据库表的设计。CWE 数据库存储表的定义如下图:
CWE 数据库表的含义:
cwe_node: CWE 节点的主要信息;
cwe_relation: CWE 关联关系;
cwe_applicable_platforms: CWE 适用的应用平台
cwe_detection_method: CWE 的检测方式
cwe_taxonomy_mappings: CWE 与业界规范的关系;
cwe_demostrative_example: CWE 的样例代码;
cwe_observed_example: CWE 观察到的示例;
cwe_potential_mitigation: CWE 的消减措施;
cwe_attack_patterns: CWE 的攻击模式;
cwe_common_consequence: CWE 造成的危害。
1.2. CWE 节点和节点关系表的定义
本文重点关注 CWE 之间的关系,所以在这里只对 CWE 节点的定义和节点之间的关系表做了描述。两个表的定义如下:
1.3. 将 xml 的信息存储到数据库
解析 CWE xml 文件将 xml 种的信息存入 Sqlite 数据库,具体步骤略过(这个会代码的不难实现);
采用 DB Browser for SQLite 作为查询界面;
为了便于查询,我们将节点关系为"ChildOf"的类型都换成"Has_Member"。
1.4. 以 CWE-1000 研究者视图为例
我们仍以 CWE-1000 研究者视图为例:
查询结果如下:共得到 1077 条记录。
2. CWE 关系的查询
CWE 之间的关系是以父、子节点的方式存储在表 cwe_relation 中的。SQLite 提供了递归的查询方式来遍历树形结构。我们可以利用 SQLite 的这个特性来完成 CWE 间关系的查询。
我们先来介绍下这个特性的关键技术公用表表达式(Common Table Expression)。
2.1. 公用表表达式(Common Table Expression)
1999 年,公用表表达式(Common Table Expression),简称 CTE 成为 ANSI SQL 99 标准的一部分。
CTE 可以看做是一个临时的结果集。使用公用表达式 CTE 可以让语句更加清晰简练。
CTE 带来的好处:
查询语句的可读性更好;
在一个查询中,可以被引用多次;
能够连接多个 CTE;
能够创建递归查询;
能够提高 SQL 执行性能;
能够有效地替代视图
CTE 和临时表、表变量的比较。
临时表:需要在临时数据库 TempDB 中通过 I/O 操作来创建表结构,一旦用户推出环境则自动被删除;
表变量:在内存中以表结构的形式存在,其定义与变量一致,其使用与表类似,不需要产生 I/O;
公用表表达式:定义在内存中保存的临时存储结果集对象,不产生 I/O,不需要按照表变量这样定义,使用方法和表类似。可以自己引用,也可以再查询中被多次引用。
公用表表达式的作用类似于仅在单个 SQL 语句期间存在的临时视图。按照是否递归,可以将公用表表达式分为递归公用表表达式和非递归公用表表达式:
普通: 普通的公共表表达式通过将主查询中的子查询分解出来,有助于使查询更易于理解;
递归公用表表达式: 提供了对树和图进行分层或递归查询的功能。
由于 CTE 的众多好处,特别是对树和图的处理能力的增强。各种数据库纷纷实现 CTE 功能:
2005 年 SQL Server2005 版本的引入 CTE;
2009 年 PostgreSQL 8.4 版本的引入 CTE;
2013 年 Oracle 12.1 版本的引入 CTE;
2014 年 SQLite 3.8.3 版本的引入 CTE;
2017 年 MySQL 在 8.0.1 版本被引入 CTE;
2.2. SQLite 中的递归查询
SQLite With 的语法
递归公用表表达式可用于编写遍历树或图的查询。递归公用表表达式具有与普通公用表表达式相同的基本语法,但具有以下附加属性:
"select-stmt"必须是复合 select。也就是说,CTE 主体必须是两个或多个单独的 SELECT 语句,这些语句由复合运算符(如 UNION,UNION ALL,INTERSECT 或 EXCEPT)分隔。
组成该复合的单个 SELECT 语句中的一个或多个必须是“递归的”。如果 SELECT 语句的 FROM 子句恰好包含对 CTE 表(在 AS 子句的左侧命名的表)的一个引用,则该 SELECT 语句是递归的。
复合中的一个或多个 SELECT 语句必须是非递归的。
所有非递归 SELECT 语句必须出现在任何递归 SELECT 语句之前。
递归 SELECT 语句必须与非递归 SELECT 语句分开,并且必须由 UNION 或 UNION ALL 运算符彼此分开。如果有两个或多个递归 SELECT 语句,则必须使用相同的运算符将它们彼此分开,该运算符将第一个递归 * SELECT 与最后一个非递归 SELECT 语句分开。
递归 SELECT 语句可能不使用 聚合函数或窗口函数。
递归公用表表达式必须类似于以下内容:
计算递归表内容的基本算法如下:运行初始选择并将结果添加到队列中。当队列不为空时:从队列中提取一行。将那一行插入递归表假设刚提取的单行是递归表中的唯一行,然后运行递归选择,将所有结果添加到队列中。
2.3. CWE 在视图中的位置
查找一个 CWE 在试图中的位置。可以转化成查找一个节点的父节点。
这里通过 level 字段来反映出所在节点的从最高层到当前节点的层级;
通过符号"->"来反映节点的链路关系。
例如:需要查找 CWE-120 在研究者视图 CWE-1000 中的位置。
CWE-120 实际的位置
参考 SQL
查询结果
从查询结果可以看到 CWE-120 的父节点依次为:CWE-119,CWE-118, CWE-664。这个结果与实际的页面展示相同。
注意:由于 CWE 在定义时,CWE 之间不完全是正交关系,所以存在一个 CWE 在不同分支的场景。在具体使用时需要用户对实际缺陷的上下文场景做分析后确认。例如:
CWE-425 直接请求(强制性浏览)就存在这种场景,如下面的查询结果。
2.4. CWE 的子节点
查找某个 CWE 下包含的 CWE。这个场景可以转化成查找某个节点的子节点来实现。
例如查找 CWE-119 的下所有的节点
参考 SQL
查询结果
3. CWE 数据库中得到的其他信息
我们将 CWE 的信息转换到数据库后,还可以快速得到很多有用的统计信息。
3.1. CWE 关联的业界规范
CWE 的外部视图中,很多是业界规范对 CWE 的映射关系。我们可以通过这些规范对 CWE 的覆盖情况来分析这些规范的侧重点和重合情况,从而在安全防御的措施制定时,根据自己的实际情况,进行全面的防御。
例如:查看 CWE 视图中关联的业界规范对 CWE 的引用情况。
参考 SQL
查询结果
3.2. CWE 的消减措施
查看 CWE 所标识的安全消减措施,用于某些安全问题的安全防御。
例如查看 CISQ 规范关联 CWE 的风险消减措施。
参考 SQL
查询结果(部分):
4. 参考:
SQLite with 子句: https://www.SQLite.net.cn/lang_with.html
5. 小结
设计了 CWE Xml 文件中存储的主要信息对应 SQLite 的数据库表;
简单介绍了数据库中公用表表达式(CTE)用于树或图的递归查询使用方法;
借助公用表表达式实现 CWE 在视图中所归属的分析信息(父节点)和所包含的 CWE(子节点)的信息;
依据 CWE 数据库实现 CWE 收录的业界规范的关联关系的分析;
依据 CWE 数据库实现 CISQ 关联的 CWE 的弱点消减措施;
依据以上的分析,可以更好的帮助我们完成软件安全的全面防御。
版权声明: 本文为 InfoQ 作者【华为云开发者社区】的原创文章。
原文链接:【http://xie.infoq.cn/article/e1f905820226e1abd535bcd40】。文章转载请联系作者。
评论