Carl Zhang’s Blog 是我一個大學朋友的博客,整個平台都是他自己寫的靜態,在前幾天,他的網站通過一個內建的SQL數據庫實現了文章搜索功能,這篇文章將會通過對這個功能的實現 來談一談網站的安全問題。
靜態站點如何實現站內搜索 這是他關於實現搜索功能的博客,其中介紹了通過一個爬蟲抓取自己網站的所有界面並且生成一個列表,在通過列表轉換成sql數據庫,之後通過php對生成的數據庫進行查找就可以實現文章查詢 功能。
什麼是數據庫
小白可能不知道什麼是數據庫,那麼這里通俗的講解一下,數據庫就和Office中的Excel. 文件名就是數據庫的名字,一個數據庫可以包含很多表,下圖有兩個,分別是商品和用戶, 每個表都由不同的字段組成。
現在大多數的關係型數據庫數據庫解決方案是MySQL和MSSQL,分別屬於Oracle和微軟,MikeTech的背後就使用了MySQL數據庫。
SQL:結構化查詢語言
那麼問題來了,數據庫的功能無非就是四個:增,刪,改,查。 拿上面的商品表舉例子 那麼我想查詢一個商品的話怎麼辦呢。
操作數據庫使用的是SQL語言,通過一個變成語言讓數據庫執行不同的SQL語句來操作數據庫,舉個例子,如果我想查詢上面的商品表中的所有帶iPhone 7的商品應該怎麼構造一個查詢語句 呢。
SELECT * FROM 商品
WHERE 名稱
= ‘iPhone 7’
就是這麼簡單,這樣就能查詢出來商品表中所有名稱為 iPhone 7 的商品了
那麼要是想要名稱只要包含iPhone 7就算數呢? 搜索iPhone 7出來iPhone 7和iPhone 7 plus:
SELECT * FROM 商品
WHERE 名稱
LIKE ‘%iPhone 7%’
使用LIKE語句就可以了,是不是不難理解。
這裡有一個地方需要注意,搜索的時候商品名稱都用單引號括起來了,這樣是為了避免空格切斷語句。
看一看他博客中的負責搜索的代碼:
在代碼第二行拼湊了SQL查詢語句,其中keyword參數是用戶在搜索框中輸入的詞彙,執行這個語句會找出 summary 字段和 title字段 包含搜索關鍵字的文章。 構造出sql語句之後,他的代碼 直接調用 了mysql_query()函數來讓數據庫執行這個命令,其實這個做法是非常危險的。
先來看看正常情況,我在他博客的搜索框中輸入 “峰區” ,網站真的給我返回了所有帶峰區字樣的文章,沒毛病:
這時執行的SQL語句為
SELECT * FROM 表名
WHERE summary
LIKE ‘%峰區%’ OR title
LIKE ‘%峰區%’
其中表名是我不知道的。 。 。 知道了可能就出事了,summary和title字段是我看他博客裡寫的所以應該沒有問題。
那我我再輸入點畸形的“ 峰區”(前後加入若干空格),結果還是一樣的,那是因為他的程序開始對用戶的輸入做了一個trim處理,刪除了前後所有的空格,所以最後 執行的SQL語句和結果還是一樣的
SQL注入 (SQL Injection )
可是設計者有沒有想過我輸入的不是“峰區”這樣正常的字眼而是別的?
攻擊其他網站的方法千千萬,其中,SQL注入已經有了很多年的歷史。
在設計程序的過程中,只要牽扯到用戶輸入,那麼我都會記住一點,那就是;“永遠不要相信用戶的輸入”
由於程序沒有對我輸入什麼做更多處理,那麼要是打一段SQL語句在搜索框裡會出現怎樣的情況呢?
這次來輸入 單引號 “ ‘ ” 試一試:
結果是:
這已經說明SQL語句在執行中出現了故障,為什麼呢? 來看一看:
由於我輸入了一個單引號,在組裝SQL語句是因為我的單引號和語句中原本的單引號造成了閉合,這讓黑色部分成了有效的部分,而紅色部分,由於多出來的百分號 出現了語法錯誤,導致這條命令無法執行。
再來試一試輸入:“ a’ or 1=1 – – a ”
這個輸入直接列出了數據庫中所有的文章,來看看原因:
SQL 語句變成了這樣,其中 ,兩個減號 – – 是SQL的註釋語法,出現在之後的語句是不會被執行的,所以SQL語句相當於變成了這樣:
SELECT * FROM 表名 WHERE summary LIKE ‘%a’ or 1=1
根據意思,應該是列舉出所有summary字段中包含%a 字樣的列,但是後面多了一句or 1 = 1,1 = 1是一個恆為真的表達式,通過和OR (邏輯或)語句聯合使用 ,最後相當於執行了:
SELECT * FROM 表名 WHERE 1
所以數據庫列出了所有的文章。
再來試一試” a’ or 1 = 1 LIMIT 1; — a ” 通過Limit語法限制一下檢索結果的最大數量為1, 從結果來看沒問題。
這就是最基本的SQL注入攻擊,這一類漏洞可以允許用戶直接在數據庫中執行自己的SQL語句。
如果我知道了表名的話後果會更嚴重,攻擊者甚至可以直接刪除這張表。
但是我不知道表名,在沒有更多線索之前只能冒猜。
這一類SQL注入漏洞是可能對網站造成嚴重後果的,如果有黑客通過漏洞知道了用戶表的名字,然後黑客就可以直接獲得管理員密碼或者在網站中直接加入一個新的管理員,所以再 設計這一類帶有表單提交功能的時候要注意防範。
知道SQL注入的人不在少數,稍微懂點網絡開發的人都會知道防範。 還記得以前網絡上流傳過這樣的圖片,現在能看懂了吧~
本文作者周毅剛,歸屬於其個人網站MikeTech, 未經允許禁止轉載。