歡迎光臨
我們一直在努力

寫入型查詢與 Second-order Injection

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

SQL Injection 不只讀資料。INSERT、UPDATE、DELETE 若使用字串拼接,也可能改變資料或業務狀態;Second-order Injection 更會先把內容正常存入,等另一段程式日後拼接它時才觸發。

Second-order 的時間差技術流程圖
Second-order 的時間差:依序追蹤資料與安全控制點。

本篇會學到什麼

  • 辨識寫入型查詢的注入面
  • 理解儲存不等於信任
  • 追蹤跨請求與背景工作的 Second-order 資料流

必備名詞與心智模型

第一階段把外部文字當資料保存可能完全正常;第二階段的報表、通知或管理工具從資料庫讀出文字後,錯把它視為可信並拼進新 SQL。資料庫只是中繼儲存,不會自動把 tainted data 洗乾淨。

發生情境與生活化比喻

使用者建立顯示名稱,之後後台依顯示名稱產生報表。生活化比喻是危險指令先被放進倉庫,收貨時沒事,直到另一位員工把箱中文字當工作命令照做。

不安全的原始碼

$displayName = loadDisplayName($userId); // 來自先前的使用者輸入
$sql = "UPDATE reports SET viewed=1 WHERE owner_name='"
     . $displayName . "'";
$pdo->exec($sql);

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

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

  1. 請求 A 將顯示名稱安全地存成資料
  2. 時間過去後,背景工作從資料庫讀出該值
  3. 開發者誤以為資料庫內資料皆可信
  4. 值被拼進 UPDATE 查詢
  5. 真正危險在第二個 sink,因此只檢查最初表單會漏掉

修補後原始碼

$displayName = loadDisplayName($userId);
$stmt = $pdo->prepare(
    'UPDATE reports SET viewed=1 WHERE owner_name=:owner_name'
);
$stmt->execute(['owner_name'=>$displayName]);

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

如何驗證修補

  • 以含引號的合法顯示名稱建立與讀取完整流程
  • 搜尋所有從資料庫取值後再拼 SQL 的背景工作
  • 寫入帳號只能更新必要表與欄位
  • 重要異動有審計事件、操作者與影響列數


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

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

把原理放回真實開發情境

資料安全寫入後,可能在報表、匯出或排程工作中被當成 SQL 片段重新拼接,形成二次注入。 實作時不要只盯著畫面上的輸入框,還要檢查 API 參數、伺服器端預設值、資料轉換與最後呼叫的資料庫介面。最實用的閱讀方式,是把每一段程式標成「外部來源、轉換、控制、資料庫 sink」,確認資料值沒有在途中重新變回 SQL 結構。

常見誤判

輸入曾通過驗證或來自自家資料庫,不代表後續使用時可以信任。 安全判斷不能只靠畫面、單次錯誤或某一個防護產品;應同時看原始碼、驅動程式實際執行方式、資料庫權限與回歸測試。若無法證明查詢結構固定,就應把它視為待修的設計風險。

開發與 SOC 可以觀察什麼

盤點跨服務資料流與背景工作;在每個資料庫 sink 都重新套用參數化,而非依賴來源信譽。 日誌宜記錄時間、路由、請求關聯 ID、查詢名稱、結果狀態與耗時,敏感值則遮罩或雜湊。偵測規則的用途是縮短發現時間;阻擋之後仍須回到程式碼修補,並搜尋其他共用元件與相同資料流。

審查時的三個追問

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

開發與維運防禦清單

  • 每次進入 SQL sink 都重新建立參數邊界
  • 不要把『已儲存』當成『已可信』
  • 分離讀取、寫入與 migration 帳號
  • 對異常大量 UPDATE/DELETE、影響列數與非預期排程告警

重點整理與下一篇

Second-order 顯示資料可繞一大圈才抵達 sink。下一篇將擴大來源盤點,涵蓋 Cookie、HTTP Header、JSON API 與背景工作。

參考資料與更新日期

更新日期:2026-07-20

贊(0) 贊助
未經允許不得轉載:波波的寂寞世界 » 寫入型查詢與 Second-order Injection

波波的寂寞世界

Facebook聯繫我們

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

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

贊助本站