什么是 SQL 注入攻击?

https://www.cdnetworks.com/wos/static-resource/7f4565fb2f2c459b8ba03b988d699000/What-Is-a-SQL-Injection-Attack.jpg?t=1742199746406

目录

SQL 注入攻击(也称 SQLi)是一种 Web 应用攻击,攻击者通过不可信输入改变数据库查询的结构或行为。

成功的 SQL 注入攻击可能使未授权用户查看敏感信息、修改或删除记录、绕过身份验证,或执行数据库管理操作。

这类漏洞通常出现在应用程序将用户可控数据直接拼接到动态构造的 SQL 查询中时。参数化查询、安全开发实践、最小权限访问,以及应用安全测试是主要防御措施。

Web 应用防火墙可以提供额外一层保护,在可疑请求到达存在漏洞的应用程序之前进行识别和拦截。

SQL 注入属于更广泛的注入类漏洞。OWASP Top 10:2025 将”注入“列为 A05,并建议始终将不可信数据与命令和查询分离。


核心要点

  • 当应用程序将不可信输入当作 SQL 命令的一部分处理时,就可能发生 SQL 注入。
  • 成功的攻击可能导致数据库信息泄露、篡改,或删除。
  • 带内、盲注,以及带外 SQL 注入是三大主要类型。
  • 参数化查询是最重要的技术防御措施。
  • 输入验证、最小权限、安全测试,以及 WAF 可提供额外保护。
  • WAF 应作为安全应用代码的补充,而不能取而代之。

什么是 SQL 注入?

SQL,即结构化查询语言,是应用程序与关系型数据库通信时使用的语言。应用程序通过 SQL 语句检索记录、创建数据、更新现有信息,以及删除不再需要的信息。

例如,电商应用可能使用 SQL 获取商品记录、验证客户登录信息,或显示订单历史。SQL 本身是一项合法且不可或缺的技术,广泛应用于各类数据库驱动型应用程序。

当应用程序以不安全的方式将 SQL 指令与不可信输入组合在一起时,就会产生 SQL 注入风险。数据库可能不会将输入完全视为数据,而是把其中一部分解释为指令,从而改变原本的查询逻辑。

OWASP SQL 注入指南指出,SQL 注入通常具备两个核心条件:不可信数据进入应用程序,以及这些数据被用于动态构造数据库查询。

如需快速了解相关术语,请参阅 CDNetworks 的 SQL 注入定义


SQL 注入攻击如何运作?

典型的 SQL 注入攻击通常分为四个阶段。

1. 应用程序接收用户输入

输入可能来自:

  • 登录和注册表单
  • 搜索框
  • 商品或账户标识符
  • URL 参数
  • HTTP 标头和 Cookie
  • API 请求参数
  • JSON 或 XML 请求正文

用户输入本身并不会直接形成漏洞。风险取决于应用程序如何处理这些输入。

2. 应用程序构造 SQL 查询

存在漏洞的应用程序可能通过字符串拼接,将输入直接加入 SQL 语句。
例如,以下概念性代码将 SQL 命令与用户提交的电子邮件地址拼接在一起,以生成查询:

email = request.getParameter("email")

query = "SELECT customer_id, name FROM customers
         WHERE email = '" + email + "'"

database.execute(query)

应用程序假设提交的值只会包含电子邮件地址。由于该值被直接插入 SQL 语句,意外或恶意的语法可能改变查询原本的行为。

OWASP SQL 注入防御速查表指出,使用字符串拼接和用户输入构造动态查询,是 SQL 注入的常见成因。

3. 数据库执行被篡改的查询

应用程序将完整查询发送到数据库。如果指令和输入之间没有明确分隔,数据库可能会把提交值中的一部分解释为 SQL 语法。

根据存在漏洞的查询,以及应用程序数据库账户所拥有的权限,数据库可能返回超出应用授权范围的信息,或执行本不允许的操作。

4. 应用程序暴露结果

可能产生的结果包括:

  • 绕过身份验证
  • 获取未授权的数据库记录
  • 返回包含技术细节的数据库错误
  • 修改或删除信息
  • 出现异常的应用响应
  • 在盲注场景中出现响应延迟

有些攻击会直接返回信息,另一些攻击则通过应用行为的差异,推断数据库的响应结果。


SQL 注入攻击会造成什么后果?

SQL 注入的影响取决于存在漏洞的查询、数据库配置,以及授予应用程序数据库账户的权限。

泄露机密信息

攻击者可能未经授权访问:

  • 客户资料
  • 员工记录
  • 账户信息
  • 身份验证数据
  • 内部业务记录
  • 财务或交易相关信息

