优秀的编程知识分享平台

网站首页 > 技术文章 正文

谈谈 SQL 注入及防范(如何处理sql注入)

nanyue 2025-07-27 22:56:35 技术文章 1 ℃

一句话总结

SQL 注入是一种通过插入恶意 SQL 代码来攻击数据库的技术,防范措施包括使用参数化查询、输入验证和最小权限原则。

详细解析

一、SQL 注入原理与危害

攻击原理(恶意包裹)

SQL 注入是一种安全漏洞,它允许攻击者将恶意的 SQL 代码插入到输入字段中,以操纵数据库。想象应用程序是快递分拣员,数据库是仓库管理员,注入的SQL代码如同恶意包裹。

  • 输入篡改:攻击者在登录框输入' OR 1=1 --,而非正常用户名。
  • 语句拼接:应用程序生成SELECT * FROM users WHERE username='' OR 1=1 --' AND password='xxx'。
  • 指令操控:--注释后续密码验证,OR 1=1使条件恒真 → 绕过认证获取所有用户数据。

典型危害

  • 拖库泄露:窃取用户密码、银行卡号等敏感数据。
  • 越权操作:篡改商品价格、删除数据表(如'; DROP TABLE users;--)。
  • 系统提权:利用数据库存储过程获取服务器控制权(如 MSSQL 的xp_cmdshell)。

二、7 类 SQL 注入攻击详解(附防御方案)

1、联合查询注入(Union Injection)

  • 攻击特征:UNION SELECT 1,password,3 FROM users--
  • 原理:通过 UNION 追加恶意查询,泄露其他表数据。
  • 防御:禁用动态拼接 UNION 语句 + 预编译。

2、布尔盲注(Boolean Blind)

  • 攻击特征:admin' AND SUBSTR(password,1,1)='a' --
  • 原理:根据页面返回 真/假 状态逐字符爆破密码。
  • 防御:统一错误页面(不泄露状态差异)。

3、时间盲注(Time-Based)

  • 攻击特征:1'; IF(SUBSTR(database(),1,1)='a', SLEEP(5),0)--
  • 原理:通过 响应延迟 判断条件真假(如 MySQL 的SLEEP())。
  • 防御:限制 SQL 执行时间 + 预编译。

4、报错注入(Error-Based)

  • 攻击特征:' AND (SELECT 1/0 FROM dual)--
  • 原理:故意触发数据库报错,在错误信息中泄露表结构。
  • 防御:关闭详细报错(生产环境返回通用错误页)。

5、堆叠查询(Stacked Queries)

  • 攻击特征:'; DELETE FROM logs; --
  • 原理:分号;追加多条 SQL 命令(需数据库支持)。
  • 防御:禁用多语句执行(如 JDBC 设置allowMultiQueries=false)。

6、二次注入(Second-Order)

  • 攻击特征:注册用户名admin'--
  • 防御:存储数据时也需过滤(不仅是输入点)。

3、宽字节注入(GBK Bypass)

  • 攻击特征:%bf%27→ 被转义为%bf%5c%27→ GBK 编码解析为縗'吃掉转义符。
  • 防御:统一使用 UTF-8 编码 + 预编译。

三、防御方案:从开发到运维全链路

  1. 预编译(参数化查询)—— 最核心屏障!
//  安全写法(Java 示例)
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, inputUsername); // 输入作为参数绑定,不可篡改 SQL 结构

为何能防注入?

将 SQL 指令与数据分离 → 用户输入始终视为 字符串/数字,而非可执行代码。

  1. 输入过滤与验证
  • 白名单校验:邮箱格式、数字范围等(如正则[a-zA-Z0-9]+)。
  • 黑名单过滤:禁止'、--、UNION等危险字符(需注意绕过风险)。
  1. 最小权限原则
  • 应用账户权限:只授予SELECT/UPDATE必要表,禁用DROP、FILE等危险权限。
  • 数据库用户分离:Web 应用 ≠ DBA 账号!
  1. 纵深防御补充

措施

作用

Web 应用防火墙(WAF)

拦截 UNION SELECT、SLEEP( 等特征 Payload(需定期更新规则)

错误信息模糊化

生产环境返回 系统错误,请联系管理员,而非 Column 'password' not found

定期漏洞扫描

使用 SQLMap 等工具主动检测(尤其新增接口)

修复方案

  • 方案1:参数化查询(PDO)
$stmt = $pdo->prepare("SELECT * FROM products WHERE id = ?");
$stmt->execute([$id]);
  • 方案2:强制类型转换(仅限数字型)
$id = (int)$_GET['id'];  // 字符串注入被阻断

Tags:

最近发表
标签列表