CWE 视图层级关系解析:节点关系查询

作者: 小麦

更新时间:2022-03-26 14:30:22

621 阅读

本文分享自华为云社区《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 节点的定义和节点之间的关系表做了描述。两个表的定义如下:

-- CWE 节点的定义
DROP INDEX IF EXISTS "cwe_node_ind";
DROP TABLE IF EXISTS "cwe_node";
CREATE TABLE "cwe_node" (
    "cweId"    INTEGER NOT NULL UNIQUE,
    "nodeType"    TEXT NOT NULL,
    "nameEn"    TEXT NOT NULL,
    "nameCn"    TEXT DEFAULT '',
    "status"    TEXT DEFAULT '',
    "filter"    TEXT DEFAULT '',
    "structure"    TEXT DEFAULT '',
    "description"    TEXT DEFAULT '',
    "extendedDscription"    TEXT DEFAULT '',  
    "likelihoodOfExp"    TEXT DEFAULT '',
    "version"    TEXT NOT NULL,
    PRIMARY KEY("cweId")
);
CREATE INDEX "cwe_node_ind" ON "cwe_node" (
    "cweId",
    "nodeType"
);

-- CWE节点关系
DROP INDEX IF EXISTS "cwe_relation_ind";
DROP TABLE IF EXISTS "cwe_relation";
CREATE TABLE "cwe_relation" (
    "cwe_relation_id"    INTEGER NOT NULL UNIQUE,
    "cweId"    INTEGER NOT NULL,
    "nodeType"    TEXT NOT NULL,  
    "viewId"    INTEGER NOT NULL,
    "relation"    TEXT NOT NULL,
    "targetCweId"    INTEGER NOT NULL,
    "ordinal"    TEXT DEFAULT '',
    "version"    TEXT NOT NULL,
    PRIMARY KEY("cwe_relation_id" AUTOINCREMENT)
);
CREATE INDEX  `cwe_relation_ind` on `cwe_relation` (`viewid`,`cweId`,`targetCweId`,`relation`);

 

1.3. 将 xml 的信息存储到数据库

  • 解析 CWE xml 文件将 xml 种的信息存入 Sqlite 数据库,具体步骤略过(这个会代码的不难实现);

  • 采用 DB Browser for SQLite 作为查询界面;

  • 为了便于查询,我们将节点关系为"ChildOf"的类型都换成"Has_Member"。

1.4. 以 CWE-1000 研究者视图为例

我们仍以 CWE-1000 研究者视图为例:

select * from cwe_relation where viewId = 1000 and relation = 'Has_Member' order by cwe_relation_id

查询结果如下:共得到 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

WITH RECURSIVE tc(level, targetCweId,target) 
as (select 0 level,targetCweId, targetCweId target from cwe_relation where viewid=1000 and cweid = 1000 and relation='Has_Member' 
    UNION
    select tc.level+1 level,r.targetCweId, tc.target||"->"||r.targetCweId target from cwe_relation r,tc where r.viewid=1000 and r.relation='Has_Member' and r.cweid = tc.targetCweId
)
SELECT * FROM tc where tc.targetCweId = 120
  • 查询结果

从查询结果可以看到 CWE-120 的父节点依次为:CWE-119,CWE-118, CWE-664。这个结果与实际的页面展示相同。

  • 注意:由于 CWE 在定义时,CWE 之间不完全是正交关系,所以存在一个 CWE 在不同分支的场景。在具体使用时需要用户对实际缺陷的上下文场景做分析后确认。例如:

CWE-425 直接请求(强制性浏览)就存在这种场景,如下面的查询结果。

2.4. CWE 的子节点

查找某个 CWE 下包含的 CWE。这个场景可以转化成查找某个节点的子节点来实现。

例如查找 CWE-119 的下所有的节点

  • 参考 SQL

WITH RECURSIVE tc(level, targetCweId,target) 
as (select 0 level,targetCweId, targetCweId target from cwe_relation where viewid=1000 and cweid = 119 and relation='Has_Member' 
    UNION
    select tc.level+1 level,r.targetCweId, tc.target||"->"||r.targetCweId target from cwe_relation r,tc where r.viewid=1000 and r.relation='Has_Member' and r.cweid = tc.targetCweId
)
SELECT * FROM tc
  • 查询结果

 

3. CWE 数据库中得到的其他信息

我们将 CWE 的信息转换到数据库后,还可以快速得到很多有用的统计信息。

3.1. CWE 关联的业界规范

CWE 的外部视图中,很多是业界规范对 CWE 的映射关系。我们可以通过这些规范对 CWE 的覆盖情况来分析这些规范的侧重点和重合情况,从而在安全防御的措施制定时,根据自己的实际情况,进行全面的防御。

例如:查看 CWE 视图中关联的业界规范对 CWE 的引用情况。

  • 参考 SQL 

select taxonomyName,count(*) from cwe_taxonomy_mappings m group by taxonomyName
  • 查询结果

3.2. CWE 的消减措施

查看 CWE 所标识的安全消减措施,用于某些安全问题的安全防御。

例如查看 CISQ 规范关联 CWE 的风险消减措施。

  • 参考 SQL

select cweId,nodetype, 
sum(case when phase='Requirements' then 1 else 0 end) as 'Requirements',
sum(case when phase='Architecture and Design' then 1 else 0 end) as 'Architecture and Design',
sum(case when phase='Documentation' then 1 else 0 end) as 'Documentation',
sum(case when phase='Build and Compilation' then 1 else 0 end) as 'Build and Compilation', 
sum(case when phase='Implementation' then 1 else 0 end) as 'Implementation',
sum(case when phase='Testing' then 1 else 0 end) as 'Testing',
sum(case when phase='System Configuration' then 1 else 0 end) as 'System Configuration',
sum(case when phase='Operation' then 1 else 0 end) as 'Operation'
from (
    select distinct a.cweid, a.nodeType,b.phase from (
    select c.cweid, c.nodeType from cwe_relation r, cwe_node c where r.viewid=1340 and r.relation = 'Has_Member' and c.cweId= r.targetCweId ) a left join 
    (select * from cwe_potential_mitigation m) b on a.cweid=b.cweId
)a group by cweId,nodetype
  • 查询结果(部分):

4. 参考:

  • CWE: https://cwe.mitre.org/

  • SQLite with 子句: https://www.SQLite.net.cn/lang_with.html

5. 小结

  • 设计了 CWE Xml 文件中存储的主要信息对应 SQLite 的数据库表;

  • 简单介绍了数据库中公用表表达式(CTE)用于树或图的递归查询使用方法;

  • 借助公用表表达式实现 CWE 在视图中所归属的分析信息(父节点)和所包含的 CWE(子节点)的信息;

  • 依据 CWE 数据库实现 CWE 收录的业界规范的关联关系的分析;

  • 依据 CWE 数据库实现 CISQ 关联的 CWE 的弱点消减措施;

  • 依据以上的分析,可以更好的帮助我们完成软件安全的全面防御。

 

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

版权声明:本文著作权归作者【小麦 】所有,不代表本网站立场。

侵权请联系:root_email@163.com

相关推荐