跳轉到

PostgreSQL Varchar Overflow Three-Layer Defense

概念概覽

三層防護架構

核心知識

三層防護架構

只修 DB 欄位大小不夠,原因是其他未覆蓋路徑(舊版 client、第三方整合)仍可繞過;只加應用截斷不夠,因為 DB 側若有 bulk insert 等直接操作同樣會溢位。

Layer 1 — DB MigrationALTER TABLE devices ALTER COLUMN device_info TYPE VARCHAR(2048)(範例),防止底層直接寫入溢位。

Layer 2 — 應用層截斷:在 service 入口加 Device.SanitizeDeviceInfo() + truncatePtr(s string, max int) helper,確保進 DB 前已截斷,同時可在 log 中留下截斷事件。

Layer 3 — PG error class 22 sentinel

if pqErr.Code.Class() == "22" {
    return ErrDataValidation
}
將 PG data exception(class 22,包含 string_data_right_truncation、numeric_value_out_of_range 等)統一映射至 twirp.InvalidArgument,防止未覆蓋路徑炸出 500。

注意事項

  • Layer 3 是泛用 catch-all,會掩蓋「截斷本身不該發生」的語意問題,需搭配 Layer 2 的 log 才能在事後追查
  • Migration 若中途失敗進入 dirty state,需手動 SET version=N, dirty=false 後才能繼續

經驗教訓

  • 三層缺一不可:只改 DB 無法防所有路徑;只加應用截斷無法防 DB 直接操作;只加 PG error class 攔截會掩蓋根因

  • PG error class 22 涵蓋多種 data exception,適合作為 defensive catch-all,但須搭配上層 log 保留可查性

  • Migration dirty state 需手動修復,不能忽略直接重跑

常見陷阱

  • 只擴充 DB varchar 欄位,忘記加應用層截斷 → 其他 direct write 路徑仍會炸

  • 只加應用截斷但沒有 PG error class 攔截 → 未覆蓋路徑會回傳 500 而非 InvalidArgument

  • Migration 中途失敗後繼續重跑而不修復 dirty state → 所有後續 migration 全部卡住

相關概念

相關視角

以下頁面與本概念共享主題,但從不同角度切入。保留獨立視角同時提供交叉參考:

來源 Sessions

日期 Session 貢獻摘要

| 2026-04-02 | d088842d-abec-48fc-8a1a-779a5f74e05d | 確立 varchar 溢位防護的三層完整架構:DB 欄位擴充 + 應用層截斷 + PG error class 22 分類,並說明缺一不可的原因 |


本概念頁面由 Semi-Brain Wiki 系統自動維護

最後更新: 2026-04-02