在sql防注入方法我们是说天天都在想各种办法,前段时间公司数据库中存在大量的注入代码,后来发使用了php mysql_real_escape_string 和 mysql_escape_string但怎么还是有问题呢,下面我来分析一下。
具体方法:当sql where 条件等于一串特殊符号时候就容易报错,切断,甚至不执行,或者造成数据库危险.
下面我们简单测试下,创建测试数据,代码如下:
- DROP TABLE IF EXISTS `user`;
- CREATE TABLE `user` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-
- INSERT INTO `user` VALUES ('1', ''\\'''\\\'');
如果我们通过这样的sql语句查询,是查不到的,代码如下:
select * from user where name = "'\'''\'"
必须要经过转义后才能查询,这样才能查询到结果,代码如下:
select * from user where name = "'\\'''\\\'"
有些人可能会想到用模糊查询比如like,但并不是一个很好的解决方案,导致查询不准确,那我们在执行sql之前要进行转义,但是 mysql_real_escape_string 和 mysql_escape_string 这样的转移函数 也并不是所有时候都靠谱。
这里我写了个php函数,代码如下:
- function escape($sql_str) {
- $search = array('\', '/', '"', "'", '|', '-', ';', '[', ']');
- $replace = array('\\', '\/', '\"', "\'", '\|', '\-', '\;', '\[', '\]');
- return str_replace($search, $replace, $sql_str);
- }
在执行sql前进行一次特殊符号转义即可,代码如下:
$sql = escape($sql);
另外对于php手册中get_magic_quotes_gpc的举例,代码如下:
- if (!get_magic_quotes_gpc()) {
- $lastname = addslashes($_POST[‘lastname’]);
- } else {
- $lastname = $_POST[‘lastname’];
- }
语句有四大句:select 、update、delete、insert,那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?
于是我们使用正则就构建如下函数,PHP代码如下:
- <?php
- function inject_check($sql_str)
- {
- return eregi('select|insert|update|delete|'|
- function verify_id($id=null)
- {
- if (!$id) { exit('没有提交参数!'); }
- elseif (inject_check($id)) { exit('提交的参数非法!'); }
- elseif (!is_numeric($id)) { exit('提交的参数非法!'); }
- $id = intval($id);
- return $id;
- }
- ?>
呵呵,那么我们就能够进行校验了,于是我们上面的程序代码就变成了下面的:
- <?php
- if (inject_check($_GET['id']))
- {
- exit('你提交的数据非法,请检查后重新提交!');
- }
- else
- {
- $id = verify_id($_GET['id']);
- echo '提交的数据合法,请继续!';
- }
- ?>
但是我们有没有考虑过post提交的数据,大批量的数据呢?
比如一些字符可能会对数据库造成危害,比如 ' _ ', ' %',这些字符都有特殊意义,那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的magic_quotes_gpc = off的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加' '的,那么我们要控制这些问题,于是构建如下函数:
- <?php
- function str_check( $str )
- {
- if (!get_magic_quotes_gpc())
- {
- $str = addslashes($str);
- }
- $str = str_replace("_", "_", $str);
- $str = str_replace("%", "%", $str);
-
- return $str;
- }
- ?>
这样你只要再对php.ini与服务器进行安全配置了. |