渗透测试之SQL注入(一)
字数 1258 2025-08-15 21:32:10
SQL注入攻击与防御技术详解
一、SQL注入基本概念
SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者利用应用程序对用户输入数据的不当处理,向数据库注入恶意SQL代码,从而执行非授权的数据库操作。
定义
SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,以此来实现欺骗数据库服务器执行非授权的任意查询。
典型示例
$SQL = "select * from '某字段' where id = $id";
当攻击者可以控制$id参数时,就可能构造恶意输入改变SQL语句的原始意图。
二、SQL注入产生条件
- 参数可控:应用程序接受用户提供的可控制参数
- 参数带入查询:这些参数被直接拼接到SQL语句中并执行
三、SQL注入验证方法
以示例代码为例,验证是否存在SQL注入:
- 输入
1',构造的SQL语句变为:
select * from '某字段' where id = 1'
- 由于单引号不匹配导致语法错误,若系统返回数据库错误信息,则证明存在SQL注入漏洞
四、SQL注入分类
- 联合注入(Union Injection):使用UNION操作符合并查询
- 布尔盲注(Boolean-based Blind Injection):根据页面返回的真假判断信息
- 报错注入(Error-based Injection):利用数据库报错信息获取数据
- 时间盲注(Time-based Blind Injection):通过延时响应判断条件真假
- 堆叠注入(Stacked Queries Injection):执行多条SQL语句
- 二次注入(Second-order Injection):存储的恶意输入后被使用
- 宽字节注入(Wide-character Injection):利用字符编码转换漏洞
- Cookie注入(Cookie Injection):通过Cookie参数进行注入
五、SQL注入防御方案
方案一:预编译技术(参数化查询)
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
优点:
- SQL语句结构在预编译时已确定
- 参数值不会改变SQL语义
- 有效防止绝大多数注入攻击
注意:存在极少数预编译绕过技术需要防范
方案二:严格控制数据类型
强类型语言示例(Java/C等):
int id = Integer.parseInt(request.getParameter("id"));
弱类型语言防御(PHP等):
if(is_numeric($_GET['id'])) {
$id = $_GET['id'];
$SQL = "select * from '某字段' where id = $id";
}
方案三:特殊字符转义
MySQL转义示例:
$id = mysqli_real_escape_string($conn, $_GET['id']);
PHP安全函数:
addslashes():基础转义函数mysql_real_escape_string():MySQL专用转义PDO::quote():PDO转义方法
注意:转义函数并非绝对安全,需结合其他防御措施
六、其他防御建议
- 最小权限原则:数据库账户使用最低必要权限
- 输入验证:对用户输入进行严格的白名单验证
- 错误处理:避免显示详细的数据库错误信息
- Web应用防火墙(WAF):部署专业防护设备
- 定期安全测试:进行渗透测试和代码审计
七、总结
SQL注入是Web应用最危险的安全漏洞之一,防御需要从开发阶段开始,采用参数化查询为主,结合输入验证、转义处理等多层防护措施,才能有效保障系统安全。