具体泄露多少信息,在一定程度上取决于查询范围,以及应用程序可用的数据库权限。

绕过身份验证

如果应用程序使用不安全的数据库查询验证用户名和密码,攻击者可能通过改变查询逻辑,在没有有效凭据的情况下访问账户。

篡改业务数据

成功的攻击可能修改以下记录:

  • 账户信息
  • 商品价格
  • 库存数量
  • 用户权限
  • 交易详情
  • 订单状态
  • 应用程序设置

未经授权的修改会破坏数据完整性,并干扰关键业务流程。

删除信息

某些漏洞可能允许攻击者删除记录、数据表,或其他数据库对象,进而造成服务中断、数据丢失,以及高昂的恢复成本。

获取更高数据库权限

如果应用程序使用权限过高的账户连接数据库,成功的 SQL 注入攻击可能使攻击者访问应用程序日常运行并不需要的管理功能。

影响底层系统

在某些数据库和服务器配置下,SQL 注入还可能导致文件访问,甚至操作系统命令执行。具体风险取决于数据库技术、已启用的功能,以及数据库账户拥有的权限。

OWASP Web 安全测试指南指出,SQL 注入可能导致数据泄露、数据篡改、数据库管理操作、文件访问,并在某些情况下触发操作系统命令执行。


SQL 注入攻击的类型

SQL 注入攻击通常根据恶意输入的提交方式,以及信息的返回方式进行分类。主要类型包括带内 SQL 注入、推断式或盲注,以及带外 SQL 注入。

带内 SQL 注入

带内 SQL 注入使用同一通信通道发送恶意输入并接收数据库结果。

基于错误的 SQL 注入依赖详细的数据库错误信息,这些信息可能暴露表名、列名、查询结构,或数据库软件类型。

基于 UNION 的 SQL 注入尝试将应用程序原本的查询与另一条查询合并,使未授权数据出现在响应中。

隐藏详细错误信息可以减少信息泄露,但仍必须修复存在漏洞的查询。

推断式 SQL 注入或盲注

当数据库结果不会直接显示时,就可能出现盲注。攻击者通过应用程序行为的差异推断信息。

基于布尔条件的盲注根据数据库条件为真或为假时应用程序返回的不同响应进行判断。

基于时间的盲注利用特定数据库条件引起的可测量响应延迟推断信息。

OWASP 盲注指南介绍了即使数据库输出被隐藏,应用程序响应仍可能泄露信息的原因。

带外 SQL 注入

带外 SQL 注入通过独立的通信通道传输信息,例如诱使数据库发起外部网络请求。

这种技术依赖特定数据库功能、系统配置,以及出站网络访问能力。

二阶 SQL 注入

二阶 SQL 注入是指不安全的输入先被存储,随后又被用于动态构造查询。

原始请求看起来可能没有问题。等到另一个应用程序流程读取已存储的值,并将其中一部分解释为 SQL 语法时,漏洞才会显现。


SQL 注入示例

任何使用用户可控信息构造数据库查询的功能,都可能受到 SQL 注入影响。登录页面常用于解释这一概念,但搜索功能、报表工具、账户门户、API,以及管理界面同样可能存在漏洞。

示例 1:不安全的搜索功能

假设某个应用程序根据访客选择的类别检索商品:

query = "SELECT product_id, product_name
         FROM products
         WHERE category = '" + category + "'"

应用程序假设 category 中只会包含 bookselectronics 等正常值。

由于该值被直接插入 SQL 语句,意外或恶意语法可能改变查询含义。开发人员应改用参数化查询:

query = "SELECT product_id, product_name
         FROM products
         WHERE category = ?"

database.execute(query, [category])

参数化版本会固定查询结构,并将类别值作为数据处理。OWASP SQL 注入防御速查表建议将预编译语句和参数化查询作为防御 SQL 注入的首要措施。

示例 2:不安全的动态报表

报表系统有时允许用户选择字段、表名,或排序选项。SQL 语句中的这些结构性部分并不总能通过普通值参数处理。
开发人员应将用户选择映射到预定义的允许列表,而不是直接把用户提交的表名或列名插入查询。

例如:

allowed_sort_fields = {
    "name": "customer_name",
    "date": "created_at",
    "status": "account_status"
}

sort_column = allowed_sort_fields.get(user_choice, "created_at")

应用程序从映射中选择可信的数据库标识符,而不会把原始请求值当作 SQL 语法处理。

OWASP SQL 注入防御速查表建议,在动态查询元素无法通过绑定参数表示时,采用允许列表验证。

真实案例:MOVEit Transfer

2023 年,CL0P 勒索软件组织利用了 Progress Software 的 MOVEit Transfer 产品中的 CVE-2023-34362 漏洞。

