MySQL--SQL中的安全问题
---恢复内容开始---
1) SQL 注入简介
SQL 注入(SQL Injection) 就是利用某些数据库的外部接口将用户数据插入到实际的数据库操作语言(SQL)当中,从而达到入侵数据库乃至操作系统的目的。他的产生主要是由程序对用户输入的数据没有进行严格的过滤,导致非法数据库查询语句的执行。
2) 应用开发中可以采取的应对措施
- PrepareStatement + Bind-Variable
MySQL 服务器端并不存在共享池概念,所以在 MySQL 上使用绑定变量(Bind Variable)最大的好处主要是为了避免 SQL 注入,增加安全性。
同样,使用注释 /* 或 # 让后续条件失效也可以防范。
需要注意,PrepareStatement 语句是由 JDBC 驱动来支持的,在使用 PrepareStatement 语句的时候,仅仅做了简单的替换和转义,并不是 MySQL 提供了 PrepareStatement 的特性。对 Java、JSP 开发的应用,可以使用 PrepareStatement + Bind-Variable 来防止 SQL 注入,另外从 PHP 5开始,也在扩展的 MySQLI 中支持 PrepareStatement,所以在使用这类语言作数据库开发时,强烈建议使用 PrepareStatement + Bind-variable 来实现。
- 使用应用程序提供的转换函数
很多应用程序接口都提供了对特殊字符进行转换的函数,恰当的使用这些函数,可以防止应用程序用户输入使应用程序生成不期望的语句。
MySQL C API: 使用 mysql_real_escape_string() API 调用
MySQL++: 使用 escape 和 quote 修饰符
PHP: 使用 mysql_real_escape_string() 函数(适用于 PHP 4.3.0版本)。从 PHP 5开始,可以使用扩展的 MySQLI,这是对 MySQL 新特性的一个扩展支持,其中的一个优点就是支持 PrepareStatement
Perl DBI: 使用 placeholders 或者 quote() 方法
Ruby DBI: 使用 placeholders 或者 quote() 方法
- 自己定义函数进行校验
如果现有的转换函数仍然不能满足要求,则需要自己编写函数进行输入校验。输入验证是一个很复杂的问题。输入验证的途径可以分为以下几种:
整理数据使之变得有效
拒绝已知的非法输入
只接受已知的合法输入
因此,如果想要获得最好的安全状态,目前最好的解决办法就是,对用户提交或者可能改变的数据进行简单分类,分别应用正则表达式来对用户提供的输入数据进行严格的检测和验证。