2024年11月19日, MITRE发布了2024 CWE TOP25最危险软件弱点榜单[1](后续简称“TOP25”)。由于推出时间不久,网络上相关介绍的文章不多,且大都存在概念不清,意义不明确,应对手段缺失等问题。本文拟在对“TOP25”做出综述的同时:明确相关的基础概念,阐述它对于网络安全行业各类人群的价值,分析其发展趋势,最后重点说明对于软件开发者而言,应该如何应对“TOP25”中的软件弱点。
01
基础概念
基础概念1
MITRE是啥组织?
MITRE始于1958年,由美国空军赞助,是一家非营利性公司,旨在为政府机构提供军用和民用系统工程方面的客观顾问。MITRE公司提出的CVE,CWE是当今网络安全领域的标杆。
部分中文网站上介绍该公司前身是麻省理工学院的林肯实验室,一些介绍“TOP25”的文章甚至直接说该榜单是麻省理工发布的,但在MITRE公司官网[2]上并没有相关介绍,所以直接说MITRE公司就是麻省理工是不恰当的。
基础概念2
CWE和CVE有啥区别?
CVE[3]英文全称Common Vulnerabilities & Exposures,代表“常见漏洞和暴露”,它指的是具体产品或系统中漏洞的特定实例。例如,Microsoft Outlook 权限提升漏洞为 CVE-2023-23397,该漏洞在2023年3月14日由CERT-UA组织向微软上报,据称该漏洞曾经被APT28组织在2022年4月中旬和12月的攻击活动中使用。
CWE[4]英文全称Common Weakness Enumeration,是“常见弱点枚举”,它指的是软件弱点的类型,而不是具体某款产品或系统中可以被攻破的软件漏洞的实例。通俗点讲CWE就是具体软件漏洞的汇总分类,而这个“TOP25”就是分析了各种软件产品和系统的漏洞后汇总出来最常见的几类软件的弱点类型。
基础概念3
2024 TOP25是如何统计出来的?
MITRE TOP25团队首先采集2023-6-1至2024-6-1 期间发布的所有CVE记录;然后通过关键字匹配、邮件确认等方式将所有CVE做了CWE的映射归类;之后结合了频率(CVE归类到CWE上的次数)和每个CVE的平均严重程度(通用漏洞评分系统CVSS基本分数)对所有900多个CWE类型进行了“危险分数”打分;最后根据“危险分数”排序,得出的“TOP25”。
02
“TOP25”对于
网络安全行业各类人群的价值
MITRE TOP25团队共采样了31,770条CVE记录,有超过60%的CVE漏洞映射关联到了这些TOP25的CWE分类。榜单样本基数巨大,评价体系相对客观,“TOP25”已经是业界具有极大影响力的榜单。
软件开发人员
通过参考“TOP25”中的示例和潜在缓解措施,可以更好地了解特定弱点的性质,并更好地准备缓解和补救措施。通过遵循“TOP25”的补救规范,开发人员能够在产品生命周期更早的阶段预防漏洞的产生,软件测试人员能够在测试策略和测试设计阶段就关注“TOP25”弱点针对性构建测试用例,显著减少软件中出现的漏洞数量,从而提升软件产品的质量,进而帮助企业节省掉更多在漏洞解决方面的经费投入。
产品使用者
公司企业等产品使用者,在购买软件产品满足自己业务需求的同时,往往还需要应对企业内部、行业内部以至于国内、国际层面的安全审查。在面临审查的时候产品使用者可以利用“TOP25”来审查产品供应商,利用产品供应商提供的“TOP25”的消除声明来对外证实自己满足各方面的安全要求。同时,产品使用者也可以使用“TOP25”中提供的测试手段来核查产品提供商的声明是否存在问题。“TOP25”为企业和供应商提供了缓解和预防软件漏洞的优先注意事项。
公共价值:统一语言
在当今的网络安全领域,当人们讨论如何消除或缓解软件架构、设计、代码和实施中的安全漏洞时,CWE是大家用于对齐概念的统一语言。人们将CWE作为漏洞识别、缓解和预防工作的通用标准。人们在讨论网络安全的弱点分类的时候,比如讨论如何消除项目中的“跨站脚本”问题,通过描述其中编号CWE-79 跨站脚本,就能很清晰地知道彼此之间讲的弱点是什么,需要如何实施对弱点的消除措施以及如何测试和检验项目中是否包含此弱点。而“TOP25”就是CWE中的重中之重,指导人们将投资、关注、精力更多地这些重点之上。
03
“TOP25”体现的软件弱点发展趋势
排名 | 编 号 | 描 述 | 排名变更 |
1 | CWE-79 | 网页生成期间输入的处理不当(“跨站脚本”) | 1 |
2 | CWE-787 | 越界写入 | -1 |
3 | CWE-89 | SQL命令中使用的特殊元素的处理不当(“SQL注入”) | 0 |
4 | CWE-352 | 跨站点请求伪造(CSRF) | 5 |
5 | CWE-22 | 对受限目录的路径名限制不当(“路径遍历”) | 3 |
6 | CWE-125 | 越界读取 | 1 |
7 | CWE-78 | 操作系统命令中使用的特殊元素的中和不当(“操作系统命令注入”) | -2 |
8 | CWE-416 | 内存释放后使用 | -4 |
9 | CWE-862 | 缺少授权 | 2 |
10 | CWE-434 | 无限制上传危险类型的文件 | 0 |
11 | CWE-94 | 代码生成控制不当(“代码注入”) | 12 |
12 | CWE-20 | 不正确的输入验证 | -6 |
13 | CWE-77 | 命令中使用的特殊元素的中和不当(“命令注入”) | 3 |
14 | CWE-287 | 身份验证不当 | -1 |
15 | CWE-269 | 权限管理不当 | 7 |
16 | CWE-502 | 不受信任数据的反序列化 | -1 |
17 | CWE-200 | 将敏感信息暴露给未经授权的角色 | 13 |
18 | CWE-863 | 错误授权 | 6 |
19 | CWE-918 | 服务器端请求伪造(SSRF) | 0 |
20 | CWE-119 | 对内存缓冲区范围内的操作限制不当 | -3 |
21 | CWE-476 | 空指针引用 | -9 |
22 | CWE-798 | 硬编码凭据的使用 | -4 |
23 | CWE-190 | 整数溢出或环绕 | -9 |
24 | CWE-400 | 未控制的资源消耗 | 13 |
25 | CWE-306 | 缺少关键功能的身份验证 | -5 |
上表为“TOP25”榜单,相对于2023年,2024年TOP25“TOP25”有较大的变化。
榜内最速上升
CWE-352: 跨站点请求伪造(CSRF) 上升5位,从第9位上升至第4位
CWE-94: 代码生成控制不当(“代码注入”) 上升12位,从第23位上升至第11位(可能与CVE错误关联相关)
CWE-269: 权限管理不当 上升7位,从第22位上升至第15位
CWE-863: 错误授权 上升6位,从第24位上升至第18位
榜内最速下降
CWE-20: 不正确的输入验证 下降6位,从第6位下降至第12位
CWE-476: 空指针引用 下降9位,从第12位下降至第21位
CWE-190: 整数溢出或环绕 下降9位,从第14位下降至第23位
CWE-306: 缺少关键功能的身份验证 下降5位,从第20位下降至第25位
新晋入榜
CWE-400: 未控制的资源消耗 上升13位,从第37位上升至第24位
CWE-200: 将敏感信息暴露给未经授权的角色 上升13位,从第30位上升至第17位
跌出TOP25的CWE
CWE-362: 使用共享资源并发执行,但同步不正确(“争用条件”) 下降13位,从第21位下降至第34位
CWE-276: 默认权限不正确 下降11位,从第25位下降至第36位
对于TOP25榜单的变化,“TOP25”团队承认其中有小部分统计机制变化的原因:2024年的CVE到CWE映射的审查机制强调的是CVE编号机构对CVE到CWE映射进行自查,而非由“TOP25”团队进行审查,这样部分CVE漏洞可能没有映射到合适的CWE分类上,也可能造成了部分CWE排名的变化。尽管如此,“TOP25”仍不失为一个统计严谨数据量充足的统计榜单。
04
开发者应该如何应对TOP类的软件弱点
文章内容所限,这里展示“TOP25”中前三位弱点在具体软件中的样例及解决办法,并尝试总结“TOP25”中较为通用的一些解决办法,期待能据此帮助开发者们以较小的代价消除最多的软件弱点。
CWE-79 跨站脚本
原理
跨站脚本不基于特定语言,是基于WEB应用的常见弱点,可能导致在受害者的计算机上运行任意代码。有以下两种类型的跨站脚本:
反射型XSS:攻击者公开发布URL或直接通过电子邮件发送给受害者URL。受害者点击URL后,网站将攻击者的内容反射回受害者,受害者的浏览器会执行这些内容。
存储型XSS:攻击者将危险数据存储在可信数据存储中。危险数据随后被包含在动态页面。受害者访问恶意页面,受害者的浏览器会执行这些恶意内容。
编码实例
下面是某网站存在反射型跨站脚本的例子,比如某网站的访问方式为,在浏览器中输入:该网站的处理脚本如下:
$username = $_GET['username'];
echo '<div class="header"> 欢迎您, ' . $username . '</div>';
滑动查看全部代码
看起来似乎没有问题,当我们在浏览器中输入:
http://trustedSite.example.com/welcome.php?username=张三
滑动查看全部代码
上面代码处理后会在浏览器中返回字符“欢迎您,张三”,这时黑客可以通过邮件将下面链接发送给受害者:
http://trustedSite.example.com/welcome.php?username=<Script Language="Javascript">alert("You've been attacked!");</Script>
滑动查看全部代码
上面 username= 之后的代码就是黑客想要在受害者机器上执行的代码,受害者如果点击了邮件中的网站链接,就会在自己的计算机上执行黑客的攻击代码了。
消减措施
对于存在XSS漏洞的WEB服务器,可以采取以下消减措施:
1、使用经过审查的库或框架如:Microsoft的Anti-XSS库、OWASP ESAPI编码模块和Apache Wicket
2、对于将输出到另一个网页的任何数据,特别是从外部输入接收的任何数据而言,对所有非字母数字字符使用适当的编码,参考XSS预防作弊表:
https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-url-contexts
3、将客户端状态和敏感信息存储在服务器端,而不是存储在cookie、HTTP头、隐藏表单字段等中
4、服务器端校验(客户端的安全检查在服务器端也需要检查)
5、输入校验:拒绝任何不严格符合规范的输入,或者将其转换为符合规范的内容。(它可以显著减少攻击面)
6、应用防火墙:当代码无法修复(因为它由第三方控制)的情况下,作为一种紧急预防措施,同时应用更全面的软件保证措施,或者提供深度防御
CWE-787 越界写入
原理
踩内存,产品写入的数据超过了预期缓冲区的末尾或开始之前。此弱点在C/C++语言中较为常见。影响程序的完整性和可用性:修改内存;拒绝服务:崩溃、退出或重新启动;执行未经授权的代码或命令。
编码实例
下面是越界写入的代码实例:
int id_sequence[3];
id_sequence[0] = 123;
id_sequence[1] = 234;
id_sequence[2] = 345;
id_sequence[3] = 456;
最后一行代码就执行了越界写入写入范围超出了数组的定义。
消减措施
1、使用不允许出现这种弱点的语言。内存自管理语言如Java,不受缓冲区溢出影响。C#通常提供溢出保护
2、使用经过审查的库或框架如:Messier和Viega的SafeC字符串库(SafeStr,以及Microsoft的Strsafe.h库,不能完全解决问题,因为很多内存溢出和字符串操作无关)
3、使用某些编译器或编译器扩展提供的自动缓冲区溢出检测机制。包括:Microsoft Visual Studio/GS flag、Fedora/Red Hat FORTIFY_SOURCE GCC flag(不能完全解决,因为检测机制只能检测某些类型的溢出)
4、在分配和管理应用程序内存时,请考虑遵守以下规则:
仔细检查缓冲区是否与指定的一样大
使用字节复制函数(如strncpy)时,注意如果src长度比len长,strncpy后dst不以\0结尾,读取dst会溢出
在循环中访问缓冲区,请检查缓冲区边界,并确保没有写入超过分配空间的危险
如有必要,在将所有输入字符串传递给复制和串联函数之前,将其截断为合理的长度
将无界复制函数替换为支持长度参数的函数,例如用strncpy替换strcpy
CWE-89 SQL注入
原理
产品部分或全部使用了来自外界输入的SQL,但没有做安全处理。不基于特定语言,基于DB服务器的常见弱点。可能导致:读取更改删除敏感数据,绕过用户名密码校验等问题。
编码实例
下面是会造成SQL注入的代码实例:
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '" + userName + "' AND itemname = '" + ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
滑动查看全部代码
上面代码执行了如下SQL查询:
SELECT * FROM items WHERE owner =AND itemname =;
滑动查看全部代码
但是,由于查询条件 Itemname 是用户输入字符串动态构造的,因此只有当itemName不包含单引号字符时,查询才会正确运行。如果用户名为wiley的攻击者输入以下字符串作为itemname的时候:
name' OR 'a'='a
就会执行如下的SQL查询:
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR 'a'='a';
滑动查看全部代码
由于 'a'='a' 是永真的判断条件相当于执行了:
SELECT * FROM items;
这时候wiley的用户绕过了owner的校验,查询了不归自己所有的items数据。wiley甚至可以输入如下字符串作为itemname的值:
name'; DELETE FROM items; --
此时程序会执行如下语句:
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name';
DELETE FROM items;
--'
滑动查看全部代码
这里攻击者甚至可以删除items表中的所有数据。
消减措施
1、使用经过审查的库或框架如:Hibernate之类的持久层,如果使用得当,它们可以提供针对SQL注入的重要保护
2、使用prepared statements预编译语句,参数化查询或存储过程处理SQL查询
3、环境强化:在创建SQL数据库的帐户时,遵循最小权限原则,用户只具有使用其帐户所需的最低权限
4、服务器端校验:客户端的安全检查在服务器端也需要检查
5、输出编码:正确引用参数并转义这些参数中的任何特殊字符,在转义/筛选步骤后用引号将每个参数括起来
6、输入校验:拒绝任何不严格符合规范的输入,或者将其转换为符合规范的内容。(它可以显著减少攻击面)
7、确保错误消息只包含对预期受众有用的最小细节,避免攻击者利用返回的错误信息(例如用户帐户是否存在)
8、应用防火墙:当代码无法修复(因为它由第三方控制)的情况下,作为一种紧急预防措施,同时应用更全面的软件保证措施,或者提供深度防御
05
总 结
通过对“TOP25”的消减措施的总览,我们发现其中的一些共性,以下措施总是能很好的消减软件中弱点发生的可能:
1、使用安全的开源框架。主流的编程语言往往存在一些安全可信的库或者框架,帮助应用开发者完成很多的弱点预防工作。
2、产品软件中永远保持对外界输入的警惕性,在服务器端进行校验而不仅仅在客户端进行校验总是能规避很多问题。
3、通过各类静态检查工具检查代码,并认真修改工具检查出的问题,总是能降低弱点发生的可能性。
4、引入应用防火墙,在代码无法修复时提供深度防御。
参考文献
1、2024 “CWE Top 25” Now Available!
https://cwe.mitre.org/news/archives/news2024.html#november19_2024_CWE_Top_25_Now_Available
2、MITRE官网 https://www.mitre.org/who-we-are/our-story
3、CVE官网 https://www.cve.org/
4、MITRE CWE TOP25官网 https://cwe.mitre.org/