[转]SQL注入漏洞及绑定变量浅谈
1、一个问题引发的思考
大家在群里讨论了一个问题,奉文帅之命写篇作文,且看:
String user_web = "user_web"
String sql = "update user set user_web="+user_web+" where userid=2343";
大家看看这条sql有没有问题,会将user_web字段 更新成什么?
问题的结论是:执行后的记录结果跟执行前一样,(执行时的sql语句为
update user set user_web=user_web where userid=2343,
user_web字段值被update为自己原有的值),这与作者的本意想违背却很难被发现有问题。原来的语句漏掉了一对单引号,正确的写法应该是:
String sql = "update user set user_web='"+user_web+"' where userid=2343";
用这种写法将变量值传递到sql语句中,意图是达到了,但不是好的方式,理由如下:
1.可读性差。单引号双引号混杂(试想有多个变量的情况,再想下如果稍一不慎在前面的单引号双引号直间多个空格又会怎样?)
2.会造成潜在的性能问题和sql注入漏洞(对测试代码而言,这两点可能要求不高,但养成良好的编码习惯还是很重要的)
下面以非专业人员的角度大致分析下 ‘”+变量+”‘(未采用绑定变量方式)这种方式组织sql为什么会造成潜在的性能问题和sql注入漏洞问题
2、性能问题
Sql代码不采用绑定变量的方式可能会造成性能问题,表现在以下两个方面:
1.导致相同的测试计划被重复执行
sql语句的执行过程分几个步骤:语法检查、分析、执行、返回结果。当一条sql通过语法检查后,会在共享池里寻找是否有跟其相同的语句,如果有则用已有的执行计划执行sql语句,如果没有找到,则生成执行计划,然后才执行sql语句。可见,后者比前者多了额外的步骤,消耗了额外的CPU,并导致sql总体执行时间延长,而这里的关键就是“共享池中是否有相同的sql语句”。
String username="test_xx";
String sql = "SELECT id,nick FROM user WHERE username='"+username+"'";
以这样的方式传递到数据库中的sql为
SELECT id,nick FROM user WHERE username='test_xx'
假定这个语句是第一次执行,会生成执行计划。当变量发生变化时(username=”test_yy”),数据库又接收到这样的语句
SELECT id,nick FROM user WHERE username='test_yy'
Oracle不认为以上两条语句是相同的,因此又会生成执行计划,而这两者的执行计划是一样的(做了重复的工作)
2.导致共享池中的sql语句过多,加速SQL老化,造成共享池内部结构频繁维护。
如果一个某段程序未采用绑定变量的方式而又被大量调用,会导致共享池中不同的sql语句增多,而重用性极低,导致共享池内命中率下降。随着sql数量过多,一些语句逐渐老化,最终被清理出共享池。 而维护共享池内部结构要消耗大量的CPU和内存资源。
3、Sql注入漏洞
不采用绑定变量的方式可能会造成sql注入漏洞,本文仅仅通过示例说明为什么会造成sql注入漏洞,不对攻击方式、攻击类型等展开。以一个用户验证为例。
String sql = "SELECT id,nick FROM user WHERE username='"+username+"'
AND password='"+password+"'";
以上代码接收从客户端传来的username和password变量,在数据库中查询验证。假设攻击者从客户端传的username为任意值(如test)password变量为
1′ or ‘1′=’1
此时替换变量后的sql变为
SELECT id,nick FROM user WHERE username='test' AND password='1' or '1'='1'
这样得到的结果就是user表中的所有数据了。
4、使用绑定变量
以上两种问题的解决方式就是使用绑定变量,就是在sql语句里不直接写变量,而是用占位符,在执行时再把占位符替换为具体的变量值。代码片段如下
String sql = "SELECT id,nick FROM user WHERE username=? AND password=?";
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
一些常用Jdbc工具对此进行了良好的封装,使代码更加简洁。比如Spring的SimpleJdbcTemplate
String sql = "SELECT id,nick FROM user WHERE username=? AND password=?";
jdbcTemplate.queryForList(sql,username,password);
上面 ?的做占位符的形式被称为顺序占位符,在传参数值时必须注意顺序对应,还有一种是名称占位符。同样以SimpleJdbcTemplate为例说明.
String sql = "SELECT id,nick FROM user WHERE username=:name AND password=:pass";
map.put("pass",password);
map.put("name",username);
jdbcTemplate.queryForList(sql,map);
上面的例子中的:name和:pass就是名称占位符,在执行时sql时再绑定变量。
iBatis中有两种占位符,#name# 和$name$两种方式,需要注意的是前者会在执行sql时绑定变量,而后者直接是替换为变量值,所以后者仍然存在sql注入漏洞问题。
5、未尽话题
接口测试要不要检查sql注入漏洞问题?这个问题值得商榷,个人认为通过常规的用例设计检查sql注入漏洞恐怕不太可行(工作量太大效果不一定好),如果要做的话可借助(或自己开发)一些工具,通过扫描静态代码再人工排查的方式进行。另外如果这项工作进行的太细致,恐怕会跟安全测试的工作重叠太多,当然如果在测试过程中发现开发的代码存在sql注入漏洞(这往往跟开发者编码习惯有关)问题,一定不要放过,进行排查还是很有必要的。
转自:http://kb.cnblogs.com/page/55287/
[转]SQL注入漏洞及绑定变量浅谈的更多相关文章
- dedecms SESSION变量覆盖导致SQL注入漏洞修补方案
dedecms的/plus/advancedsearch.php中,直接从$_SESSION[$sqlhash]获取值作为$query带入SQL查询,这个漏洞的利用前提是session.auto_st ...
- SQL 注入漏洞浅研究学习
SQL注入漏洞:Web安全方面最高危的漏洞,SQL漏洞威胁着网站后台数据的安全问题. 网上常说“万能密码”,这个万能密码则就是利用了SQL注入漏洞: ' or 1=1 -- 上述的万能密码输入在用户登 ...
- 浅谈SQL注入漏洞以及防范策略
--HeShiwei 2014-5-15 什么是SQL注入 SQL注入,指的是用户通过向登录框输入恶意字符,利用代码的字符串拼接漏洞进行网站注入攻击,最终导致整个网站用户表信息泄露的攻击方式.黑客就是 ...
- WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案(转)
对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...
- WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案
对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避 ...
- SQL注入漏洞技术的详解
SQL注入漏洞详解 目录 SQL注入的分类 判断是否存在SQL注入 一:Boolean盲注 二:union 注入 三:文件读写 四:报错注入 floor报错注入 ExtractValue报错注入 Up ...
- SQL注入漏洞详解
目录 SQL注入的分类 判断是否存在SQL注入 一:Boolean盲注 二:union 注入 三:文件读写 四:报错注入 floor报错注入 ExtractValue报错注入 UpdateXml报错注 ...
- 防sql注入之参数绑定 SQL Injection Attacks and Defense 预处理语句与存储过程
http://php.net/manual/zh/pdo.prepared-statements.php 预处理语句与存储过程 很多更成熟的数据库都支持预处理语句的概念.什么是预处理语句?可以把它看作 ...
- 从c#角度看万能密码SQL注入漏洞
以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理. 今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事. 众所周知的万能密码SQL注入漏洞, ...
随机推荐
- XILINX之RAM使用指南(加个人总结)
先加点自己的总结:真双口RAM可以在任意时间访问任意地址,两个端口的地址是一样的,即共享内存和地址.这就会带来一个问题:同时读写一个地址会发生冲突.基于这个点矛盾就要设置限制条件,这个在Xilinx ...
- 【Android】3.20 示例20—全景图完整示例
分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 一.简介 1.展示全景图的方式 有以下展示全景图的办法: (1)利用地理坐标展示全景图. (2)利用全景图ID ...
- haproxy 配置mysql的代理
应用场境,是如果mysql服务器没有外网的,需要一个有外网的代理服务器做代理,这时就可以用haproxy做个四层的代理: listen mysql bind mode tcp balance roun ...
- 递增和递减进度条CCProgressTimer
关于scheduleUpdate看这篇即可 http://www.benmutou.com/blog/archives/56 接下来是示例代码: CCSize size = CCDirector::s ...
- 在开发中写一些tool来提升自己的效率
比如说,我在调试一个web-project的时候,因为eclipse默认编译好的.class文件放在/build/classes/中,但是我希望随时把这些class文件放到/WEB-ROOT/WEB- ...
- Python IDLE快捷键【转载合集】
转载自:http://www.douban.com/note/212321426/ 编辑状态时:Ctrl + [ .Ctrl + ] 缩进代码Alt+3 Alt+4 注释.取消注释代码行Alt+5 A ...
- 1326: The contest(并查集+分组背包)
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1326 殷犇有很多队员.他们都认为自己是最强的,于是,一场比赛开始了~ 于是安叔主办了一场比赛,比赛 ...
- 浅谈C#委托和事件【转】
委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...
- SVN导入maven项目
在项目中,曾今遇到过这种问题,用eclipse将项目从svn下载下来,maven去自动下载jar包怎么都报错,本来时间就很紧张, 还特么遇到这种坑爹的问题.不过,整了我一天,最后终于在同事的帮助下,搞 ...
- linux命令--vi,vim
进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件.并将光标置于第n行首 vi + filename :打开文件.并将光标置 ...