萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> mysql語句轉義,sql特殊字符轉義(sql防注入)

mysql語句轉義,sql特殊字符轉義(sql防注入)

在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代碼     

 代碼如下 復制代碼     <?php    
    if (inject_check($_GET['id']))    
    {    
    exit('你提交的數據非法,請檢查後重新提交!');    
    }    
    else    
    {    
    $id = verify_id($_GET['id']); // 這裡引用了我們的過濾函數,對$id進行過濾    
    echo '提交的數據合法,請繼續!';    
    }    
    ?>

但是我們有沒有考慮過post提交的數據,大批量的數據呢?

比如一些字符可能會對數據庫造成危害,比如 ' _ ', ' %',這些字符都有特殊意義,那麼我們如果進行控制呢?還有一點,就是當我們的php.ini裡面的magic_quotes_gpc = off的時候,那麼提交的不符合數據庫規則的數據都是不會自動在前面加' '的,那麼我們要控制這些問題,於是構建如下函數:
PHP代碼      

 代碼如下 復制代碼 <?php        
    function str_check( $str )    
    {    
    if (!get_magic_quotes_gpc()) // 判斷magic_quotes_gpc是否打開    
    {    
    $str = addslashes($str); // 進行過濾    
    }    
    $str = str_replace("_", "_", $str); // 把 '_'過濾掉    
    $str = str_replace("%", "%", $str); // 把' % '過濾掉    
        
    return $str;    
    }    
    ?>

   

這樣你只要再對php.ini與服務器進行安全配置了。

copyright © 萬盛學電腦網 all rights reserved