BOSS:你連什麼是 SQL 注入都不知道,我怎麼給你加薪?

1 什麼是 SQL 注入?

所謂 SQL 注入,便是指黑客將 SQL 代碼嵌入在輸入參數之中,在未經過濾的情況下直接拼接到 SQL 語句之中進行解析並執行的一種攻擊方法。

2 一個 SQL 注入的簡單例子

我們來模擬一個登錄場景,大家平時登錄網站什麼之類的需要啥呢?沒錯,賬號密碼!於是,我們的登錄界面一般都是這個樣子。。。

很明顯,
當我們輸入賬號密碼按下回車之後,會向後臺返回賬號密碼兩個參數。

https://mail.qq.com?username=3030&password=1010

然後在後臺相當於調用了下面的 SQL 語句:

SELECT * FROM user WHERE username = '3030' AND password = '1010'

好,上面老實人一般都會正常輸入賬號密碼,但總是有一些不法分子存在非分之想,他們會這麼輸入賬號密碼:

在這裏插入圖片描述
在後臺,執行的 SQL 語句變成了下面這條:

SELECT * FROM user WHERE username = '3030'#' AND password = '1010'

在 MySQL 中,# 之後的所有字符串都會被當成註釋進行處理,其實上面的 SQL 語句與下面這一條等價:

SELECT * FROM user WHERE username = '3030'

我們可以發現,只需要在賬號後面加上 '# 兩個字符,然後我們便可以隨便輸入密碼,因爲最終會被註釋掉。在這種情況下,我們只需要知道別人的賬號,即可不需要密碼進行登錄操作,這是一個非常嚴重的安全問題!

3 SQL 注入的條件

經過一個例子,我們來總結一下 SQL 注入的產生條件:

  1. 存在參數傳遞
  2. 參數值帶入 SQL 語句查詢並且執行

4 如何防止 SQL 注入攻擊?

在上面的例子中我們可以發現,SQL 注入攻擊實在太可怕了!那麼,我們又該如何防止 SQL 注入攻擊呢?一般我們可以採取以下方法:

  1. 對輸入變量的類型與格式進行檢查。如果參數類型爲整數,則加上必要的判斷;如果參數類型爲字符串,則使用正則表達式進行過濾操作(賬號必須爲 [0-9a-zA-Z] 範圍內的字符串)
  2. 對特殊字符進行過濾和轉義。例如對 ’ 或 " 或 \ 等特殊字符進行轉義
  3. 使用 MySQL 的預編譯機制

什麼是預編譯?

一般 SQL 語句的執行可以分爲以下三個過程:

  1. 詞法和語義解析
  2. 優化 SQL 語句,制定執行計劃
  3. 執行並返回結果

這種是一般情況,但是我們在某些場景下可能存在 SQL 語句反覆執行或者每次執行只有個別值不同的情況,如果每次執行都要重新經過上面三個步驟,顯然效率是非常不可觀的,幸好預編譯機制可以有效解決這個問題。

預編譯機制將 SQL 語句中的值用佔位符替代,可以理解爲將 SQL 語句模板化或者參數化。使用預編譯,我們便可以一次編譯、多次運行,省去了解析,優化等過程,另外使用預編譯機制也可以有效防止 SQL 注入。

問題來了,爲什麼預編譯機制可以防止 SQL 注入呢?使用預編譯機制,我們後臺的 SQL 語句就可以抽象爲:

SELECT * FROM user WHERE username = ? AND password = ?

在該語句中,無論用戶輸入何種賬號密碼,邏輯關係始終爲 AND,不會導致 SQL 語句結構發生變化。參數值是參數值,語句是語句,參數的值並不是語句的一部分,MySQL 只按語句的語義來執行 SQL。

5 Mybatis 如何防止 SQL 注入?

MyBatis 是我們常用的持久層框架,其 SQL 均需要我們手動編寫,那麼它又是如何防止 SQL 注入的呢?

在編寫映射語句時,使用 #{} 會進行預編譯處理,其 SQL 語句類似於下面的格式:

SELECT * FROM user WHERE username = ? AND password = ?

SQL 執行時,會直接將佔位符 ?替換爲參數,自然不會存在 SQL 注入的問題。

參考:SQL注入攻擊常見方式及測試方法
SQL注入詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章