当前位置: 首页 > news >正文

SQL注入攻击的方法与预防

一、SQL注入概述

SQL 注入SQL Injection)是一种常见且危险的 Web 应用程序安全漏洞,攻击者通过在用户输入中注入恶意 SQL 代码,从而操纵后端数据库执行。

这种攻击可能会导致数据泄露、数据篡改、权限提升甚至整个数据库的破坏。

二、SQL 注入的工作原理

SQL 注入的核心原理是"数据与代码的混淆"。

当应用程序将用户输入直接拼接到 SQL 查询中而没有适当处理时,攻击者可以插入特殊的 SQL 语法,改变原始查询的意图。

例如:

-- 原始查询
SELECT * FROM users WHERE username = 'user_input'-- 攻击者输入: admin' --
-- 最终查询
SELECT * FROM users WHERE username = 'admin' -- '

三、SQL注入的常见攻击方法

1. 基于联合查询的注入

使用 UNION 操作符将恶意查询附加到原始查询上,获取其他表的数据。

-- 原始查询
SELECT name, email FROM users WHERE id = user_input-- 攻击者输入: 1 UNION SELECT username, password FROM admin_users

2. 布尔盲注

攻击者通过真/假条件判断来推断数据库类型和版本信息

-- 判断数据库类型
' AND 1=CONVERT(int, @@version) --

3. 时间盲注

通过条件语句和延时函数判断条件真假。

-- 如果响应延迟5秒 → 数据库名的第一个字符是'a'
' AND IF(SUBSTRING(database(),1,1)='a', SLEEP(5), 0) --

4. 堆叠查询注入

执行多个 SQL 语句,实现更复杂的攻击。

-- 攻击者输入: 1; DROP TABLE users --

通过以上的注入手段,我们发现这种通过把外部传入的参数直接拼接成 SQL 的方式非常危险!

四、SQL 注入的预防措施

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

PreparedStatement 的 SQL 语句是固定的,不是直接拼出来的方式,而是将外界传进来的条件当作参数 set 进去,这样就避免了 SQL 注入的风险。
Java JDBC 示例:

```sql
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
```

MyBatis 示例:

<!-- 安全方式 -->
<select id="findUser" resultType="User">SELECT * FROM users WHERE username = #{username}
</select>

2. 使用ORM框架

现代 ORM 框架(如Hibernate、JPA)通常内置了 SQL 注入防护。

// JPA示例
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);

3. 输入验证与过滤

  • 白名单验证:只允许特定格式的输入(如邮箱、电话号码)
  • 黑名单过滤:过滤特殊字符(如单引号、分号)

4. 最小权限原则

数据库用户应仅具有必要的最小权限,避免使用 root 或 sa 账户连接数据库。

五、MyBatis中安全使用动态SQL

大家都知道 MyBatics 有两种占位符:${}#{}
但是我们应该避免在 MyBatis 中使用 ${} 进行字符串替换,可能会引发 SQL 注入风险。

而使用 #{} 可以避免 SQL 注入,原因其实就是 #{} 的底层就是预编译语句 PreparedStatement 。

如下所示:

<select id="findUsers" resultType="User">SELECT * FROM users<where><if test="name != null">AND name = #{name}</if><if test="ids != null">AND id IN<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach></if></where>
</select>

六、总结

通过采用预编译语句、ORM 框架、输入验证与过滤和最小权限原则等防御措施,可以有效地防止这类攻击。

所以我们开发人员应当始终对用户的输入保持警惕,遵循安全的编码规范,定期进行安全测试和代码审计,以确保应用程序的安全性。

相关文章:

  • C++内存学习
  • 【从零开始学习QT】信号和槽
  • 《P3959 [NOIP 2017 提高组] 宝藏》
  • 系统初步设计方案/系统建设方案
  • C++修炼:位图和布隆过滤器
  • 6、在树莓派上安装 NTP(Network Time Protocol )服务的步骤
  • esp-idf ubuntu环境配置
  • 基于谷歌ADK的智能客服系统简介
  • duilib图片属性中corner属性九宫格拉伸说明
  • 深入了解Vue2和Vue3的响应式原理
  • 线程与进程
  • CppCon 2014 学习:C++ in Huge AAA Games
  • 美业+智能体,解锁行业转化新密码(2/6)
  • C语言进阶--程序的编译(预处理动作)+链接
  • Java实现中文姓名转拼音生成用户信息并写入文件
  • Java求职者面试指南:DevOps技术栈深度解析
  • NodeJS全栈开发面试题讲解——P7 DevOps 与部署和跨域等
  • LangChain-结合GLM+SQL+函数调用实现数据库查询(三)
  • 【配置指南】Dify部署超全配置参考手册
  • Python 训练营打卡 Day 32-官方文档的阅读
  • 企石网站建设/公众号怎么做文章推广
  • 廊坊住房与建设委员会网站/专门发广告的app
  • 国内做网站大公司/百度品牌推广
  • zblog做的商城网站/花关键词排名系统
  • 网站 英语/百度怎么发帖子
  • 崇左市住房和城乡建设局网站/最新新闻消息