- 应用安全
【免费下载链接】Top10
Official OWASP Top 10 Document Repository
导读
本文以 OWASP Top 10:2025 官方文档仓库 中的 A05:2025 Injection 英文原档(及仓库内 繁体中文译本)为绝对主体,系统拆解注入(Injection)在 2025 版榜单中的排名变化、评分依据、漏洞成因、判定条件、攻击场景与防护手段。读完本文,你将掌握 SQL、NoSQL、OS 命令、ORM、LDAP、EL/OGNL 等各类注入的统一防护原则,理解"数据与命令分离"这一核心方法论,并能在代码审计与 CI/CD 测试实践中落实 OWASP 推荐的检测与修复策略。
一、榜单地位:为什么注入从第 3 位滑落到第 5 位
注入(Injection)在 OWASP Top 10:2025 中排名第 5 位,相比 2021 版(第 3 位)下降两个位次,但它相对于 A04:2025 加密机制失效 和 A06:2025 不安全设计 的相对位置保持不变。需要注意,"排名下降"并不代表该类问题变少,而是其他类别(如安全配置错误、软件供应链失效)的统计数据增长更快。
注入是测试覆盖最充分的类别之一——100% 的应用都接受了某种形式的注入测试。同时,它是所有类别中关联 CVE 数量最多的类别,本类别共映射37 个 CWE。其中:
- 跨站脚本(XSS):高频率、低影响,关联超过3 万个 CVE;
- SQL 注入:低频率、高影响,关联超过1.4 万个 CVE。
大量已报告的 CWE-79(网页生成期间输入中和不当,即跨站脚本)CVE 拉低了该类别的平均加权影响分。
1.1 官方评分表
下表为 A05:2025 在 2025 数据周期中的完整评分(数据来源:英文原档):
| 指标 | 数值 |
|---|---|
| 映射的 CWE 数量 | 37 |
| 最大发生率(Max Incidence Rate) | 13.77% |
| 平均发生率(Avg Incidence Rate) | 3.08% |
| 最大覆盖率(Max Coverage) | 100.00% |
| 平均覆盖率(Avg Coverage) | 42.93% |
| 平均加权可利用性(Avg Weighted Exploit) | 7.15 |
| 平均加权影响(Avg Weighted Impact) | 4.32 |
| 发生总数(Total Occurrences) | 1,404,249 |
| CVE 总数(Total CVEs) | 62,445 |
说明:仓库内 2025 版引言文档 中对该类别表述为"38 个 CWE",而本类别文档及评分表均为 37 个,正文以本类别文档的 37 个为准。
1.2 评分是如何算出来的
要读懂上表,需要理解 OWASP 2025 版的风险评分方法论。仓库中的 《什么是应用安全风险》 给出了明确公式:
(Max Incidence Rate % × 1000) + (Max Coverage % × 100) + (Avg Exploit × 10) + (Avg Impact × 20) + (Sum Occurrences / 10000) = Risk Score各项指标含义如下:
- CWEs Mapped:Top 10 团队映射到该类别的 CWE 数量;
- Incidence Rate(发生率):某组织在某一年度测试的应用中,存在该 CWE 的应用所占百分比;
- Weighted Exploit / Impact(加权可利用性/影响):从 NVD 中 CVEs 关联的 CVSSv2/v3 分数提取、归一化到 10 分制;
- Coverage(覆盖率):所有组织针对某个 CWE 测试过的应用百分比,覆盖率越高,发生率越可信;
- Total Occurrences:被发现存在该类 CWE 的应用总数;
- Total CVEs:NVD 数据库中映射到该类 CWE 的 CVE 总数。
评分数据来自 2025 版数据收集计划(详见仓库 2025/Data/README.md):由安全厂商、咨询机构、漏洞赏金平台等贡献超过 280 万个应用样本,贡献窗口覆盖 2021—2024 年数据,并对"人工辅助工具(HaT)"与"工具辅助人工(TaH)"两类数据加以区分和归一化处理。
二、漏洞定义与判定条件
2.1 什么是注入漏洞
官方定义:注入漏洞是应用缺陷,它允许不可信的用户输入被发送给解释器(例如浏览器、数据库、命令行),并导致解释器将输入的一部分当作命令执行。
"解释器"是一个宽泛概念——SQL 引擎、NoSQL 引擎、操作系统 shell、ORM 查询构造器、LDAP 目录服务、表达式语言求值器(EL/OGNL)、模板引擎等都是解释器。注入的本质是数据与命令未分离:恶意数据被解释器当作可执行结构来解析。
2.2 应用易受攻击的四个判定条件
当出现以下任一情况时,应用就处于注入风险中:
- 用户提供的数据没有被应用验证、过滤或清理(sanitize);
- 动态查询或非参数化调用在缺少上下文感知转义的情况下被直接用于解释器;
- 未清理的数据被用于对象关系映射(ORM)搜索参数,从而提取额外的敏感记录;
- 可能有害的数据被直接使用或拼接——SQL 或命令在动态查询、命令或存储过程中同时包含结构(structure)和恶意数据。
注意第 4 点的关键:当"查询的结构"和"恶意数据"被拼接进同一条动态语句时,攻击者就能改写语句的语义。
2.3 常见注入类型
较常见的注入包括:
| 注入类型 | 目标解释器 | 典型后果 |
|---|---|---|
| SQL 注入 | 关系数据库 SQL 引擎 | 越权读取/修改/删除数据,调用存储过程 |
| NoSQL 注入 | MongoDB 等 NoSQL 查询语言 | 绕过认证、越权读取 |
| OS 命令注入 | 操作系统 shell | 在服务器上执行任意命令 |
| ORM 注入 | Hibernate(HQL)等 ORM 查询语言 | 绕过过滤器,越权访问数据 |
| LDAP 注入 | 目录服务查询 | 绕过认证、越权读取目录 |
| EL / OGNL 注入 | 表达式语言求值器 | 代码执行、远程命令执行 |
尽管解释器各不相同,攻击与防护的概念在所有解释器间是相同的:都是让不可信输入穿越"数据边界"进入"命令边界"。
2.4 相关的新兴形态:LLM 提示注入
文档特别指出,一类相关的注入漏洞在大语言模型(LLM)场景中已经变得常见,即LLM01:2025 Prompt Injection(提示注入),它在 OWASP LLM Top 10 中单独讨论。这类问题与经典注入共享同一本质——用户/外部内容被解释器(LLM)当作指令而非数据执行。
三、与 2021 版的对照:注入类别的演进
仓库同时收录了 2021 版 A03:2025-Injection 文档,两版对照可以清晰看到该类别四年的演进:
| 维度 | 2021 版(A03) | 2025 版(A05) |
|---|---|---|
| 排名 | 第 3 位 | 第 5 位 |
| 映射 CWE 数 | 33 | 37 |
| 最大覆盖率 | 94.04% | 100.00% |
| 平均覆盖率 | 47.90% | 42.93% |
| 最大发生率 | 19.09% | 13.77% |
| 平均发生率 | 3.37% | 3.08% |
| 发生总数 | 274,228 | 1,404,249 |
| CVE 总数 | 32,078 | 62,445 |
值得注意的变化:
- CVE 总数翻了近一倍(从约 3.2 万增至 6.2 万),发生总数从 27 万增至 140 万,说明自动化测试工具对该类问题的检出能力大幅提升;
- 2021 版中 HQL 攻击场景的 payload 为
' UNION SLEEP(10);--,2025 版更新为' OR custID IS NOT NULL OR custID='(语义更直接地展示"绕过过滤器"); - 2025 版新增强调了 LLM 提示注入这一跨领域形态;
- 2025 版对存储过程(PL/SQL 的
EXECUTE IMMEDIATE、T-SQL 的exec())中残余 SQL 注入风险的提示被保留并强化。
四、如何预防:数据与命令分离的核心原则
文档明确给出了注入防护的首选策略与兜底技术,这是全篇最具实战价值的部分。
4.1 首选:使用安全 API(彻底避免使用解释器)
预防注入的最佳手段是让数据与命令、查询保持分离:
- 使用安全 API——完全避免使用解释器;
- 使用参数化接口(parameterized interface)——查询结构预先固定,用户输入仅作为参数绑定;
- 或迁移到对象关系映射工具(ORM)——由框架负责查询构造与参数绑定。
以文档场景 #1 的 Java 代码为例,其安全替代写法正是参数化接口:
// 危险写法:字符串拼接 String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'"; // 安全写法:PreparedStatement 参数化绑定 PreparedStatement ps = conn.prepareStatement("SELECT * FROM accounts WHERE custID = ?"); ps.setString(1, request.getParameter("id")); ResultSet rs = ps.executeQuery();重要提示:即使已参数化,存储过程仍可能引入 SQL 注入——如果 PL/SQL 或 T-SQL 在存储过程内部拼接查询和数据,或用
EXECUTE IMMEDIATE/exec()执行有害数据,参数化接口的保护就会被绕过。
4.2 兜底技术:当无法分离数据与命令时
当业务场景无法做到完全参数化时,可以采取以下手段降低威胁:
- 正向服务端输入验证(positive server-side input validation):按白名单规则校验输入格式。注意这不是完整防御——许多应用(文本域、移动端 API)本身就允许特殊字符;
- 对残余的动态查询,使用该解释器专用的转义语法转义特殊字符:不同解释器的转义语法不同,必须"上下文感知"。
注意:SQL 结构(表名、列名等)无法被转义,因此用户提供的结构名称是危险的——这在报表编写软件中是非常常见的问题(用户可控制排序字段、表名)。
警告:转义技术涉及对复杂字符串的解析和转义,容易出错,且对底层系统的细微变化不够稳健。因此文档的立场非常明确:安全 API / 参数化是首选,转义只是兜底。
4.3 从防护到体系:把注入防护嵌入开发流程
注入防护不应停留在单点代码修复。仓库中的 《建立现代应用安全计划》 给出了体系化路径:在需求阶段明确数据的机密性、完整性、可用性与真实性保护需求;在设计阶段进行威胁建模、安全设计评审;在开发阶段推行安全编码规范与代码评审;在验证阶段将静态分析(SAST)、动态分析(DAST)、软件成分分析(SCA)等工具纳入 CI/CD。
五、典型攻击场景详解
文档提供了三个经典攻击场景,逐一拆解如下。
5.1 场景 #1:SQL 注入(字符串拼接 + 恒真条件)
应用使用不可信数据构造易受攻击的 SQL 调用:
String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'";攻击者在浏览器中把id参数值修改为' OR '1'='1:
http://example.com/app/accountView?id=' OR '1'='1拼接后的完整语句变为:
SELECT * FROM accounts WHERE custID='' OR '1'='1'由于'1'='1'恒为真,查询被改写为返回accounts表的全部记录,造成账户信息越权泄露。更危险的载荷还可以修改或删除数据,甚至调用存储过程(如追加; DROP TABLE accounts;--、; EXEC xp_cmdshell('...');--等)。
5.2 场景 #2:ORM/HQL 注入(盲目信任框架)
应用对框架的盲目信任可能产生仍可被利用的查询。例如 Hibernate Query Language(HQL):
Query HQLQuery = session.createQuery("FROM accounts WHERE custID='" + request.getParameter("id") + "'");攻击者提供:' OR custID IS NOT NULL OR custID=',从而绕过过滤器并返回所有账户:
FROM accounts WHERE custID='' OR custID IS NOT NULL OR custID=''虽然 HQL 的危险函数少于原始 SQL(没有UNION、DROP等直接 DDL/DML 能力),但当用户输入被拼接进查询时,仍会允许未经授权的数据访问。HQL 场景的安全替代写法是使用命名参数:
Query HQLQuery = session.createQuery("FROM accounts WHERE custID = :custId"); HQLQuery.setParameter("custId", request.getParameter("id"));5.3 场景 #3:OS 命令注入(Runtime.exec 拼接)
应用把用户输入直接传给 OS 命令:
String cmd = "nslookup " + request.getParameter("domain"); Runtime.getRuntime().exec(cmd);攻击者提供example.com; cat /etc/passwd,利用 shell 的命令分隔符;在服务器上执行任意命令:
nslookup example.com; cat /etc/passwd这是命令注入的典型形态:nslookup的正常功能只是"幌子",;之后的任意命令会被 shell 解释执行。安全替代写法是避免经过 shell,以参数数组方式直接启动进程(如 Java 的ProcessBuilder):
ProcessBuilder pb = new ProcessBuilder("nslookup", request.getParameter("domain")); Process p = pb.start();ProcessBuilder的变长参数形式不会经过 shell 解释,;、&、|等元字符会作为普通参数传递,从而阻断命令拼接。
六、检测与测试实践
文档给出的检测建议是组合式的,单靠一种手段无法覆盖全部注入面:
- 源代码审查(Source Code Review):直接审计是否存在字符串拼接式动态查询、非参数化调用、直接执行外部输入的 OS 命令等反模式;
- 自动化测试(含模糊测试/Fuzzing):对所有参数、请求头(headers)、URL、cookie、JSON、SOAP 和 XML 数据输入进行自动化注入测试;
- 将 SAST / DAST / IAST 工具接入 CI/CD 流水线:在生产部署之前发现注入缺陷。其中:
- SAST(静态应用安全测试):不运行程序,扫描源码定位拼接点;
- DAST(动态应用安全测试):运行中的应用进行黑盒注入探测;
- IAST(交互式应用安全测试):在运行时结合代码插桩定位漏洞触发链路。
仓库 2025/Data/README.md 还披露了数据侧的信息:2025 版收集的数据来自安全厂商与咨询机构、漏洞赏金(bug bounty)、企业/组织贡献等多种来源,并区分人工辅助与工具辅助的测试类型——这说明注入类问题在真实应用中的高检出率与自动化工具的成熟度直接相关。
七、映射的 37 个 CWE 清单
A05:2025 共映射 37 个 CWE(中文名称参考仓库 zh-Hant 译本 整理为简体中文):
| CWE 编号 | 名称 |
|---|---|
| CWE-20 | 输入验证不当(Improper Input Validation) |
| CWE-74 | 下游组件所用输出中特殊元素中和不当(注入) |
| CWE-76 | 等价特殊元素中和不当 |
| CWE-77 | 命令中特殊元素中和不当(命令注入) |
| CWE-78 | 操作系统命令中特殊元素中和不当(OS 命令注入) |
| CWE-79 | 网页生成期间输入中和不当(跨站脚本) |
| CWE-80 | 网页中脚本相关 HTML 标签中和不当(基础 XSS) |
| CWE-83 | 网页属性中的脚本中和不当 |
| CWE-86 | 网页标识符中的无效字符中和不当 |
| CWE-88 | 命令中参数分隔符中和不当(参数注入) |
| CWE-89 | SQL 命令中特殊元素中和不当(SQL 注入) |
| CWE-90 | LDAP 查询中特殊元素中和不当(LDAP 注入) |
| CWE-91 | XML 注入(又称盲 XPath 注入) |
| CWE-93 | CRLF 序列中和不当(CRLF 注入) |
| CWE-94 | 代码生成控制不当(代码注入) |
| CWE-95 | 动态求值代码中指令中和不当(Eval 注入) |
| CWE-96 | 静态保存代码中指令中和不当(静态代码注入) |
| CWE-97 | 网页中服务端包含(SSI)中和不当 |
| CWE-98 | PHP 程序中 include/require 语句文件名控制不当(PHP 远程文件包含) |
| CWE-99 | 资源标识符控制不当(资源注入) |
| CWE-103 | Struts:validate() 方法定义不完整 |
| CWE-104 | Struts:表单 Bean 未扩展验证类 |
| CWE-112 | 缺少 XML 验证 |
| CWE-113 | HTTP 头中 CRLF 序列中和不当(HTTP 响应拆分) |
| CWE-114 | 进程控制 |
| CWE-115 | 输出解释错误 |
| CWE-116 | 输出编码或转义不当 |
| CWE-129 | 数组索引验证不当 |
| CWE-159 | 特殊元素无效使用处理不当 |
| CWE-470 | 使用外部可控输入选择类或代码(不安全反射) |
| CWE-493 | 关键 public 变量缺少 final 修饰符 |
| CWE-500 | public static 字段未标记为 final |
| CWE-564 | SQL 注入:Hibernate |
| CWE-610 | 对另一范围中资源的外部可控引用 |
| CWE-643 | XPath 表达式中数据中和不当(XPath 注入) |
| CWE-644 | 脚本语法的 HTTP 头中和不当 |
| CWE-917 | 表达式语言语句中特殊元素中和不当(EL 注入) |
可以看到,该清单既包含根因类CWE(如 CWE-20、CWE-116),也包含症状类CWE(如 CWE-79 XSS、CWE-89 SQL 注入),覆盖从 Web 页面生成、SQL/LDAP/XPath 查询到 OS 命令、反射、表达式语言的完整注入面。企业可按语言/框架筛选与本技术栈相关的 CWE 建立针对性培训与检测基线。
八、进一步阅读与仓库导航
8.1 本文依据的仓库文档
- A05:2025 Injection 英文原档:本文主体来源;
- A05:2025 注入 繁体中文译本:CWE 中文命名参考;
- 2025 版引言(含类别变更与方法论):A05 排名变化的全局背景;
- 什么是应用安全风险(评分公式与指标定义):解读评分表必需;
- 建立现代应用安全计划:注入防护的体系化落地;
- 2021 版 A03 注入文档:跨版本对照;
- 2025 数据收集与分析计划:评分数据来源与贡献流程;
- 2025 站点配置 mkdocs.yml:文档站的多语言结构与导航组织;
- 2025 演讲材料目录。
8.2 官方延伸阅读(原档 References,按名称列出)
原档引用的 OWASP 官方资料包括:OWASP Proactive Controls 的 Secure Database Access;OWASP ASVS 的 V5 Input Validation and Encoding;OWASP Testing Guide 中 SQL Injection、Command Injection、ORM Injection 测试章节;Injection Prevention、SQL Injection Prevention、Injection Prevention in Java、Query Parameterization 等 Cheat Sheet;OWASP Automated Threats to Web Applications(OAT-014);PortSwigger 关于服务端模板注入的资料;以及 Awesome Fuzzing 模糊测试资源列表。
结语:把"数据与命令分离"变成工程习惯
A05:2025 注入类别的核心教训可以浓缩为一句话:凡是将不可信输入交给解释器执行的地方,都必须保证数据与命令结构分离——首选安全 API 与参数化接口,兜底使用上下文感知转义,并以源代码审查、全输入面模糊测试、SAST/DAST/IAST 组合检测在 CI/CD 中持续验证。注入不会因为"框架很安全"而消失(HQL 场景即是证明),也不会因为"排名下降"而变少(CVE 总数从 3.2 万增长到 6.2 万即是证明)。真正有效的防线,是把这一原则固化为团队的编码规范、评审清单与自动化测试基线。
- 应用安全
【免费下载链接】Top10
Official OWASP Top 10 Document Repository
相关推荐
OWASP Top 10:2025 注入(A05)深度解析:漏洞原理、攻击场景与防护实践
OWASP Top 10:2025 注入(A05)深度解析:漏洞原理、攻击场景与防护实践 本指南以 OWASP Top 10 官方文档仓库中的 A05:2025
应用安全OWASP Top 10:2025 A05 注入(Injection)漏洞深度解析:原理、检测、防御与攻击场景
OWASP Top 10:2025 A05 注入(Injection)漏洞深度解析:原理、检测、防御与攻击场景 本文以 OWASP Top 10:2025 官方
应用安全OWASP Top 10 2017 A1:2017 注入(Injection)漏洞完全解读:从攻击原理到防护实践
OWASP Top 10 2017 A1:2017 注入(Injection)漏洞完全解读:从攻击原理到防护实践 本文基于 OWASP Top 10 官方文档仓
应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考