Notes | A large-Scale Empirical Study of Security Patches
作者:互联网
A large-Scale Empirical Study of Security Patches
- Introduction
- Data Resource
- Related work
- Data collection methodology
- Data characterization
- Analysis results
- Discussion
- Conclusion
此文为笔者简单的论文笔记,仅供浏览学习,请不要置以其余任何用途
Introduction
- 对安全补丁进行大规模的实证研究,调查了影响682个开源软件项目的3000多个漏洞的4000多个漏洞修复
- 数据集来自NVD的漏洞条目、从相关外部引用、受影响的软件库、相关的安全修复程序中提取的信息
- 对补丁开发生命周期进行深入分析,包括漏洞生命周期、安全修复的时效性,以及开发人员生成安全可靠的安全补丁的(可靠)程度
- security patches 与non-security patches的对比特征
- 不同类型补丁的复杂性及其对code base的影响
Data Resource
-
数据来源:NVD、外部链接、受影响的软件库、相关的安全修复程序
-
调查对象: 682个开源项目 —— 3000+ bugs —— 4000+ bug fixes
-
调查内容:
a. 漏洞对代码库的影响时长
b. 补丁开发的时效性
c. 所开发的修复程序的安全可靠程度(the degree to which developers produce safe and reliable fixes)
d. security fixes v.s. non-security fixes
Why NVD?
(1) public, free, and easily accessible in XML format, allowing for reproducibility and follow-on studies
(2) expansive, as the NVD aims to catalog all publicly disclosed vulnerabilities across numerous software packages
(3) manually vetted and curated, which in theory provides more accurate data
(4) detailed, containing extensive documentation of vulnerabilities (notably external references).
About NVD: CVE process
1. 发现漏洞,请求CVE ID(此时漏洞的相关信息尚未公开)
2. 公开漏洞信息,CVE ID与其详细信息加入CVE list
3. NVD进一步调查,增加相关信息:链接到外部应用,列举受影响的软件,CWE分类,CVSS评估严重性程度
Why open-source projects?
Related work
- 目前已有关于漏洞生命周期的工作以及关注补丁特性的工作大多是在较小的规模上进行的,且未区分不同类型的漏
- 作者广泛探索了补丁开发动态的新方面,将从漏洞数据库收集到的信息与从软件源代码中显露出来的信息相结合
- 通过研究大规模超过650个不同的开源项目来得出结论
- 试图梳理出security patch 和 non-security patch之间的区别,此项之前没有进行过
Data collection methodology
- Finding pubilc vulnerabities
- Identifying software repositories & security patches
- Identifying non-security bug fixes
- Processing commits
- Estimating vulnerability public disclosure dates
另,贯穿以上全部过程的验证方法:抽取大约100个样本手工检查
1. Finding Public vulnerabilities
使用 2016/12/25 NVD XML dataset snapshot —— 80,741 CVE vulnerabilities 作为数据集。
数据收集方法:
- 从 NVD 中 有链接到 Git 提交链接的 CVE 中提取漏洞特征
- 爬取其他 references ,并获取页面的公布日期来评估公开披露日期
- 爬取 Git 提交链接 来识别并克隆Git的源代码库,并获取 security fixes(collected security fixes using the commit hashes in the links)
- 用 Git 仓库获取 non-security fixes
2. Identifying software repositories & security patches
- 通过 CVE 中链接到修复特定存储库提交的 web URL 获取安全补丁、访问源代码库。
- 重点关注链接到 Git 的URL
Why Git URL?
- Git是最常用的开源软件版本控制系统,也在CVE 的外部链接中最常见
- 作者统计URL数据:5700+ “git”子串(不含“digit”子串)、1144个“svn”子串、613个“cvs”子串、347个“hg”或“mercurial” ⇒ Git 相比其余流行的版本控制系统在URL中被包含的更多
- 进一步验证 URL 与 Git相关:手工随机抽样100个URL,发现只有 2 个不是Git URL
怎么找到Git仓库及security patches?
- 对包含常见git应用(cgit\Github\GitWeb\Gitlab)的URL进行逆向,其中95%的URL都包含“git”子串
- 对链接到git界面的但不包含“git”子串的128个URL进行逆向
(故而由上述两种情况,认为已经识别到了大多数的Git URLs) - 对于上述80%的URL(链接到特定提交的URL),爬取web界面摘要/主页并获取Git clone URLs(如果已列出)
- 删除重复镜像版本⇒ 保证仓库不同
- 验证:人工随机抽取100个提交,全部实现了对相应漏洞的修复
4,080 commits across 682 unique Git repositories, tied to 3,094 CVEs in total
3. Identifying Non-Security Bug Fixes
需要对比security patches & non-security patches ⇒ 大规模实现 ⇒ 实现自动识别 non-security patches ⇒ 逻辑回归 使用Git提交信息实现n-grams模型,手动选取提交进行训练分类器,使用分类器随机选择每个存储库最多10个提交来收集bug fixes数据集。
4. Processing Commits
对于收集到的每个提交,提取该commit提交前后所受影响的文件的历史版本:
- 提交前后的版本除该patch外无其它任何区别
- 只考虑对功能性源代码的更改,而不考虑对文档、注释的更改
⇒ 需要过滤非源代码文件、删除注释
怎样过滤非源代码文件、删除注释?
- 将常见的30个文件扩展名映射到对应的语言语法,并将文件扩展名作为文件类型指示器
- 在对应语法下过滤注释、尾随空格,过滤非源代码文件
- 验证:随机抽取100个带有前30个文件扩展名的文件,且文件扩展名全部正确对应相应类型
为什么仅选用前30个文件扩展名而非更少或更多的文件扩展?
- 30个文件扩展已经包含了95%的提交文件
- 再多的话无意义,需要额外的清理且性价比不高
5. Estimating Vulnerability Public Disclosure Dates
NVD中的 CVE 发布日期为漏洞在数据库中发布的日期,而实际发布的日期可能更早 ⇒ 需要获取更准确的公开披露时间
怎样获取更准确的公开披露时间?分析CVE references:通常包含与漏洞有关的发布信息,可能包含公开日期
- 确定 top 20 可能包含公开日期的常用站点
- 对上述20个中可用的16个网站一一构建对应的parser,提取指定页面(比如漏洞数据库条目、漏洞报告等)的发布信息
- 验证:随机抽取100个页面,发现所提取日期均正确
13,600 active external references in total,从94%的页面中均提取出公开日期(at least one date extracted from an external reference for 93% of CVEs, with multiple dates extracted for 73% of CVEs)
为什么仅确定20个网站而非更多或更少?
- 再少的话不能确保能够提取出公开日期
- 每个站点都需要一个parser,再多的话无意义
结果:8% 的漏洞没有提取到更早的发布时间,大多数集中在27天左右,最长的有几年的差异。
limitations
Data characterization
- Vulnerability publication timeline
- Affected software products
- Vulnerability severity
- Vulnerability categories
- Vulnerability distribution over repositories
- Repository size
1. Vulnerability publication timeline
对于所收集CVE数据集的漏洞公开时间绘图如下:
2. Affected software products
对NVD中列出的受漏洞影响的产品进行统计,列举受影响最多的产品数量:
- 受影响的产品数量超过漏洞数量,一个漏洞可能影响其对应的多个产品
- 最受影响的是Linux发行版
⇒ 还需要对存储库进行分析
3. Vulnerability severity
CVSS标准划分严重性:
0-3.9低严重性,4.0-7.9被标记为中等,8.0-10.0被认为是高度严重。所收集的跨越所有严重性分数的漏洞。
4. Vulnerability categories
CWE标准进行分类,结果如下:
5. Vulnerability distribution over repositories
所选择的CVE漏洞不均匀地分布在 682 个项目上 ⇒ 需考虑按存储库划分
6. Repository size
通过文件数量或文件中的行数描述存储库大小,包括原始存储库与清理后的存储库:
Analysis results
已收集:
- 不同软件项目中的漏洞
- 源代码存储库
- security fixes & non-security fixes
1. Patch Development Life Cycle
Vulnerability Life Spans in Code Bases
漏洞代码库生存周期(the vulnerability’s code base life span):从漏洞第一次被发现到被修正的时间,反映了攻击者的机会窗口
⇒难以自动确定⇒通过确定受安全修复影响的源代码上次修改的时间来近似下限:
- 对清理版本的security commit进行分析,对提交删除或修改的所有行,使用 Git “blame”功能检索上次更新时间
- 该上次更新时间到提交时间之间的时间段即为所求下限
How long do vulnerabilities live in code bases?
方法:
- 对于有多次提交的CVE,使用最短的生命周期
- 按仓库分类,并为每一仓库中的最小、中间值、最大生命周期的分布绘图
结果:
- 代码库中漏洞存在的时长有不同的范围
- 50%的生命周期超过438天,1/4的存储库中位数超过3年,全部CVE中的1/3超过3年,最长的是21年,6.5%的生命周期低于10天
- 手动评估Ubuntu内核漏洞,漏洞的代码库平均生命周期约为5年;手动评估openBSD发现,平均生命周期超过2.6年
- 漏洞存在多年,且在多种类型的软件中存在
- typical life span estimates are lower than these previous ones, which may be due to our consideration of software projects beyond Linux variants, or our conservative approximation method
Do more severe vulnerabilities have shorter lives?
方法:
将CVSS评分与生命周期联系起来,计算Spearman相关系数 ρ
结果:
- ρ=−0.062
- 严重性与生命周期无本质联系(包括Ubuntu)
Do different types of vulnerabilities have varying life spans?
方法:
总结了CWE分类中不同类型的cve的漏洞寿命
结果:
top 10 :
观察到:
- 基于不同软件弱点类别,漏洞生命周期变化很大
- 与软件逻辑和内存管理中的错误相比,面向Web的漏洞(如SQL注入和跨站点脚本)的生命周期明显更短
- 相比之下,竞争条件、数字错误和缓冲区溢出在两到三倍的时间内仍未被发现
结论:
不同漏洞类型的生命周期取决于:漏洞本身与受影响的软件类型
Security Fix Timeliness
方法:
- 比较CVE中的补丁提交日期与漏洞公开披露日期
- 描述公开披露日期与补丁日期之间时间间隔的CDF:
- 将CVE按软件库分类,绘制跨软件库的分布。所有cve的聚集分布很大程度上与每个存储库中位数的分布相匹配,尽管每个存储库中位数表现出对较小绝对值的轻微倾斜。
How frequently are vulnerabilities unpatched when disclosed?
由公开披露日期与补丁日期之间时间间隔的CDF可得如下结论:
- 21.2%的漏洞,公开披露但尚未修复为正的时差值
- 超过四分之一(26.4%)的未修补的安全问题在披露后30天仍未得到解决
- 大约30%的Windows漏洞在公开时没有修补,有些漏洞已经存在了180多天
How frequently are vulnerabilities fixed by disclosure time?
由公开披露日期与补丁日期之间时间间隔的CDF可得如下结论:
- 对于78.8%的漏洞,security fixes在公开披露之前被提交
- 上条表明,大多数的漏洞都是内部发现的或者是开发人员通过私人渠道得知
Are vulnerability patches publicly visible long before disclosure?
由公开披露日期与补丁日期之间时间间隔的CDF可得如下结论:
- 70%的补丁在被公开之前提交
- 人工检查发现,由于不同项目的不同发布周期(以及每个项目开发时间表中的变化),补丁在公开之前提交的时间间隔范围不同
- 突出开源社区的一个方面:项目将安全补丁滚动到用户必须直接下载和安装的定期版本发布中,或者将更新拉到下游,由软件发布平台合并;之后发布关于发行版或更新的公告,以及所包含的安全修复程序。
- 超过50%的cve在公开之前一周多打了补丁,这给了攻击者足够的时间开发和部署漏洞
- 针对特定软件项目的攻击者可以跟踪安全补丁和它们解决的漏洞。虽然该漏洞在项目存储库中已被修复,但在公开披露和升级发布之前,可能得不到广泛的修复。
Are higher severity vulnerabilities patched quicker?
方法:
将CVE按严重程度划分 (low, medium, and high)
结果:
- 严重程度显著影响修复时间
- 88.1%的高严重程度cve在公开之前被修补,78.2%的中等严重程度在公开之前被修补,58.8%的低严重程度在公开之前被修补
- 项目开发人员会优先考虑高严重程度的漏洞
- 对于公开披露时已修复的漏洞,严重程度与补丁速度无明显关系
- 对于公开披露时未修复的漏洞,高严重程度的漏洞打补丁更快
Patch Reliability
方法:为同一个CVE识别多个提交,并对原因进行分类
How frequently are security patches broken (e.g., incomplete or regressive)?
方法:
- 使用Git日志获取一个CVE的后续提交,搜索存储库的Git日志,查找包含CVE ID或提交散列的7个字符前缀的提交消息
- 考虑到开发人员可能将一个提交分多次提交,将提交分类为:分段修复与无问题修复
- 随机抽样50个并人工调查
- 从随机抽样的50个外推到全部的440个
结论:
- 随机抽样50个并人工调查中,发现 52% incomplete patches,34% regressive patches,8% both
- 从随机抽样的50个外推到全部的440个,估计大约7% incomplete,5% regressive
- 补丁安全问题不可忽视,且数据集中最近的补丁可能还没有足够的时间来证明最终需要多次提交,故而结果可能被低估
- security patches 、 non-security patches 都面临不成功的可能
How long do problematic patches remain unresolved?
结论:
- 修正原始问题补丁所需的附加补丁数的中位数仅为一个commit
- 典型的 incomplete patches 需要半年的时间来修复
- 问题严重到需要恢复的补丁通常需要一个月的时间来修复
2. Patch Characteristics
对比 security fixes &non-security fixes
Non-Source Code Changes
方法:
对比commit data及其清理源代码注释与非源代码文件后的版本
结论:
- 6.1% non-security patches 涉及错误的配置、带有破坏的依赖关系或设置的构建脚本、不正确的文档和其他非源代码更改
- 1.3% security patches没有涉及源代码更改
- 某些情况下,提交将补丁文件添加到存储库中,而非应用到代码库中
- 许多CVE漏洞并不存在于源代码中
后续分析仅限修改源代码的提交。
Patch Complexity
How complex are security patches compared to other non-security bug fixes?
选用代码行(LOC)。
Are security patches smaller than non-security bug fixes?
方法:
绘制了所有安全和非安全补丁、每个存储库中安全修复的全部LOC的CDFs
结论:
- 安全提交的中位数差异涉及7个LOC,而非安全提交涉及16个LOC
- 大约20%的非安全补丁有超过100行更改的差异,而只有6%的安全提交发生了这种情况
- 总体上安全提交更小
Do security patches make fewer “logical” changes than non- security bug fixes?
方法:
- 将提交所更改的连续行分组为单个“逻辑”更改,更新的几行代码被视为单个逻辑更新,删除的代码块被视为单个逻辑删除
- 描述每个提交的逻辑操作数量的CDFs
结论:
- security commits明显包含更少的更改
- 近78%的security commits没有删除任何代码,66%的 non-security commits 没有删除任何代码
- Between 30% to 40% of all commits also did not add any code, indicating the majority of logical changes were updates
Do security patches change code base sizes less than non- security bug fixes?
结论:
- 18%的非安全bug修复减少了code base大小,而安全补丁减少了9%
- 对于所有提交,大约有四分之一的提交没有导致项目LOC的净变化(一般在只更新行时)
- security patches的更改相对于 non-security patches 更少
Commit Locality
考虑两个指标:受影响的文件数量、受影响的函数数量
Do security patches affect fewer source code files than non- security bug fixes?
方法:
描述补丁涉及的文件数量的CDFs
结论:
- 明显安全补丁修改的文件数量更少
- Only 4% of security fixes created new files (vs. 13% of non-security bug fixes), and only 0.5% of security patches deleted a file (vs. 4% of non-security bug fixes)
Do security patches affect fewer functions than non- security bug fixes?
方法:
- 使用ctags实用程序识别源代码中函数的开始,根据相应编程语言的规则确定每个函数的结束
- 将commit差异中的行更改映射到函数中
- 绘制补丁影响的函数数量的CDFs
结论:
- 5%的非安全性bug修复影响函数边界之外的全局代码,而安全性补丁只有1%
- 安全补丁明显(p≈0)在函数之间的本地化程度更高:59%的安全更改位于单个函数中,相比之下,其余为42%。
总之,安全补丁在其更改中的本地化程度更高。
Discussion
- 开源项目需要更广泛、更有效的代码测试和审计过程
- 需要开发更有效的测试过程,尤其注意可用性
- 由于软件发布周期的原因,当安全问题被私下报告并修复时,补丁不会立即发布
Conclusion
- security patches对code bases影响更小,更本地化
- 安全问题在代码库中存在多年后才会被修复
- 7% incomplete patches,5% recessive patches
标签:non,Scale,Patches,Notes,fixes,漏洞,提交,security,patches 来源: https://blog.csdn.net/weixin_43894553/article/details/112801034