SQL Injection 是什麼?為什麼一個輸入欄位會影響資料庫?
網站通常需要從資料庫讀取帳號、商品、文章或訂單資料。當使用者在登入框、搜尋欄、商品篩選器或網址參數輸入內容時,後端程式會把這些資料交給資料庫處理。如果程式用不安全的字串拼接方式組合查詢,資料庫可能無法分辨哪些內容是使用者資料,哪些內容是查詢結構。 這就是 SQL Injection 的核心問題:輸入內容原本應該只是資料,卻可能被當成查詢語句的一部分。攻擊者不一定需要知道完整資料庫結構,只要應用程式的輸入處理方式存在缺陷,就可能嘗試改變查詢結果、讀取不應公開的資料,甚至影響資料庫內容。 這裡所說的駭客,是指具備程式、網路和系統分析能力的技術人員。安全研究人員會在取得授權後利用測試環境找出問題,協助網站修補漏洞;未經授權而竊取資料、破壞服務或入侵帳戶的人,則是攻擊者或犯罪者,兩者不能混為一談。
哪些網站功能最需要檢查 SQL Injection 風險?
SQL Injection 不只可能出現在登入頁面。只要網站把使用者輸入交給資料庫查詢,就應該檢查輸入和查詢之間是否有安全隔離。常見位置包括搜尋功能、商品分類、文章篩選、會員資料查詢、訂單編號、報表匯出、API 參數和後台管理介面。 網站管理者可以先建立輸入點清單,再逐一確認每個輸入點的資料流向。實際檢查時,可以依照以下順序進行:
- 列出所有來自表單、網址、Cookie、Header 和 API 的外部輸入。
- 標記哪些輸入會被送到 SQL、NoSQL、ORM 或其他資料庫查詢層。
- 確認後端是否使用參數化查詢,而不是將輸入直接拼接成查詢字串。
- 檢查錯誤回應是否暴露資料庫名稱、欄位、查詢結構或伺服器路徑。
- 使用測試帳號和測試資料庫,在獲得授權的隔離環境中驗證修補結果。
一般讀者也可以從網站表現觀察風險線索,例如某個搜尋欄輸入特殊內容後出現資料庫錯誤、不同頁面回傳不一致的結果,或錯誤頁面直接顯示 SQL、資料庫品牌和程式路徑。不過,看到錯誤訊息只能代表需要進一步檢查,不能直接證明網站一定存在可利用漏洞。
參數化查詢如何阻止 SQL Injection?
最重要的防禦方式,是讓 SQL 查詢結構和使用者輸入分開處理。參數化查詢會先固定查詢模板,再把使用者輸入當成獨立參數交給資料庫。即使輸入內容包含特殊符號,也不會直接改變原本的查詢結構。 概念上,安全的流程不是把文字直接接在 SQL 後面,而是先建立查詢,再把值綁定到參數。例如在 Python 使用資料庫套件時,應採用套件提供的參數繫結方式: query = "SELECT id, name FROM users WHERE email = ?" user = database.execute(query, (email_input,)).fetchone() 不同程式語言和資料庫的寫法會不同,但核心原則一致:不要把外部輸入直接拼接到 SQL 字串中。 OWASP 的 SQL Injection Prevention Cheat Sheet 將參數化查詢列為主要防禦方法,開發者應依照所使用的語言、框架和資料庫官方文件實作。 ORM 或資料庫框架可以降低風險,但不代表自動安全。某些開發者仍可能使用原始 SQL、動態排序欄位或手動拼接查詢,讓漏洞重新出現。因此,程式碼審查不能只確認是否使用 ORM,而要確認實際查詢是否將資料與指令分離。
除了參數化查詢,網站還需要哪些防禦?
參數化查詢是核心,但完整防禦需要多層措施。輸入驗證可以限制資料格式,例如帳號只能接受預期的電子郵件格式、商品編號只能是指定格式、排序欄位只能從固定清單選擇。輸入驗證不能取代參數化查詢,但能降低異常資料進入後端的機會。 資料庫帳號也應採用最小權限。網站讀取商品資料的帳號,不應同時擁有刪除資料表、修改管理員帳號或建立新帳號的權限。即使應用程式存在漏洞,限制資料庫帳號權限也能縮小可能造成的影響。 錯誤訊息應對使用者保持簡潔,詳細資料則保存到只有授權人員能查看的伺服器日誌。錯誤頁面不應直接顯示 SQL 語句、資料庫版本、內部路徑或連線資訊。日誌中可以記錄請求時間、路徑、狀態碼、錯誤類型和來源,但要避免把密碼、Token 或個人敏感資料寫入日誌。 網站管理者還應安排程式碼審查、依賴套件更新、秘密資訊管理、資料庫備份、弱點掃描和事件監控。WAF 可以作為額外防線,但不能取代安全程式設計;如果後端仍然使用不安全的查詢方式,單靠 WAF 可能無法處理所有變形輸入。
如何在合法環境中學習 SQL Injection?
初學者不應直接拿陌生網站測試。比較安全的學習方式,是使用設計給資安訓練的隔離環境,例如 PortSwigger Web Security Academy 的 SQL Injection 課程。這類靶場會提供明確的授權範圍和虛擬練習目標,適合理解漏洞原理和防禦思路。 學習時可以採用防禦者流程:先閱讀靶場情境,理解哪一個功能負責查詢;觀察應用程式如何處理輸入;記錄錯誤或異常回應;在完成練習後,回頭思考參數化查詢和權限限制如何阻止問題。不要把靶場中的測試內容直接套用到真實網站,也不要掃描沒有取得授權的網域。 如果是網站開發者,可以在自己的測試專案中建立測試資料庫,使用假帳號和虛構資料驗證輸入處理。修補後,應用自動化測試確認不同輸入仍然被當成資料,而不是查詢結構;同時檢查錯誤頁面、日誌和資料庫權限是否符合預期。 發現疑似漏洞時,不要公開貼出真實網站的資料、帳號、查詢內容或可重現細節。應先停止測試、保存最少必要證據,按照網站的漏洞回報政策或安全聯絡方式通知擁有者。VexelOps 可以在你對網站安全檢查、漏洞概念或合法學習環境有疑問時提供協助,但不會協助未授權入侵或資料竊取。
SQL Injection 常見問題
SQL Injection 一定會讓整個網站被駭客控制嗎?
不一定。實際影響取決於查詢漏洞的位置、資料庫帳號權限、網站架構、資料庫類型和其他防禦措施。有些問題可能只造成搜尋結果異常,有些則可能暴露個人資料、帳號資訊或管理資料。不能只根據一個錯誤頁面判斷最終影響。 真正重要的是快速確認輸入是否安全、資料庫權限是否過大、錯誤訊息是否洩露內部資訊,以及是否有異常請求和資料存取記錄。網站管理者應在授權測試環境中驗證,不應等到真實資料外洩後才處理。
使用 WAF 之後,還需要修正程式碼嗎?
需要。WAF 可以攔截部分可疑請求,並協助記錄異常流量,但它不是參數化查詢的替代品。攻擊請求可能改變格式、編碼或通過其他未被規則覆蓋的輸入點;如果程式本身仍把外部輸入直接併入查詢,根本問題依然存在。 正確做法是先修正資料庫查詢方式,再用 WAF、日誌監控、權限限制和安全測試增加防禦深度。每次修改後都應在測試環境確認正常功能沒有被破壞,並檢查錯誤訊息是否仍然洩露資料庫細節。
一般網站使用者可以自己測試某個網站有沒有 SQL Injection 嗎?
不要在沒有明確授權的情況下測試別人的網站。即使你只是好奇,也可能造成服務負擔、觸發安全警報,或意外接觸不應查看的資料。看到網站錯誤時,最安全的做法是記下時間、頁面網址和一般錯誤畫面,不要嘗試進一步利用。 如果想學習,可以使用 PortSwigger Web Security Academy、OWASP 教材或自己的本機測試專案。若你是網站擁有者,則可以在測試環境使用假資料進行檢查,並在正式上線前完成程式碼審查和弱點修補。
One Key Takeaway:參數化查詢是防禦 SQL Injection 的核心。