根据 CISA 与 FBI 联合安全公告,攻击始于 MOVEit Transfer Web 应用中的 SQL 注入漏洞。此次攻击活动涉及未授权访问、部署 Web Shell,以及从受影响系统窃取数据。

该事件带来了几项重要安全启示:

  • 面向互联网的应用程序需要持续开展漏洞管理。
  • SQL 注入可能成为更大规模入侵的切入点。
  • 组织需要及时修补漏洞,并具备事件响应能力。
  • 在永久修复部署完成前,监控和临时安全控制有助于降低暴露风险。
  • 单个应用漏洞造成的影响可能超出受影响数据库本身。

如何检测 SQL 注入漏洞和攻击

检测工作应结合安全开发审查、经过授权的应用测试,以及生产环境监控。任何单一方法都无法可靠识别所有 SQL 注入漏洞或攻击尝试。

审查应用程序源代码

代码审查可以在应用程序部署前识别不安全的查询模式。
审查人员应重点检查:

  • 通过字符串拼接构造的 SQL 语句
  • 传入原始查询函数的用户可控值
  • 动态选择的表名或列名
  • 构造动态 SQL 的存储过程
  • 未使用绑定参数的数据库调用
  • 允许执行不安全原始查询的 ORM 函数
  • 权限过高的应用程序数据库账户

使用对象关系映射框架并不能自动防止 SQL 注入。原始查询、不安全的查询构造函数,以及对用户可控值处理不当,仍可能引入漏洞。

开发团队还应检查主应用程序之外的数据库访问点,包括后台任务、报表工具、管理实用程序,以及数据导入流程。

将安全测试融入开发流程

应用安全测试可能包括:

  • 静态应用安全测试,即 SAST
  • 动态应用安全测试,即 DAST
  • 交互式应用安全测试,即 IAST
  • 人工安全代码审查
  • 安全回归测试
  • 经授权的渗透测试

测试应覆盖所有可能与数据库交互的输入通道,包括:

  • 表单字段
  • URL 参数
  • HTTP 标头
  • Cookie
  • API 请求
  • JSON 和 XML 正文
  • 上传的数据
  • 先前存储的值
  • 后台进程

OWASP SQL 注入 Web 安全测试指南提供了一套结构化方法,用于识别 SQL 注入点,并评估攻击者可能获得的数据库访问级别。

测试只能针对测试人员已获得明确授权的应用程序和系统开展。生产环境测试必须谨慎控制,以免造成服务中断、数据丢失,或意外的数据库更改。

监控应用程序和安全活动

SQL 注入尝试的潜在迹象包括:

  • 重复出现的格式异常请求
  • URL 或 API 参数中出现异常输入
  • 数据库语法错误突然增多
  • 重复触发类似应用错误的请求
  • 异常响应延迟
  • 数据库查询量异常
  • 返回结果集异常庞大
  • 未授权访问记录
  • 敏感数据发生意外更改
  • 同一来源反复触发 WAF 检测

单个迹象也可能有合理解释。例如,数据库错误可能源于应用缺陷,异常请求量也可能来自经过批准的自动化流程。

安全团队应综合分析应用日志、数据库日志、WAF 事件、身份系统,以及网络监控数据,再判断相关活动是否属于已确认的攻击。

保护安全日志和错误信息

日志应包含足够的调查上下文,同时避免记录不必要的敏感信息。

密码、身份验证令牌、支付数据,以及会话标识符应被排除,或得到适当保护。日志访问应受到限制,相关记录也应防止被未授权删除或修改。

面向公众的应用响应应避免暴露详细数据库错误、查询文本、表名、软件版本、堆栈跟踪,或内部文件路径。详细技术信息应保存在受保护的内部日志中,而不应直接显示给用户。

隐藏详细错误信息可以减少攻击者获得的信息,但无法修复存在漏洞的查询。


如何防止 SQL 注入

有效防御应从安全构造查询开始,并通过验证、访问控制、测试,以及运行时保护进一步加强。

使用参数化查询

参数化查询和预编译语句是防止 SQL 注入的主要技术措施。
应用程序使用占位符定义 SQL 命令,并单独传入用户可控值,从而避免提交值改变查询结构。

OWASP SQL 注入防御速查表建议将参数化查询作为首选防御措施。

避免拼接 SQL 字符串

应用程序不应将查询字符串与不可信值直接拼接,以生成 SQL 命令。
不可信数据可能来自表单、URL、标头、Cookie、API、上传文件、第三方集成、消息队列,或先前存储在数据库中的值。

改用支持参数化的数据库 API,可以从根源上解决这类漏洞。

