Mysql使用SQL的安全问题,Mysql防止SQL注入

    作者:课课家教育更新于: 2017-05-18 13:51:07

      在日常开发过程中,程序员一般只关心SQL是否能实现预期的功能,而对于SQL的安全问题一般都不太重视。实际上,如果SQL语句写作不当,将会给应用系统造成很大的安全隐患,其中最重要的隐患就是SQL注入。本章以MySQL为例,将会对SQL注入以及相应的防范措施进行详细的介绍。

     在日常开发过程中,程序员一般只关心SQL是否能实现预期的功能,而对于SQL的安全问题一般都不太重视。实际上,如果SQL语句写作不当,将会给应用系统造成很大的安全隐患,其中最重要的隐患就是SQL注入。本章以MySQL为例,将会对SQL注入以及相应的防范措施进行详细的介绍。

      1)SQL注入简介

      SQLInjection攻击具有很大的危害,攻击者可以利用它读取、修改或者删除数据库内的数据,获取数据库中的用户名和密码等敏感信息,甚至可以获得数据库管理员的权限。如果能够再利用SQLServer扩展存储过程和自定义扩展存储过程来执行一些系统命令,攻击者还可以获得该系统的控制权。而且,SQLInjection也很难防范。网站管理员无法通过安装系统补丁或者进行简单的安全配置进行自我保护,一般的防火墙也无法拦截SQLInjection攻击。

      2)SQLInjection原理:

      结构化查询语言(SQL)是一种用来和数据库交互的文本语言。SQLInjection就是利用某些数据库的外部接口把用户数据插入到实际的数据库操作语言(SQL)当中,从而达到入侵数据库乃至操作系统的目的。它的产生主要是由于程序对用户输入的数据没有进行严格的过滤,导致非法数据库查询语句的执行。

      如下面的用户登陆验证程序:

      $sql="SELECT*FROMuserWHEREusername='$username'ANDpassword='$password'";

      $result=mysql_db_query($dbname,$sql);

      如果我们提交如下url:

      http://127.0.0.1/injection/user.php?username=angel'or'1=1

      那么就可以成功登陆系统,但是很显然这并不是我们预期的,同样我们也可以利用sql的注释语句实现sql注入,如下面的例子:

      http://127.0.0.1/injection/user.php?username=angel'/*

      http://127.0.0.1/injection/user.php?username=angel'%23

      这样就把后面的语句给注释掉了!说说这两种提交的不同之处,我们提交的第一句是利用逻辑运算,第二、三句是根据mysql的特性,mysql支持/*和#两种注释格式,所以我们提交的时候是把后面的代码注释掉,值得注意的是由于编码问题,在IE地址栏里提交#会变成空的,所以我们在地址栏提交的时候,应该提交%23,才会变成#,就成功注释了,这个比逻辑运算简单得多了。

      3)应用开发中可以采取的应对措施

      1.PrepareStatement+Bind-Variable

      对java和Jsp开发的应用,可以使用prepareStatement+Bind-variable来防止sql注入,另外从PHP5开始,也在扩展的mysqli中支持preparedstatements,所以在使用这类语言作数据库开发时,强烈建议使用prepareStatement+Bind-variable来实现,而尽量不要使用拼接的sql。

      2.同样,使用注释/*或#让后续条件失效也可以防范

      需要注意,PrepareStatement语句是由JDBC驱动来支持的,在使用PrepareStatement语句的时候,仅仅做了简单的替换和转义,并不是MySQL提供了PrepareStatement的特性。对Java、JSP开发的应用,可以使用PrepareStatement+Bind-Variable来防止SQL注入,另外从PHP5开始,也在扩展的MySQLI中支持PrepareStatement,所以在使用这类语言作数据库开发时,强烈建议使用PrepareStatement+Bind-variable来实现。

      3.使用应用程序提供的转换函数

      很多应用程序接口都提供了对特殊字符进行转换的函数,恰当的使用这些函数,可以防止应用程序用户输入使应用程序生成不期望的语句。

      MySQLCAPI:使用mysql_real_escape_string()API调用

      MySQL++:使用escape和quote修饰符

      PHP:使用mysql_real_escape_string()函数(适用于PHP4.3.0版本)。从PHP5开始,可以使用扩展的MySQLI,这是对MySQL新特性的一个扩展支持,其中的一个优点就是支持PrepareStatement

      PerlDBI:使用placeholders或者quote()方法

      RubyDBI:使用placeholders或者quote()方法

      4.自己定义函数进行校验

      如果现有的转换函数仍然不能满足要求,则需要自己编写函数进行输入校验。输入验证是一个很复杂的问题。输入验证的途径可以分为以下几种:

      1.整理数据使之变得有效

      2.拒绝已知的非法输入

      3.只接受已知的合法输入

      因此,如果想要获得最好的安全状态,目前最好的解决办法就是,对用户提交或者可能改变的数据进行简单分类,分别应用正则表达式来对用户提供的输入数据进行严格的检测和验证。

      小编结语:

      更多内容尽在课课家教育!

课课家教育

未登录