XSS過濾
輸入類可以自動的對輸入數據進行過濾,來阻止跨站腳本攻擊。如果你希望在每次遇到 POST 或 COOKIE 數據時自動運行過濾,你可以在 application/config/config.php 配置文件中設置如下參數:
$config['global_xss_filtering'] = TRUE;
或者自動設置get和post方法的第二個參數為true,則對輸入的參數進行XSS過濾,注意只是XSS過濾,並不會對SQL注入進行有效的防范。
$this->input->post("userName",TRUE);
防SQL注入
防SQL注入的原理主要是過濾判斷條件(WHERE或LIKE)中字段的特殊字符(',\,%,_.....等),在特殊字段前加上轉義字符等操作,使數據庫能正常執行SQL,不會發生DatabaseError的問題
1、數字類型數組可以通過判斷是否是數字和位數進行篩選,避免執行到數據庫那里遇到問題
2、如果是純字符串不需要特殊字符插庫的話,可以判斷如果有特殊字符的話就不繼續執行,避免執行到數據庫那里遇到問題
3、如果執行到數據庫這里,需要對判斷條件的字段進行過濾轉義
這里說一下CI框架中轉義的方式:
1、直接使用CI的AR(Active Record)的數據庫CURD方式去處理
(1)、插入:$this->db->insert("tableName",$insertArray);
(2)、刪除:$this->db->where("id",$id)->delete("tableName");
(3)、更新:$this->db->where("id",$id)->update("tableName",$updateArray);
(4)、查詢:$this->db->where("id",$id)->select("id,name,age")->get("tableName");
*這里有個細節需要get一下,where里面寫sql自定義字符串時(下面的第4種方式),如where("id = '{$id}'"),where這一塊並不算是AR類的操作,換言之也就是不會自動進行過濾轉義的
*下面的4方式,自定義字符串方式雖然不是AR類寫法,不支持自動過濾轉義,但是可以支持where中寫or的寫法,相對靈活,如果遇到有or的情況,需要在那之前把判斷的字段先轉義過來,不管是用CI自己的方式(詳見最下方的轉義查詢),還是自己封好的demo函數都可以
-
簡單的 key/value 方式:
$this->db->where('name', $name); // Produces: WHERE name = 'Joe'注意自動為你加上了等號。
如果你多次調用該方法,那么多個 WHERE 條件將會使用 AND 連接起來:
$this->db->where('name', $name); $this->db->where('title', $title); $this->db->where('status', $status); // WHERE name = 'Joe' AND title = 'boss' AND status = 'active' -
自定義 key/value 方式:
為了控制比較,你可以在第一個參數中包含一個比較運算符:
$this->db->where('name !=', $name); $this->db->where('id <', $id); // Produces: WHERE name != 'Joe' AND id < 45 -
關聯數組方式:
$array = array('name' => $name, 'title' => $title, 'status' => $status); $this->db->where($array); // Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'你也可以在這個方法里包含你自己的比較運算符:
$array = array('name !=' => $name, 'id <' => $id, 'date >' => $date); $this->db->where($array); -
自定義字符串:
你可以完全手工編寫 WHERE 子句:
$where = "name='Joe' AND status='boss' OR status='active'"; $this->db->where($where);
轉義查詢
在提交數據到你的數據庫之前,確保先對其進行轉義是個非常不錯的做法。 CodeIgniter 有三個方法來幫你做到這一點:
-
$this->db->escape() 這個函數會檢測數據類型,僅轉義字符串類型的數據。 它會自動用單引號將你的數據括起來,你不用手動添加:
$sql = "INSERT INTO table (title) VALUES(".$this->db->escape($title).")"; -
$this->db->escape_str() 這個函數忽略數據類型,對傳入的數據進行轉義, 這個方法並不常用,一般情況都是使用上面的那個方法。方法的使用代碼如下:
$sql = "INSERT INTO table (title) VALUES('".$this->db->escape_str($title)."')"; -
- $this->db->escape_like_str() 這個函數用於處理 LIKE 語句中的字符串,
-
這樣,LIKE 通配符('%', '_')可以被正確的轉義。
$search = '20% raise'; $sql = "SELECT id FROM table WHERE column LIKE '%" . $this->db->escape_like_str($search)."%' ESCAPE '!'";
*轉義這里有一點需要get下,$this->db->escape()在使用這個函數之后,變量會自動在兩側加上單引號'',同時也會在里面進行自動的過濾
*比如會把abc變成'abc' , 也會把a'bc變成'a\'bc'的,所以在寫進where的sql自定義字符串中時,就不要再加單引號了,那樣就會有兩個單引號在變量外邊(''abc'')
*$this->db->escape_str()在使用這個函數之后,變量不會自動在兩側加上單引號'',只會在里面進行自動的過濾
*比如會把abc還是abc , 也會把a'bc變成a\'bc的,所以在寫進where的sql自定義字符串中時,和以前用法是一樣的
