zoukankan      html  css  js  c++  java
  • sql注入方式及如何有效避免

    首先提及sql注入这个题目,也许大家会笑笑,觉得这是一件比较低级的攻击方式,但事实上,正是这种不屑,就可能会导致我们网站数据库服务器被攻击,甚至服务器权限都被提走,这种例子,以不鲜见。以下是我在写ORM时sql注入这块,所研究的心得,分享给大家,有可能说的不对,还望大家指正。
     
    先来看下这段sql
    $query = 'SELECT * from user where name =" '.$name.' "';
    这样的sql是我们经常有写的,
     
    然后$name = ' ";delete from user where name="mini -- ";';
    这里' 后面跟一个空格,其实没有,是wile看的更清楚些
     
    如此,这就是是一个sql注入,先截断了我们定义好的"符号,自定义一个"使之于我们定义好的第一个"配对,这样后面的输入串,就非一个sql字符串了,就成功完成sql注入
     
    这种截断引号的注入方式非常常见,当然引号包括单引号于双引号,注入者,必须要完成与sql语句的前一个引号,成功配对,才可能完成注入,这里所说的成功配置指的是,如果 我们这里
    where name =" ' .$name. ' " 注入者,就必须只有用"号才能成功配对,截断本该是字符串的参数,
    如果这块是 where name =' " .$name. " ' 单引号来标识的字符串,那么注入者,只可能用单引号来截断,完成注入
     
    注意上面提到的sql语句,变量拼接语法所涉及到的单引号或双引号,这只是语法形式,拼接完成后,并不会保留
     
    前面说到的是,截断引号方式的注入方法,还有一种是根本不需要截断引号就可以完成注入的方式,
    比如说,如下sql 
     
     $query = 'SELECT * from '.$user.' where name ="zhangyan" ';
     
    其中$user = 'user;delete from user where name="mini";--';
     
    如此这个变量本来就不在一个字符串中,当然,注入时,不用引号配对来截断,直接;结束上一个sql然后写我们的注入sql语句就ok
     
    所以,有效的避免sql注入,并不仅仅是在where条件后。
     
    如何来有效的避免sql注入呢,
     
    这里只说pdo,
     
     
    1.首先pdo提供quote方法,来转义所有的输入的参数
     
    但是使用quote方法需要注意的是,它认为所有输入的参数都是字符串形式输出,所以在拼接sql是,自定义的sql语句就不用在加上 字符串表示符了(单引号或者双引号) 比如说where name ='.$name 
    直接如此就ok 。这里出现的单引号是为了拼接变量的语法形式,并不是字符串中的引号
     
    2.第二种方式是使用prepare来于执行你的sql语句,之后再进行填充你的输入参数,以此来保证不会出现截断整体sql的行为,但并不是说sql语句就完全能够防止sql注入,比如如下
     
    $prepareSql = 'SELECT * from '.$user.' where name =:name';
    $sth = $dbh->prepare($prepareSql);
    $sth->execute(array(':name' => 'zhangsan'));
     
    这里的$user 还是和之前一样 $user = 'user;delete from user where name="mini";--';
     
    这样在预执行的时候,sql注入就已经发生了,网上都说pdo能够防止sql注入,这完全是不对的说法,
     
    其实是否能完全防止sql语句,在于你是怎样用 的,比如说,我们把所有的输入参数,都经过转义后,才拼接到sql语句中,如果是用prepare,我们把所有输入参数都放在execute中,而不是拼接在prepare时,如此就能有效的防范sql注入,
     
    其实关于网上说pdo能够防止sql注入,这句话应该这样说,pdo能够提供给更好的方法来防止sql注入。
     
    其他链接数据库方式,只要做好输入字段的转义工作,也一样能够有效的防止sql的注入
     
    其实所谓字段的转义工作,在sql语句里面,可以参照于pdo的quote方法,吧所有输入字段都当做字符串的输出,并且对所有引号进行转义,这样就能有效的防止,sql语句的注入。
     
     
    3.对整个sql语句进行直接转义。
     
    也许你回这样想,直接对整个sql语句进行转义,这样就开发者就不用单独提出所输入的字段了,也许你没这样想过,但至少我这样想过,但是这种方式是不对的,如下
     
    这里就不以脚本的形式表现了,直接是sql语句形式
    SELECT * from user where name = /"zh/"angyan/"
     
    如果是对整个sql语句进行直接转义,最终发送给mysql的就是这样一句sql。
     
    可以执行下,就知道,失败。
    因为第一次转义和第二次转义的",正好会完成引号的配对,这样后面的字符就不是一种字符串方式了,在此之前,sql语句已经被截断,也就是说这种方式,是不会解决sql注入的。
     
    最后总结一句:想从根本上解决sql注入,其实在于开发者的个人意识,根本上说什么框架不能完美的解决这个问题,即使是从框架方法解决,开发者也必须要把输入数据按照框架的约定放在我特定的规则里面,才能完美的解决sql注入隐患。
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    SQL性能优化:如何定位网络性能问题
    ORACLE 10升级到10.2.0.5 Patch Set遇到的内核参数检测失败问题
    Linux 僵尸进程查杀
    Linux 虚拟机网络适配器从E1000改为VMXNET3
    v$session中server为none与shared值解析
    SQL SERVER导出特殊格式的平面文件
    XtraBackup出现 Can't connect to local MySQL server through socket '/tmp/mysql.sock'
    CentOS 6.6安装Xtrabackup RPM提示缺少libev.so.4()
    SQL Server Replication 中关于视图的点滴
    ORA-00988: missing or invalid password(s)
  • 原文地址:https://www.cnblogs.com/miss-once/p/3231908.html
Copyright © 2011-2022 走看看