歡迎光臨
我們一直在努力

Error-based SQL Injection 與錯誤訊息洩漏

安全提醒:本文為防禦導向的虛構案例與不可部署片段;測試僅限自有或明確授權環境。

資料庫錯誤能協助開發,卻不該直接出現在正式頁面。Error-based SQL Injection 利用可觀察的錯誤差異推測查詢結構或資料;即使沒有注入,詳細錯誤也會洩漏表名、欄位與技術堆疊。

錯誤訊息的安全去向技術流程圖
錯誤訊息的安全去向:依序追蹤資料與安全控制點。

本篇會學到什麼

  • 分辨使用者訊息、應用日誌與資料庫日誌
  • 理解錯誤如何成為資訊側通道
  • 設計可除錯但不洩漏的錯誤流程

必備名詞與心智模型

錯誤處理有兩個受眾:使用者只需要穩定訊息與事件 ID;維運人員需要受控日誌中的例外類型、時間、端點與追蹤資訊。SQL 原文、連線字串、密碼與完整敏感參數不應出現在前端。

發生情境與生活化比喻

搜尋功能遇到單引號後直接顯示 PDOException。生活化比喻是餐廳不只說『訂單格式錯誤』,還把廚房配置、食材庫位置與內部操作手冊一起交給顧客。

不安全的原始碼

try {
    $rows = $pdo->query("SELECT * FROM products WHERE name='$q'")->fetchAll();
} catch (PDOException $e) {
    echo $e->getMessage(); // 正式環境洩漏資料庫細節
}

此片段刻意省略連線、路由與部署設定,只用來辨識資料流,請勿放入任何服務。

逐步看懂資料如何變成查詢

  1. 外部 q 被拼接進查詢
  2. 資料庫解析失敗或回傳型別錯誤
  3. PDO 把詳細例外交給應用程式
  4. 應用程式原樣回顯
  5. 使用者可比較錯誤內容、狀態碼與頁面長度

修補後原始碼

$eventId = bin2hex(random_bytes(8));
try {
    $stmt = $pdo->prepare('SELECT id,name,price FROM products WHERE name=:q');
    $stmt->execute(['q'=>$q]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    error_log("database_error event={$eventId} endpoint=product_search");
    http_response_code(500);
    echo "系統暫時無法處理,事件編號:" . htmlspecialchars($eventId);
}

修補的共同原則是先固定 SQL 結構,再把值獨立綁定;無法作為值綁定的識別字只能從程式內允許清單產生。

如何驗證修補

  • 一般輸入與特殊字元不觸發 SQL 解析錯誤
  • 所有資料庫失敗對外使用一致格式
  • 前端沒有表名、SQL、路徑、堆疊或連線資料
  • 內部日誌可用事件 ID 串起請求,但敏感值已遮罩


閱讀提醒:以下分析的目的,是讓你能在自己的程式、測試資料與授權環境中辨識風險。面對正式系統時,先取得明確授權並保存變更紀錄;不要用錯誤訊息或一次回應就推論資料外洩,也不要把文章中的概念改造成自動化探測。安全工作的完成條件,是能說明根因、修補位置、回歸結果與剩餘風險。

更多應用情境、常見誤判與觀察方法

把原理放回真實開發情境

公開頁面回傳通用訊息,內部保存事件編號、查詢名稱、程式位置與去識別化上下文。 實作時不要只盯著畫面上的輸入框,還要檢查 API 參數、伺服器端預設值、資料轉換與最後呼叫的資料庫介面。最實用的閱讀方式,是把每一段程式標成「外部來源、轉換、控制、資料庫 sink」,確認資料值沒有在途中重新變回 SQL 結構。

常見誤判

關閉詳細錯誤只是在減少資訊洩漏;若根因仍是動態拼接,漏洞依然存在。 安全判斷不能只靠畫面、單次錯誤或某一個防護產品;應同時看原始碼、驅動程式實際執行方式、資料庫權限與回歸測試。若無法證明查詢結構固定,就應把它視為待修的設計風險。

開發與 SOC 可以觀察什麼

把資料庫語法錯誤、轉型失敗與權限拒絕集中到可搜尋平台,為同一請求建立關聯 ID。 日誌宜記錄時間、路由、請求關聯 ID、查詢名稱、結果狀態與耗時,敏感值則遮罩或雜湊。偵測規則的用途是縮短發現時間;阻擋之後仍須回到程式碼修補,並搜尋其他共用元件與相同資料流。

審查時的三個追問

  1. 這個值最早由誰控制,經過哪些轉換?
  2. 它在資料庫呼叫中是資料值,還是欄位、排序、運算式等結構?
  3. 若預防失效,最小權限、監控與事件流程能限制並發現多少影響?

開發與維運防禦清單

  • 參數化先消除根因,錯誤隱藏只是第二層
  • 正式環境關閉 display_errors
  • 集中化日誌限制讀取權限與保存期限
  • 對短時間大量資料庫錯誤與不同輸入模式告警

重點整理與下一篇

若頁面不顯示資料或錯誤,真假條件仍可能造成不同結果。下一篇將解釋 Boolean-based Blind SQL Injection 的側通道概念。

參考資料與更新日期

更新日期:2026-07-20

贊(0) 贊助
未經允許不得轉載:波波的寂寞世界 » Error-based SQL Injection 與錯誤訊息洩漏

波波的寂寞世界

Facebook聯繫我們

覺得文章有幫助,歡迎贊助支持本站

感謝你的支持,我會持續整理資安筆記、實務經驗與有價值的技術內容。

贊助本站