安全使用存储过程

当存储过程使用参数并避免动态 SQL 时,可以降低 SQL 注入风险。
如果存储过程仍会拼接输入,或执行动态生成的语句,它依然可能存在漏洞。因此,即使在存储过程中,也必须保持 SQL 命令与不可信数据相互分离。

采用允许列表验证

输入验证应确认提交值符合预期格式、范围,以及允许选项。

例如,要求标识符必须为数字、将状态字段限制为预定义值、验证日期格式,以及将排序选项映射到可信列名。

输入验证应配合参数化查询使用,而不能取代参数化查询。仅依赖拒绝列表过滤并不可靠,因为 SQL 语法可以通过多种方式表示。

实施最小权限访问

应用程序数据库账户只应获得执行正常功能所需的权限。
例如,报表应用可能只需要读取权限,不应拥有修改权限。面向客户的应用程序也不应使用数据库管理员账户连接数据库。

最小权限无法消除漏洞,但可以限制成功利用后造成的损害。

控制错误信息并持续测试

应用程序应向用户显示中性的错误消息,同时将技术细节记录在访问受限的内部日志中。

安全测试应贯穿设计、开发、部署,以及维护全过程。重要实践包括代码审查、自动化安全测试、渗透测试、回归测试、依赖更新,以及数据库访问审查。

组织还应持续关注供应商安全公告,并及时更新存在漏洞的应用程序、框架、插件,以及第三方软件。

使用 WAF 实现纵深防御

Web 应用防火墙可以检查 HTTP 和 HTTPS 请求、拦截多种已知攻击模式、提供可疑活动可视性,并在永久修复完成前通过虚拟补丁降低风险。

WAF 无法修复存在漏洞的代码,也无法保证拦截所有 SQL 注入技术。参数化查询和漏洞修复仍然不可或缺。

OWASP 关于绕过 WAF 的 SQL 注入技术文档进一步说明了将运行时保护与安全应用开发相结合的重要性。


CDNetworks 如何帮助应用程序防御 SQL 注入

修复存在漏洞的应用代码,仍是防止 SQL 注入最有效的方法。CDNetworks 可通过漏洞测试为这一过程提供支持,帮助识别应用程序中的安全弱点,使开发和安全团队能够确定修复优先级。

CDNetworks Web 应用防火墙会在 HTTP 和 HTTPS 请求到达源站应用之前进行检查,从而增加一层安全防护。依托全球 3000 多个 PoP,该方案结合 1000 多条内置安全规则,以及基于 AI 和机器学习的分析能力,可检测已知和持续演变的 SQL 注入模式。

cybersecurity-trends-CDNetworks-WAAP-capabilities.png

自动规则更新、自定义安全策略,以及虚拟补丁,有助于在永久修复开发和部署期间降低暴露风险。作为纵深防御体系的一部分,这些控制措施可与参数化查询、输入验证,以及数据库最小权限访问协同工作。

CDNetworks 的安全服务还包括漏洞评估和渗透测试能力。立即开始使用 CDNetworks WAF,或下载 Web 应用防火墙产品简介


常见问题

SQL 注入是什么意思?

SQL 注入是一类安全漏洞,不可信输入会改变数据库查询,可能导致未授权数据访问、修改、删除、绕过身份验证,或执行数据库管理操作。

SQL 注入属于网络攻击吗?

SQL 注入是一种应用层网络攻击。攻击者利用不安全的数据库查询访问、修改,或删除数据,绕过身份验证,或执行超出应用程序预期权限的操作。

SQL 和 SQL 注入有什么区别?

SQL 是用于管理关系型数据库的语言。SQL 注入则是一类漏洞,它允许不可信输入改变数据库查询原本的结构或行为。

SQL 注入攻击的例子有哪些?

当搜索表单把用户输入直接插入 SQL 查询时,就可能产生漏洞。参数化查询可以防止提交值被解释为可执行的 SQL 语法。

哪些数据库会受到 SQL 注入影响?

只要应用程序以不安全的方式构造查询,使用关系型 SQL 系统的数据库都可能受到影响。具体语法和影响因数据库平台、编程语言、驱动程序,以及应用框架而异。

探索更多

网站性能

2026年亚洲七大CDN服务商

比较 2026 年亚洲顶级 CDN 提供商,包括 Cloudflare、Akamai、CDNetworks、CloudFront、Fastly、腾讯和阿里巴巴。

了解更多 »
云安全

2025 年 WAAP 现状报告:人工智能正在改变 Web 应用和 API 安全

了解《2025 年 WAAP 现状报告》中的关键见解,看看人工智能正在如何改变 Web 应用程序和 API 安全。

了解更多 »