一次sql注入引发的多个mysql进程锁住的问题(针对myisam)

以前碰到过一个sql注入式攻击引发大量mysql进程被锁住的例子,现在分享给大家。当时数据表用的是myisam存储引擎。

 

基本知识点:

InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,而MyISAM支持的是表级锁。

 

对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;MyISAM表的读操作与写操作之间,以及写操作之间是串行的。

 

模拟示例:

create table myisam_test(id int primary key not null auto_increment,

v1 varchar(64),

v2 varchar(64)) engine=myisam;

 

insert into myisam_test(v1,v2) values('a','b');

多次执行 insert into myisam_test(v1,v2) select concat(v1,'a'),concat(v2,'b') from myisam_test;

 

 

接下来大boss上场了,就是那段被注入的sql

 

select * from myisam_test  where (id=1000) xor(if(453=453,sleep(5),0)) limit 1;

 

由于程序没有过滤非法参数值(xor(if(453=453,sleep(5),0))),sql一直在执行中,但是读操作不会阻塞其他用户对同一个表的读请求因此执行另一条select后会立刻返回执行结果:

 


 

但是假如我们在此时执行写操作呢?见下图:

 


  



 

读操作会阻塞对同一表的写请求,而写操作会阻塞其他用户对同一表的读和写操作,因此在这里后续的update和select语句都因为id=8的那个process而一直处于等待状态,无法返回结果。

 

我们kill掉那条被注入的sql执行进程,锁立刻释放,后续的sql立刻返回结果。

 

Sql注入式攻击再配合myisam的特性,导致大量进程处于等待状态,因此我们编程时基本的安全意识还是要有的,如净化用户输入,如使用如下参数化查询而不是将参数拼接到sql语句中:

PreparedStatement prep = conn.prepareStatement("SELECT * FROM  myisam_test WHERE v1=? AND v2=?");

prep.setString(1, value1);

prep.setString(2, value2);

prep.executeQuery();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值