透過把SQL指令插入Web表單遞交或輸入網域或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的SQL指令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到後台資料庫引擎執行的能力,並得到一個存在安全漏洞的網站上的資料庫。
SQL Injection,SQL 注入,其實就是利用程式碼漏洞改變SQL 的語意,從而形成惡意SQL 語句
$username = $_POST['username']; $password = $_POST['password']; $query = "select * from users where username = '{$username}' and password = '{$password}'"; // 判断是否登录成功 if (DB::select($query)) { return true; } return false;
咋一看這段偽代碼沒啥問題,就是判斷帳號密碼是否正確,正確就回傳true,允許登入。但如果傳入的username 為123' or 1=1;#\,那麼SQL 語句就變成了
select * from users where username = '123' or 1=1; # and password = '{$password}'";
這條惡意的SQL 語句無論何時都會回傳true,因為1=1
我們前面講過SQL Injection 就是利用程式碼漏洞改變SQL 的語義,意味著ORM 也是一個潛在的注入點。以tp3.2 為例,有下面這段程式碼
$result = D('User')->where([ 'username' => $_POST['username'], 'password' => $_POST['password'], ]); if ($result) { echo '登录成功'; } else { echo '登录失败'; }
這段程式碼咋看起來沒啥問題,但是如果username 傳入的是username[0]=neq&username[1]=1111,這樣就是的查詢語句變成
$result = D('User')->where([ 'username' => ['neq', 111], 'password' => $_POST['password'], ]);
那麼$result 的結果將永遠為true
對傳入的參數進行資料類型判斷和資料型別轉換
對引號轉義,PHP 可以使用addslashes,mysql_real_escape_string 等函數
預處理語句,最有效防範SQL Injection
程式碼審計
預處理語句是由資料庫實現的,例如MySQL 就有實作預處理語句。首先講下預處理的基本流程
MySQL 接收到預處理SQL Template,立刻著手解析(詞法與文法)
客戶端傳送數據,去取代SQL Template 中的佔位符(?)
MySQL 執行語句,傳回結果
刪除預處理語句(可選)
那麼預處理語句是如何防範SQL 注入的呢?首先所謂的 SQL Injection 就是強行改變 SQL 語意。而在步驟一中已經處理完成語句,將 SQL 的語意固定下來,步驟二的替換佔位符並不會改變 SQL 語意。以下是 PHP PDO 的範例
$stmt = $pdo->prepare("select * from users where username = '?' and password = '?'"); $stmt->execute("123' or 1=1;#", 'test');
相關推薦:《mysql教學》
以上是一分鐘帶你了解SQL Injection的詳細內容。更多資訊請關注PHP中文網其他相關文章!