[转]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/

时间: 2024-10-05 06:07:52

[转]SQL注入漏洞及绑定变量浅谈的相关文章

dedecms SESSION变量覆盖导致SQL注入漏洞修补方案

dedecms的/plus/advancedsearch.php中,直接从$_SESSION[$sqlhash]获取值作为$query带入SQL查询,这个漏洞的利用前提是session.auto_start = 1即开始了自动SESSION会话. 危害: 1.黑客可以通过此漏洞来重定义数据库连接. 2.通过此漏洞进行各种越权操作构造漏洞直接写入webshell后门. 云盾团队在dedemcs的变量注册入口进行了通用统一防御,禁止SESSION变量的传入,修复方法如下: 用文本编辑器打开/mnt/

WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见. 对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避免后知后觉的犯下大错,专门参考大量前辈们的心得,小小的总结一下,欢迎大家拍砖啊 一.跨站脚本攻击(XSS) 跨站脚本攻击的原理 XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该页之时

网站漏洞修复方案防止SQL注入×××漏洞

SQL注入漏洞在网站漏洞里面属于高危漏洞,排列在前三,受影响范围较广,像asp..net.PHP.java.等程序语言编写的代码,都存在着sql注入漏洞,那么如何检测网站存在sql注入漏洞? SQL注入漏洞测试方法 在程序代码里不管是get提交,post提交,cookies的方式,都可以有随意控制参数的一个参数值,通过使用sql注入工具,经典的sqlmap进行检测与漏洞利用,也可以使用一些国内的SQL代码注入工具,最简单的安全测试方法就是利用数据库的单引号, AND 1=1 AND 1=2等等的

PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析

catalog 1. 漏洞描述 2. 漏洞触发条件 3. 漏洞影响范围 4. 漏洞代码分析 5. 防御方法 6. 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/phpcms_v9/index.php?m=member&c=index&a=login dosubmit=1&username=phpcms&password=123456%26username%3d%2527%2bunion%2bselect%2b%25272%2

jdbc mysql crud dao模型 sql注入漏洞 jdbc 操作大文件

day17总结 今日内容 l JDBC 1.1 上次课内容总结 SQL语句: 1.外键约束:foreign key * 维护多个表关系! * 用来保证数据完整性! 2.三种关系: * 一对多: * 一个客户可以对应多个订单,一个订单只属于一个客户! * 建表原则: * 在多的一方创建一个字段,作为外键指向一的一方的主键!!! * 多对多: * 一个学生可以选择多个课程,一个课程也可以被多个学生选择! * 建表原则: * 创建第三张表,第三张表中放入两个字段,作为外键分别指向多对多双方的主键! *

SQL Injection(SQL注入漏洞)

审计前准备: 1.安?php程序(推荐phpStudy) 2.高亮编辑器(推荐 Sublimetext Notepad++) 3.新建一个文本,复制以下变量,这些变量是审计中需要在源码中寻找的 ###################### $_SERVER $_GET $_POST $_COOKIE $_REQUEST $_FILES $_ENV $_HTTP_COOKIE_VARS $_HTTP_ENV_VARS $_HTTP_GET_VARS $_HTTP_POST_FILES $_HTTP

从c#角度看万能密码SQL注入漏洞

以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理. 今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事. 众所周知的万能密码SQL注入漏洞,大家相信很熟悉了. 不懂得简单了解下,懂的大牛直接飘过即可. ***************************************************************************** 当我们用御剑之类的扫描器扫描到某些有这个万能密码SQL注入的漏洞网站后台后, 打开

如此高效通用的分页存储过程是带有sql注入漏洞的

原文:如此高效通用的分页存储过程是带有sql注入漏洞的 在google中搜索“分页存储过程”会出来好多结果,是大家常用的分页存储过程,今天我却要说它是有漏洞的,而且漏洞无法通过修改存储过程进行补救,如果你觉得我错了,请读下去也许你会改变看法. 通常大家都会认为存储过程可以避免sql注入的漏洞,这适用于一般的存储过程,而对于通用分页存储过程是不适合的,请看下面的代码和分析! 一般的通用的分页存储过程代码如下: 通用分页存储过程CREATE PROCEDURE pagination@tblName 

Discuz <= 7.2 SQL注入漏洞详情

Discuz树大招风已成常态,不过对于其他整站程序何尝不是如此?是否曾记得大明湖畔的PHPCMS和DEDCMS万人破的场景,流行整站程序最重要的还是漏洞的快速响应. 0x01 漏洞成因: 在<高级PHP应用程序漏洞审核技术>一文里的"魔术引号带来的新的安全问题"一节里,有提到通过提取魔术引号产生的“\”字符带来的安全问题,同样这个问题在这里又一次完美体现,如下面的代码片段: 1 // foo.php?xigr='ryat 2 3 function daddslashes($