PostgreSQL Varchar Overflow Three-Layer Defense¶
概念概覽
三層防護架構¶
核心知識¶
三層防護架構¶
只修 DB 欄位大小不夠,原因是其他未覆蓋路徑(舊版 client、第三方整合)仍可繞過;只加應用截斷不夠,因為 DB 側若有 bulk insert 等直接操作同樣會溢位。
Layer 1 — DB Migration:ALTER 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:
將 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 全部卡住
相關概念¶
相關視角¶
以下頁面與本概念共享主題,但從不同角度切入。保留獨立視角同時提供交叉參考:
- Game Item Exemption Resource Architecture — 共享:
game-backend/ 獨特:architecture-pattern,item-system - Twirp Error Handling — 共享:
error-handling/ 獨特:api,rpc
來源 Sessions¶
| 日期 | Session | 貢獻摘要 |
|---|---|---|
| 2026-04-02 | d088842d-abec-48fc-8a1a-779a5f74e05d | 確立 varchar 溢位防護的三層完整架構:DB 欄位擴充 + 應用層截斷 + PG error class 22 分類,並說明缺一不可的原因 |