PostgreSQL 一次修補 52 個漏洞(CVE-2026-6460 等):先更新,再看誰建得了物件

PostgreSQL 在 2026 年 11 月 12 日發布 18.7、17.12、16.16、15.20 與 14.25,一次修補 52 個漏洞,其中 32 個的 CVSS 評 8.8。討論最多的是 CVE-2026-6460,能登入資料庫又建得了物件的帳號,可以用跑資料庫的那個作業系統使用者身分執行任意程式。還在支援的 14 到 18 各版,沒升到這幾個版號的都在範圍內。

先更新小版本並重啟,再清點哪些帳號建得了物件。查核到 2026-11-13 09:50(台北時間)為止,官方公告沒有提到在野利用,CISA KEV 最新一版也沒有列入。只是研究者已經公開技術細節,CVE-2026-6460 要的又只是通過驗證、建得了物件的帳號,預設權限下不少一般帳號就符合,應用程式的連線帳號被 SQL injection 借走也算,排修補不必等攻擊被證實。

受影響的條件

官方把 CVE-2026-6460 歸為 type confusion。照公告的說法,系統對帶型別的值追蹤不足,值本身也不帶型別資訊,型別改過以後,舊的值還可能留在 data dictionary 項目、PL/pgSQL 變數等地方,被當成另一種型別來用。主要路徑是 ALTER ... SET DATA TYPE,公告也寫明還有別的 DDL 路徑。CVSS 3.0 評 8.8,向量是 AV:N/AC:L/PR:L/UI:N,攻擊者要先通過身分驗證,而且得是公告所說的 object creator。

這次更新不能只看一個編號。評 8.8 的 32 個,標題多半直接寫著 executes arbitrary code(可執行任意程式碼),成因包括 type confusion、use-after-free、integer wraparound 和 heap buffer overflow,牽涉到 plpgsql、plperl、pltcl、dblink 與全文檢索函式。另有 6 個出在 client 工具,pg_dump、pg_restore、reindexdb、vacuumdb、pg_basebackup 都在內,跑備份還原的主機和 CI 也要更新,光升資料庫伺服器不夠。不必登入的只有少數,其中 CVE-2026-116322 未經驗證就能觸發,評 5.3,只影響 18,其他幾個多半要等使用者自己去還原或訂閱對方的資料。

14.25 是 PostgreSQL 14 的最後一版,官方公告寫明 14 從此停止支援,還在 14 上的服務,這次更新完就該把大版本升級排進行程。13 與更早的版本已不在上游支援範圍,這次沒有對應的修補版,用廠商延長支援的就看廠商公告。

誰算建得了物件

一般帳號沒給過 CREATE,很容易以為這件事輪不到自己,可是照 PostgreSQL 文件,每個資料庫建立時就把 CONNECT 與 TEMPORARY 給了 PUBLIC,任何登入得了的角色都建得了暫存資料表。15 起新建資料庫的 public schema 不再讓 PUBLIC 建物件,但 release notes 寫明升級或還原 dump 會保留原本的權限,從 14 以前一路升上來的叢集,public 可能還開著。

下面是在 OrbStack 上用官方 image 做的清點,只建一個角色、查系統目錄,沒有執行任何改型別的語句,也沒有重現漏洞。兩個全新的叢集各建一個只有 LOGIN 的角色 lowpriv,再跑同一段查詢:

select r.rolname,
       has_database_privilege(r.oid, current_database(), 'TEMPORARY') as temp,
       (select string_agg(n.nspname, ',') from pg_namespace n
         where n.nspname !~ '^pg_' and n.nspname <> 'information_schema'
           and has_schema_privilege(r.oid, n.oid, 'CREATE')) as create_in,
       (select count(*) from pg_class c
         where c.relowner = r.oid and c.relkind in ('r','p')) as owned_tables
from pg_roles r
where r.rolcanlogin and not r.rolsuper
order by 1;

實際輸出,上面是 postgres:18.7,下面是 postgres:14.25:

 rolname | temp | create_in | owned_tables 
---------+------+-----------+--------------
 lowpriv | t    |           |            0

 rolname | temp | create_in | owned_tables 
---------+------+-----------+--------------
 lowpriv | t    | public    |            0

什麼權限都沒給的角色,兩版都拿得到 TEMPORARY,14.25 還能在 public 建物件。這段查詢唯讀,可以直接在每個資料庫跑一次,temp 是 t、create_in 有值或 owned_tables 大於 0 的帳號,先當成建得了物件。它只是初篩,資料庫層級的 CREATE、要 SET ROLE 切過去才拿得到的權限都沒查,owned_tables 也只算直接擁有的資料表,查出來全空不代表沒事。

應用程式自己的連線帳號最容易漏掉。不少系統讓同一個帳號兼跑 migration,資料表的擁有者就是它,ALTER TABLE 看的是擁有權,收回 schema 的 CREATE 也拿不走這個能力。應用程式若有 SQL injection,以前估損害看的是這個帳號在資料庫裡有多少權限,現在得把資料庫主機上那個作業系統使用者碰得到的東西也算進去,包括資料目錄和同一台主機上的其他資料庫。讓使用者直接下 SQL 的服務,像多租戶平台或報表工具,要排在最前面。

收權限只能縮小範圍

還沒辦法馬上更新的話,可以先把預設給出去的權限收回來:

revoke temporary on database postgres from public;
revoke create on schema public from public;

