🗄️ 第七章 用于保护数据库的基础知识-故障恢复与安全措施
📄 一句话概括

SQL 注入=把恶意 SQL 混进用户的输入里骗数据库执行——防线三件套:参数化查询(治本)、权限最小化(限损)、输入校验(辅助)。

📝 本节和前面几节的关系

全章收官,也是最经典的数据库攻击:它把 7-3「人的威胁·有意之为」落到了具体手法上,并一举回收 6-4(最小权限)、3-2(SQL 语法)、1-6(SQL 是声明式语言)三笔账——理解 SQL 的语法,才能理解「拼接 SQL」为什么危险。

一、注入是怎么发生的

登录页输入:用户名 = '波仔'   密码 = '123456'
程序拼接 SQL:"SELECT * FROM users WHERE name='波仔' AND pwd='123456'"

攻击者在密码框输入:' OR '1'='1
拼出来变成:
SELECT * FROM users WHERE name='波仔' AND pwd='' OR '1'='1'
── '1'='1' 永远为真 → 密码形同虚设,直接登录!

根因:用户输入被当成了 SQL 代码参与拼接——数据与代码混在一条字符串里。

二、防线三件套

  1. 参数化查询(治本):SQL 骨架与数据分开传送,数据库把输入永远当「数据」不当「代码」——注入当场失效
  2. 权限最小化(限损):注入成功也只拿到网站账号的权限(6-4)——只有 SELECT,偷看删不了库
  3. 输入校验(辅助):长度、格式白名单——但不能只靠它(绕过手法层出不穷)

三、动手 Demo:亲眼看一次注入与一次拦截

-- 建个迷你用户表
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, pwd TEXT);
INSERT INTO users VALUES (1, '波仔', '123456');

-- ① 程序拼接思路(示意):密码框输入 ' OR '1'='1 时
-- 等效执行:
SELECT * FROM users
WHERE name = '波仔' AND pwd = '' OR '1'='1';
-- → 返回波仔那一行:密码错了也算登录成功!(注入得手)

-- ② 参数化查询思路:骨架与数据分离
-- SELECT * FROM users WHERE name = ? AND pwd = ?
-- 参数:('波仔', "' OR '1'='1")
SELECT * FROM users
WHERE name = '波仔' AND pwd = ''' OR ''1''=''1';
-- → 0 行:那串恶意输入被当成一个「怪密码」查找,注入失效!

【准备块】在线 SQLite 运行器即可;核心体会=②里恶意文本变成了一整个待查找的字符串字面量。

四、30 秒实验

把拼接 SQL 想成填快递单:参数化=先印好表格再填字,你在「姓名」栏写什么都是姓名;拼接=把你的话直接抄进指令书——你写「把包裹扔了」,快递员就真扔。表格(参数化)才是安全边界。

五、常见误区

自测三问 1. 注入的根因是什么?(用户输入被当 SQL 代码拼接执行——数据与代码混在一起) 2. 为什么参数化查询是治本?(SQL 骨架与数据分开传送,输入永远是数据不是代码) 3. 权限最小化在注入场景的作用?(注入成功也只拿到网站账号权限——最小化破坏半径)

相关笔记