SQL注入——二次注入漏洞

SQL注入——二次注入漏洞

1. 二次注入原理

  • 在第一次插入恶意数据的时候,只是对其中的特殊字符进行了转义,在写入数据库的时候还是原来的字符,但是数据本身是包含恶意内容的。
  • 在将数据存入到数据库中之后,开发者认为数据是可信的,在下一次需要进行查询的时候,直接从数据库中取出恶意数据,没有进行进一步的校验和处理,这样就造成了SQL二次注入。

2. 二次注入需要具备的两个条件

  1. 用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)
  2. 数据库对自己存储的数据非常放心,直接取出恶意数据给用户。

3. 二次注入实例

以sqli-labs靶场的less-24为例子

访问目标网站

image-20231030201147885

点击下方new user click here? 注册两个新用户

用户一:

wuhu		# 账号
wuhu		# 密码

image-20231030201325482

用户二:

wuhu'#		# 账号
qwerty		# 密码

image-20231030201353267

注册完成后,数据库中两个账户的内容

image-20231030201419044

注册完成后登录wuhu’#,提示修改新的密码:

image-20231030201545587

输入旧密码qwerty 新密码654321 后点击reset

image-20231030201612335

此时,wuhu’#的密码没有被修改,wuhu的密码被修改为654321

image-20231030201711733

最终修改密码语句如下:

$sql = "UPDATE users SET PASSWORD='654321' where username='wuhu'#'and password=qwerty

说明:#号把后面的都注释掉了,所以sql语句最终的意思是修改wuhu的密码为654321。

4. 总结

  • 第一次进行数据库插入数据的时候,仅仅只是使用了addslashes或者是借助get_magic_quotes_gpc对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。
### SQL 二次注入原理 SQL 二次注入是一种特殊的 SQL 注入攻击形式,其核心在于恶意数据被存储在数据库中,并在后续操作中未经过充分验证或过滤而被执行。具体来说,这种攻击发生的原因可能是应用系统在初次接收到用户输入时已经对其进行了安全性处理,但当这些已存储的数据再次参与动态 SQL 查询构建时,未能重新对其进行防护[^2]。 #### 攻击过程描述 1. **初始输入阶段**:攻击者向目标系统提交含有恶意 SQL 片段的内容。此时,该内容可能会经历初步的安全检测(如转义特殊字符),随后存入数据库。 2. **后续利用阶段**:当程序从数据库提取之前保存的恶意数据并将其嵌套至新的 SQL 查询语句中时,如果缺乏必要的清理机制,则可能导致原始恶意代码得以执行,从而实现对系统的非法访问或者破坏行为[^3]。 --- ### 防御方法 针对上述提到的 SQL 二次注入风险,可以从以下几个方面着手加强防范: #### 数据校验与清洗 - 对于任何来源于外部环境的信息,在写入持久化层前都应实施严格的格式校验以及敏感符号替换工作; - 即使某些字段看似无害也需要谨慎对待,因为它们有可能在未来某个时刻成为潜在威胁源的一部分[^1]。 #### 参数化查询技术的应用 采用预编译好的参数占位符方式来代替传统的字符串拼接法构造SQL指令是非常有效的手段之一 。这种方法能够确保即使存在危险成分也不会影响最终形成的合法命令结构 ,因为它会自动把所有传进去 的变量当作纯文本看待而不是可解析语法单元 : ```java PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM users WHERE username=? AND password=?"); pstmt.setString(1, userInputName); pstmt.setString(2, userInputPassword); ResultSet rs = pstmt.executeQuery(); ``` 以上例子展示了如何通过 Java 中 PreparedStatement 类型对象来进行安全可靠的数据库交互操作 。 #### 输出编码控制 除了重视前端收集来的资料之外 , 还要特别留意那些由内部生成却又要反馈给用户的项目 . 如果有必要的话 可考虑运用 HTML 实体转换等功能 来阻止可能出现跨站点脚本 (XSS) 或其他类型的漏洞传播路径 同样适用于防止二次 sql injection 发生的情况 下面给出 python flask 框架下的简单示范 : ```python from markupsafe import escape @app.route('/search') def search(): query = request.args.get('q', '') safe_query = escape(query) # Escape potentially harmful characters. results = db.execute(f"SELECT * FROM entries WHERE title LIKE '%{safe_query}%'").fetchall() return render_template('results.html', results=results) ``` 这里借助 `markupsafe` 库里的 `escape()` 函数实现了基本层面的文字序列保护作用 . #### 定期审计日志审查制度建立 最后一点建议便是养成良好习惯定期查看服务器端产生的各类记录文件寻找异常模式迹象以便及时发现隐患所在 并采取相应补救措施减少损失扩大可能性的同时提高整体网络安全水平 [^3]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来日可期x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值