在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呵呵,那麼我們就能夠進行校驗了,於是我們上面的程序代碼就變成了下面的:
PHP代碼
代碼如下 復制代碼 <?php但是我們有沒有考慮過post提交的數據,大批量的數據呢?
比如一些字符可能會對數據庫造成危害,比如 ' _ ', ' %',這些字符都有特殊意義,那麼我們如果進行控制呢?還有一點,就是當我們的php.ini裡面的magic_quotes_gpc = off的時候,那麼提交的不符合數據庫規則的數據都是不會自動在前面加' '的,那麼我們要控制這些問題,於是構建如下函數:
PHP代碼
這樣你只要再對php.ini與服務器進行安全配置了。