SQL常犯错误---SQL注入以及解决之道

以前光听说过SQL注入攻击,并不明白是怎么回事,今天看《SQL反模式》的时候看到了,我承认我弄懂怎么回事的时候很不厚道的笑了,呵呵,都是人才啊!
先说说定定义吧:SQL注入攻击指的是来自用户的数据作为SQL语句的一部分参与动态SQL语句的拼接。就这么简单,来自用户的数据指的是这部分数据并不是来自程序内部而是来自外部,可能是WEB表单,或是第三方的报文等。
举个很简单的例子:
update employer_salary set salary = 1000000 where employer_id = v_employer_id;
仔细看看这个语句, v_employer_name 是个变量, 比如说来自于web表单。
这条语句有没有问题,功能上没问题,但是确实有被SQL 注入的危险。 假如这个v_employer_id 的值为 38 OR TRUE 那么这个SQL 变成什么样了?
update employer_salary set salary = 1000000 where employer_id = 38 OR TRUE;
看到了吧, 这条SQL 现在变成了把所有人的工资都变成1000000, 爽吧。还有更可怕的,假如 v_employer_id 的值为: 38;delete from employer_salary;  
现在这条SQL变什么样了?
update employer_salary set salary = 1000000 where employer_id = 38; delete from employer_salary;
结果是所有的记录都被干掉了, 厉害了把! 

我是觉得很厉害了。 这么厉害的攻击有什么办法应对呢, 三种方法,都不轻松。


1.  检查输入的内容。

这个不多说了, 如果输入要求的是integer 那么在接受到输入后检查下是不是integer。 注入此类,越详细越好。


2. 参数化动态的部分
这个理解起来稍微有点麻烦,比如说后台有个SQL语句是这样的
update employer_salary set salary = 1000000 where employer_id = ?
看到没,原本使用变量的地方使用了“?” 作为占位符。 但是这样怎么就有用了呢,我难道不照样输入“38 OR TRUE” 这样的参数来替换占位符吗? 还真不行,原理是这样的,如果是使用占位符以供参数替换的SQL语句RDBMS会预先解析这个SQL,并认为SQL 的结构已经固定了,可变的只是参数。 所以当我们输入“38 OR TRUE” 这样的参数,如果employer_id 是个int类型的列, 会得到一个错误信息。 简单说就是只是将参数的内容当做是参数而不会将参数的部门内容误认为是SQL的结构语句了,因为SQL的结构语句已经预解析过了,固定了。不知道说明白了没,多读几遍应该还是能明白的。

这个方式的缺点在于SQL语句是不允许将SQL结构上的部分当错参数传入的, 如表名, 列名 , 排序顺序:ASC, DESC。


3. 将用户输入和SQL代码隔离
什么意思呢,简单说就是不在将用户的输入原模原样的加入到SQL中,而是要经过一个mapping。 当然这种方式是用来弥补第二种方式的不足的,比如说用户想决定order by 的顺序, 他可以在WEB 中输入“up”/"down", 但是我不会原样拼到SQL中,如果用户输入了“down; DROP ...” 我就又被注入攻击了,怎么办呢,我会在程序中方已个map表,存放用户输入和最终拼接内容的mapping关系:
down---ASC
up---DESC
如果用户输入的不是"down"或者"up"我会报错,或者弄一个默认值如“ASC”, 其实说白了也是一种检查,但是确实是将用户和真正的代码隔离了。


好了,说了这么多就结束了,SQL注入确实是个天才的想法,呵呵。








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值