<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>网络安全 on 我的博客</title><link>https://linxi-blog.pages.dev/categories/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/</link><description>Recent content in 网络安全 on 我的博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 27 Sep 2026 11:40:00 +0800</lastBuildDate><atom:link href="https://linxi-blog.pages.dev/categories/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>SQL 注入与 WAF 绕过：从规则失配到纵深防御</title><link>https://linxi-blog.pages.dev/posts/sql-injection-and-waf-defense/</link><pubDate>Sun, 27 Sep 2026 11:40:00 +0800</pubDate><guid>https://linxi-blog.pages.dev/posts/sql-injection-and-waf-defense/</guid><description>&lt;p&gt;SQL 注入长期位居 Web 安全风险的核心位置，并不是因为它“古老”，而是因为它直接触碰了应用安全中最根本的一条边界：&lt;strong&gt;数据与代码必须分离&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;当用户输入被拼接进 SQL 语句时，输入不再只是数据，而有机会改变语句结构。安全产品、输入过滤和 WAF 可以增加攻击成本，但它们不能替代安全的数据访问方式。本文讨论 SQL 注入的主要类型、WAF 绕过的本质、常见检测误区，以及更可靠的工程化防御方案。&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;本文用于安全开发和防御体系建设。涉及真实系统的测试必须在明确授权、可恢复和可追踪的前提下进行。文章不提供针对真实目标的攻击步骤或可直接复用的绕过 payload。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="一sql-注入的本质"&gt;一、SQL 注入的本质&lt;/h2&gt;&#10;&lt;p&gt;应用程序通常会根据用户输入构造数据库查询。例如，概念上可能出现这样的逻辑：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;查询用户名为输入值的管理员记录&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果输入始终被当作“用户名”这个数据值处理，那么无论用户输入什么内容，它都不应该改变查询结构。但如果应用采用字符串拼接，输入的语义就可能从“值”变成“语法”。&lt;/p&gt;&#10;&lt;p&gt;SQL 注入成立通常同时需要三个条件：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;用户输入进入 SQL 语句。&lt;/li&gt;&#10;&lt;li&gt;输入能够影响 SQL 的语法结构。&lt;/li&gt;&#10;&lt;li&gt;应用或数据库会把执行结果、错误、状态或时间差异暴露给攻击者。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;第三个条件经常被忽略。没有可观测差异，攻击者通常难以持续判断自己的假设是否正确。因此，防御不只是阻止某个字符，而是同时收紧语法边界、数据库权限、错误输出和日志可见性。&lt;/p&gt;&#10;&lt;h2 id="二常见-sql-注入类型"&gt;二、常见 SQL 注入类型&lt;/h2&gt;&#10;&lt;p&gt;SQL 注入可以有多种分类方式。按照攻击者如何观察结果，通常可以分为以下几类。&lt;/p&gt;&#10;&lt;h3 id="1-联合查询型注入"&gt;1. 联合查询型注入&lt;/h3&gt;&#10;&lt;p&gt;部分数据库支持 &lt;code&gt;UNION&lt;/code&gt;，它可以把两条查询结果合并到同一结果集中。&lt;/p&gt;&#10;&lt;p&gt;联合查询型注入成立的前提通常包括：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;原查询结果能够返回给客户端。&lt;/li&gt;&#10;&lt;li&gt;攻击者能够推断原查询的列数和兼容的数据类型。&lt;/li&gt;&#10;&lt;li&gt;数据库用户的权限允许读取目标数据。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;code&gt;UNION&lt;/code&gt; 并不会让数据库“忽略权限”。如果数据库账号只能读取一张业务表，即便语句结构被改变，也不可能越过数据库本身的权限边界。&lt;/p&gt;&#10;&lt;p&gt;因此，防御不能只关注 &lt;code&gt;UNION&lt;/code&gt; 这个关键词，还要确保：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;应用数据库账号使用最小权限。&lt;/li&gt;&#10;&lt;li&gt;敏感表与业务读取账号隔离。&lt;/li&gt;&#10;&lt;li&gt;查询接口不暴露不必要的字段。&lt;/li&gt;&#10;&lt;li&gt;查询结果在服务端完成权限判断，而不是依赖客户端过滤。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="2-报错型注入"&gt;2. 报错型注入&lt;/h3&gt;&#10;&lt;p&gt;报错型注入依赖应用把数据库错误原样返回给客户端，或者错误信息中包含可观察的表达式结果。&lt;/p&gt;&#10;&lt;p&gt;攻击者真正利用的不是“报错”本身，而是：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;错误内容具有差异性。&lt;/li&gt;&#10;&lt;li&gt;错误内容可以被稳定复现。&lt;/li&gt;&#10;&lt;li&gt;错误内容与攻击者提交的数据存在对应关系。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;从工程角度看，生产环境应做到：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;对用户只返回统一错误码和追踪 ID。&lt;/li&gt;&#10;&lt;li&gt;将详细数据库错误写入受控日志。&lt;/li&gt;&#10;&lt;li&gt;日志中避免记录密码、令牌和完整敏感数据。&lt;/li&gt;&#10;&lt;li&gt;禁止将数据库异常直接拼接到 HTTP 响应。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;即使错误信息不再回显，也不能认为漏洞已经修复。错误隐藏只是降低信息泄漏，不能阻止注入执行。&lt;/p&gt;&#10;&lt;h3 id="3-布尔盲注"&gt;3. 布尔盲注&lt;/h3&gt;&#10;&lt;p&gt;布尔盲注利用应用状态的差异来推断条件是否成立，例如：&lt;/p&gt;</description></item></channel></rss>