實測收完以後,兩版的 temp 都變成 f,14.25 的 create_in 也空了。這兩道只收回給 PUBLIC 的授權,直接授予某個角色、或從其他角色繼承來的權限都還在。範圍也各自不同,第一道只改指名的資料庫,寫 postgres 就只動到它,第二道只改當下連線那個資料庫的 public,有幾個資料庫就要換名、連進去各做一次。

新建的資料庫也會回到預設,實測裡 TEMPORARY 又是 t,14.25 上 public 的 CREATE 也回來了。先在 template1 收過再建,public 的 CREATE 會跟著範本收掉,TEMPORARY 卻還是 t,資料庫層級的權限不從範本複製,每建一個都得再收一次。收之前先確認有沒有程式依賴暫存資料表,報表和批次作業常用。

Red Hat 的緩解建議也是限制網路連線,並收回不受信任帳號的建物件權限。官方公告沒有列 workaround,又寫明攻擊路徑不只一條,收完權限能擋下哪些我沒有驗證,所以這只算縮小範圍,真正的修補還是更新。長遠來看,跑 migration 的帳號該和服務平常連線的帳號分開,平常那個只留每天用得到的權限,下次遇到同類漏洞,要清點的範圍就小得多。

各家的狀態

對象查核時狀態
上游 PostgreSQL18.7、17.12、16.16、15.20、14.25 已於 2026-11-12 發布,14.25 是 14 的最後一版
官方 Docker imagepostgres:18.7、17.12、14.25 已經可以 pull,實測版本字串為 18.7 (Debian 18.7-1.pgdg13+2) 等
Debianbookworm 15.19、trixie 17.11、forky 18.6 仍未修正(open),sid 已是 18.7-1
Ubuntuarchive 最新仍是 jammy 14.24、noble 16.15、resolute 18.6,發布日 2026-08-20
Red Hat評為 Important,CVE 資料仍是 draft,只列 Hardened Images 的 postgresql17、postgresql18、libpq 為 Affected,尚無 RHSA,沒列到的產品不能當成不受影響
RDS、Cloud SQL、AlloyDB、Azure版本頁與 release notes 最新仍是 18.6 這一輪,未見這次修補的公告

代管服務有時會自行回補,版本頁沒列只代表查核時看不到,先用 select version() 看實際跑的版本,再對照各家針對這次漏洞的公告。Supabase、Neon 等其他服務我只用搜尋找過,沒找到聲明。

公開細節、在野攻擊與 KEV

研究者 Mehmet Ince 發表了系列文章描述 CVE-2026-6460 的利用過程,細節已經公開,本文不連結。漏洞彙整站另有標成 PoC 的條目,真偽未驗證。CISA KEV 最新一版是 2026-11-10 發布的 2026.11.10,共 1,779 筆,沒有 CVE-2026-6460,這一版比修補早兩天,能說的只有它還沒列入。

清點與更新步驟

  1. 列出所有 PostgreSQL,連同 standby 與 replica、容器、代管執行個體、跑 pg_dump 與 pg_restore 的備份主機和 CI。
  2. 逐台用 select version() 看實際在跑的版本,套件版本只說明磁碟上裝了什麼。
  3. 有修補版就更新小版本並重啟,不用 dump 再還原。官方公告列了幾項更新後的動作,用 gist_trgm_ops 的 GiST 索引和沒宣告長度的 bpchar 欄位上的 B-tree 索引要 REINDEX,GIN 索引懷疑受損時也要,用增量備份的要重做一次完整備份。
  4. 用到 C 語言 extension 的,要照新版重新編譯,release notes 寫明這樣才算完整防護,有些 extension 還得改原始碼。新增的 composite_type_mismatch 參數可以關掉這批檢查,官方註明關了有安全風險,別拿它當相容性的解法。同一批修補也收緊了 ALTER COLUMN TYPE,例如函式的預設運算式依賴那個 composite type 時就不再允許,migration 可能因此失敗,更新前先在測試環境跑一次。
  5. 等不到修補版的,先限制誰連得到資料庫的 port,再用上面的查詢清點建得了物件的帳號,把用不到的權限收回來。
  6. 還在 14 的,排大版本升級。
# 伺服器實際在跑的版本,以及這台機器上的 client 工具版本
psql --no-psqlrc --tuples-only --command 'select version()'
pg_dump --version

補充筆記

  • 這次更新修補 52 個漏洞,32 個 CVSS 評 8.8,CVE-2026-6460 只是其中之一。
  • 14 到 18 都受影響,修補版是 18.7、17.12、16.16、15.20、14.25,14 從這一版起停止支援。
  • 多數漏洞要先登入並建得了物件,而 TEMPORARY 預設就給了 PUBLIC。
  • 應用程式帳號若擁有資料表,就要當成建得了物件的帳號來看。
  • 收回 TEMPORARY 與 schema 的 CREATE 要逐一資料庫處理,新建的資料庫 TEMPORARY 會再打開,這只是縮小範圍。
  • client 工具也在修補清單上,備份主機與 CI 要一起更新,C 語言 extension 要重新編譯。

延伸閱讀

想法與技術判斷出自 Sheng,和 Claude 一起起草 · Codex 與 Grok 二審;權限清點在 OrbStack 以 postgres:18.7、postgres:14.25 實測,未重現漏洞;資料查核至 2026-11-13 09:50(台北時間)