第一章:OWASP Top 10与CWE——漏洞世界的“通用语言”
做安全这么多年,我经常被问到同一个问题:“新手学代码审计,到底该从哪入手?”
我的答案一直很固定:先搞懂OWASP Top 10和CWE。说白了,这两个东西就是漏洞世界的“普通话”。你连普通话都不会说,怎么跟同行交流?怎么去分析代码?
1.1 OWASP Top 10(2021)——Web安全的“必修课”
OWASP Top 10,全称是Open Web Application Security Project Top 10。它每三到四年更新一次,2021年的版本是最近的一次大改版。我个人习惯把这十个类别记在脑子里,因为面试、审计、写报告,随时都可能用到。
2021版最大的变化是什么?它不再只是列漏洞类型,而是引入了“漏洞类别”的概念。比如“A01:2021-Broken Access Control”不再是单纯的“越权”,而是把设计缺陷、配置错误都归了进来。
| 排名 | 类别 | 典型CWE映射 | 变化说明 |
|---|---|---|---|
| A01 | 失效的访问控制 | CWE-862, CWE-863 | 从A05升至A01 |
| A02 | 加密机制失效 | CWE-327, CWE-328 | 原“敏感数据暴露”重构 |
| A03 | 注入 | CWE-89, CWE-78 | SQL注入、命令注入合并 |
| A04 | 不安全设计 | CWE-209, CWE-256 | 2021年新增类别 |
| A05 | 安全配置错误 | CWE-16, CWE-611 | 排名上升 |
| A06 | 易受攻击和过时的组件 | CWE-1104 | 原“使用已知漏洞组件” |
| A07 | 身份识别和身份验证失败 | CWE-287, CWE-384 | 排名下降 |
| A08 | 软件和数据完整性故障 | CWE-829, CWE-494 | 2021年新增类别 |
| A09 | 安全日志记录和监控失败 | CWE-778, CWE-223 | 原“不足的日志记录” |
| A10 | 服务端请求伪造(SSRF) | CWE-918 | 2021年新增类别 |
核心观点:OWASP Top 10不是“漏洞百科全书”,而是“风险优先级清单”。它告诉你:先修哪堵墙,能挡住80%的攻击。
1.2 CWE(Common Weakness Enumeration)——漏洞的“身份证号”
如果说OWASP Top 10是目录,那CWE就是每个漏洞的详细档案。CWE由MITRE维护,每个编号对应一种具体的软件弱点。比如CWE-89就是SQL注入,CWE-787是缓冲区溢出。
我在项目中遇到过很多次这样的情况:开发人员说“我修复了SQL注入”,但审计时发现他只是在输入框加了过滤,没处理存储过程。这时候我就会搬出CWE-89的详细描述,告诉他“你只修了表面,没修根因”。
CWE的分类体系很有意思,它分了三层:
- Pillar(支柱):最顶层,比如“CWE-664:不正确的控制资源生命周期”
- Class(类):中间层,比如“CWE-89:SQL注入”
- Base(基础):最底层,比如“CWE-89:SQL注入”本身既是类也是基础
你想想看,如果没有CWE,大家说“注入”可能指SQL、可能指OS命令、可能指LDAP。有了CWE编号,沟通成本直接降为零。
我的小技巧:写安全报告时,每个漏洞都带上CWE编号。这样不仅显得专业,还能让开发团队直接去查MITRE的详细文档,省得我一遍遍解释。
1.3 CVE(Common Vulnerabilities and Exposures)——漏洞的“通缉令”
CVE和CWE容易搞混。我简单解释一下:CWE是“弱点类型”,CVE是“具体漏洞实例”。比如“CVE-2021-44228”就是Log4j那个著名的漏洞,而它的根因是CWE-502(反序列化不可信数据)。
查询CVE,我一般用这几个渠道:
- NVD(National Vulnerability Database):美国政府的官方库,信息最全
- MITRE CVE官网:原始数据源
- GitHub Advisory Database:开源项目漏洞,更新快
举个例子,假设你在审计一个C++项目,发现它用了某个旧版JSON库。你查一下CVE库,发现这个库有CVE-2020-25649(XML外部实体注入)。嗯,这里要注意:CVE编号不代表你的代码一定受影响,但它是“风险信号”。
避坑指南:我曾经见过一个团队,看到CVE编号就慌,立刻升级库。结果新库改了API,编译不过。所以我的建议是:先确认CVE是否影响你的使用场景,再决定是否升级。别盲目追CVE。
1.4 三者的关系——一张图说清楚
OWASP Top 10、CWE、CVE,这三者到底是什么关系?我画了张图,你看完就明白了。
1.5 实战中怎么用这套体系?
假设你接到一个C++代码审计任务,项目是一个HTTP服务器。你会怎么做?
我的流程是这样的:
- 先看OWASP Top 10:重点关注A01(访问控制)、A03(注入)、A06(过时组件)
- 再查CWE映射:比如A03对应CWE-89、CWE-78、CWE-94等
- 最后查CVE:看项目依赖的库有没有已知漏洞
举个例子,我在审计一个C++的HTTP解析库时,发现它用了sscanf解析请求头。嗯,这里要注意:sscanf在C++里虽然能用,但容易出格式字符串漏洞(CWE-134)。我查了一下CVE库,果然这个库的旧版本有CVE-2022-XXXX。
关键点:OWASP Top 10是“战略”,CWE是“战术”,CVE是“战例”。三者结合,才能做出靠谱的安全审计。
1.6 避坑指南——我踩过的几个坑
做安全审计这些年,我犯过不少错。分享几个典型的:
- 坑一:只信OWASP,不信CWE。OWASP Top 10是风险清单,不是技术规范。你审计时不能只列“A03注入”,得具体到CWE-89还是CWE-78,否则开发人员不知道怎么修。
- 坑二:CVE编号当圣旨。CVE编号只代表“有人报告了这个漏洞”,不代表你的代码一定受影响。我见过有人因为CVE-2021-44228(Log4j)把整个项目重写了,其实他的代码根本没用到JNDI lookup。
- 坑三:忽略CWE的层级。CWE有Pillar、Class、Base三层。你写报告时如果只写CWE-664(不正确的控制资源生命周期),开发人员会一脸懵。要写到CWE-415(双重释放)这种具体级别。
我的建议:新手先背熟OWASP Top 10的10个类别,然后每个类别记住2-3个最典型的CWE编号。比如A03注入,记住CWE-89(SQL注入)、CWE-78(OS命令注入)、CWE-94(代码注入)。够用了。
好了,这一章就到这里。OWASP Top 10、CWE、CVE这三者的关系,说白了就是“风险→弱点→实例”的链条。你把这个链条搞清楚了,后面学具体漏洞类型就会轻松很多。