sql注入就是利用某些數據庫的外接接口將用戶數據插入到實際的數據庫操做語言當中,從而達到入侵數據庫乃至操做系統的目的。在安全領域,咱們永遠不要信任用戶的輸入
,咱們必須認定用戶輸入的數據都是不安全的,咱們都須要對用戶輸入的數據進行過濾處理。沒有(運行時)編譯,就沒有注入。
因此從根本上防止上述類型攻擊的手段,仍是避免數據變成代碼被執行,時刻分清代碼和數據的界限。而具體到SQL注入來講,被執行的惡意代碼是經過數據庫的SQL解釋引擎編譯獲得的,因此只要避免用戶輸入的數據被數據庫系統編譯就能夠了。
與其餘數據庫不一樣,MySQL能夠運行在不一樣的SQL Mode(SQL服務器模式)下,而且能夠爲不一樣客戶端應用不一樣模式。這樣每一個應用程序能夠根據本身的需求來定製服務器的操做模式。模式定義MySQL應支持哪些SQL語法,以及應執行哪一種數據驗證檢查。這有點相似於apache配置不一樣級別的錯誤日誌,報告哪些錯誤,又不報告哪些錯誤。php
//php代碼
$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO `table` (`column`) VALUES ('{$unsafe_variable}')");複製代碼
當post中代碼以下時候:html
value'); DROP TABLE table;--複製代碼
查詢代碼變成mysql
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')複製代碼
這樣會直接刪除table表,你的數據被破壞了。sql
方法一
prepareStatement+Bind-Variable:SQL語句和查詢的參數分別發送給數據庫服務器進行解析。
對於php來講有兩種實現方式。數據庫
//使用PDO(PHP data object)
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
//使用mysql擴展-mysqli
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}複製代碼
方式二
對查詢語句進行轉義(最多見的方式):使用應用程序提供的轉換函數。
|應用|函數|
|--------|
|MySQL C API|mysql_real_escape_string()|
|MySQL++|escape和quote修飾符|
|PHP|使用mysql_real_escape_string()(適用於PHP4.3.0之前),以後可使用mysqli或pdo|
|Perl DBI|placeholder或quote()|
|Ruby DBI|placeholder或quote()|apache
方式三
使用本身定義函數進行校驗:其本質上仍是對輸入非法數據進行轉義和過濾。
輸入驗證能夠分爲:1.整理數據使之有效;2.拒絕已知的非法輸入;3.只接收已知的合法輸入。安全
方式四
使用存儲過程。
存儲過程參見: (9)mysql中的存儲過程和自定義函數服務器
#查看當前sql模式
select @@sql_mode;
#查看當前sql模式
SELECT @@session.sql_mode;
#修改當前sql模式
SET [SESSION][GLOBAL] sql_mode='modes';複製代碼
NO_AUTO_VALUE_ON_ZERO:
該值影響自增加列的插入。默認設置下,插入0或NULL表明生成下一個自增加值。若是用戶 但願插入的值爲0,而該列又是自增加的,那麼這個選項就有用了。session
STRICT_TRANS_TABLES:
在該模式下,若是一個值不能插入到一個事務表中,則中斷當前的操做,對非事務表不作限制。函數
NO_ZERO_IN_DATE:
在嚴格模式下,不容許日期和月份爲零。
NO_ZERO_DATE:
設置該值,mysql數據庫不容許插入零日期,插入零日期會拋出錯誤而不是警告。
ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE過程當中,若是數據被零除,則產生錯誤而非警告。如 果未給出該模式,那麼數據被零除時MySQL返回NULL。
NO_AUTO_CREATE_USER:
禁止GRANT建立密碼爲空的用戶。
NO_ENGINE_SUBSTITUTION:
若是須要的存儲引擎被禁用或未編譯,那麼拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常。
PIPES_AS_CONCAT:
將"||"視爲字符串的鏈接操做符而非或運算符,這和Oracle數據庫是同樣的,也和字符串的拼接函數Concat相相似。
ANSI_QUOTES:
啓用ANSI_QUOTES後,不能用雙引號來引用字符串,由於它被解釋爲識別符。
說明
ORACLE的sql_mode設置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER。
www.zhihu.com/question/22…
blog.csdn.net/agoago_2009…