首頁  >  文章  >  資料庫  >  一分鐘帶你了解SQL Injection

一分鐘帶你了解SQL Injection

醉折花枝作酒筹
醉折花枝作酒筹轉載
2021-08-02 16:01:222067瀏覽

透過把SQL指令插入Web表單遞交或輸入網域或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的SQL指令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到後台資料庫引擎執行的能力,並得到一個存在安全漏洞的網站上的資料庫。

一分鐘帶你了解SQL Injection

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

透過ORM 注入

我們前面講過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

  • 程式碼審計

預處理語句是如何防止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中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除