
PostgreSQL 18.6 - 高 - リモート - ファイル書き込み - pg_basebackup が CVE-2026-6475 の絶対 tar シンボリックリンク残存を追跡
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · postgres-basebackup-symlink
解説記事: https://abraxaslabs.tech/research/postgres-basebackup-symlink
クラス: ファイル書き込み 到達範囲: リモート
PostgreSQL 18.6 (724edf9) - PostgreSQL Global Development Group
CVE-2026-6475 では tar のメンバー名に対する path_is_safe_for_extraction が追加された。絶対パスのシンボリックリンクターゲットはテーブルスペースを機能させるため、依然としてこのチェックを回避する。その後 astreamer_file.c がターゲットに対して symlink() を実行し、後で fopen(..., "wb") がそれを辿る。pg_basebackup のデフォルト形式はプレーン (-F p) である。pg_rewind の create_target_symlink はパスをチェックし、リンクは決してチェックしない。
BASE_BACKUP を話す悪意あるソースは、絶対シンボリックリンクを植え付け、バックアップ UID が書き込める任意のファイルを上書きできる。 被害者モデルは 6475 と同じである。これはメンバー名チェックの再報告ではない。
| ID | CVE 未割当 |
| クラス | ファイル書き込み (CVE-2026-6475 の絶対 tar シンボリックリンクの残存) |
| 到達範囲 | リモート (UI:R クライアント対 悪意ある PostgreSQL) |
| CWE | CWE-59, CWE-22 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 製品 | PostgreSQL |
| 影響を受けるバージョン | 18.6 タグ REL_18_6 (724edf9bde9d356724ad384a2e196edc3c9f80f7)、ツリー内の pg_basebackup / pg_rewind |
| 認証 | 被害者がデフォルトの pg_basebackup -D <dir> を攻撃者のソースに対して実行する |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
オペレーターに自身の PostgreSQL に対して pg_basebackup -D を実行させることができる者 (CVE-2026-6475 と同じ UI:R モデル) は、-D の外側に書き込むことができる。
| 権限 | 手法 / シンク | ラボ実証済みか推測か |
|---|---|---|
整合性: -D の外側にファイルを書き込む | 悪意ある BASE_BACKUP tar: 安全な相対名 (pg_tblspc/16384) と絶対リンクターゲットを持つ typeflag '2' メンバー、続いてその名前の下の通常メンバー。extract_link の後 create_file_for_extract が O_NOFOLLOW なしで fopen(..., "wb") を実行する | ラボ実証済み。/work/oracle/ に POSTGRES-BASEBACKUP-SYMLINK-WITNESS を書き込んだ。Dest はシンボリックリンクを保持する。対照 tar (シンボリックリンクなし) はオラクルを空のままにし、-D の内側にのみ PG_VERSION を書き込んだ |
整合性: シェル rc、authorized_keys、systemd ユーザーユニット、または crontab を上書きする | 同じシンク、クライアント UID が書き込める任意のパス | 推測。このラボはそれらのファイルに触れていない |
| 可用性: クライアント設定や鍵を破壊する | 同じ書き込み | 推測。実証されていない |
| クライアントディスクの偵察 | extract は書き込みであり、読み取りではない | 対象外 |
.. や絶対メンバー名を辿る | path_is_safe_for_extraction | 対象外。これは CVE-2026-6475 である |
| サーバー側の非特権 SQL / 未認証プロトコル | 18.6 デフォルトサーバー | 対象外。この残存はクライアント側である |
| tar のみのバックアップ | pg_basebackup -F t は展開せずに tar を保存する | 対象外 |
postgres 内での RCE | このシンクではない | 対象外 |
pg_rewind にも同じ create_target_symlink / open() の残存がある。このラボは pg_basebackup のみを駆動する。
18.6 の波 (28 件の CVE、加えてこのツリーに既にある 18.4/18.2 のセット) の後、postgres/postgres REL_18_6 を固定した。22 回の調査。デフォルトサーバー、非特権 SQL、未認証プロトコル: この基準ではいずれも該当なし。CVE-2026-6475 が再読すべき兄弟であった。
メンバー名はチェックされる。絶対シンボリックリンクターゲットはチェックされない:
if (!is_absolute_path(linktarget) &&
!path_is_safe_for_extraction(member->linktarget))
{
pg_fatal("link target has unsafe path name: \"%s\"",
member->linktarget);
}
extract_link(mystreamer->filename, linktarget);
create_file_for_extract は依然として fopen(filename, "wb") のままです。astreamer_file.c:351-356 のコメントには、リンクが pg_tblspc 内にあるかどうかを確認せずにマッピングが適用されると書かれています。
すでに記録済みの誤った道筋:6475 をクローズ済みとして扱い立ち去ること、-D を稼働中のデータディレクトリに向けること、見せかけのためにシェルの rc を上書きすること。誠実な 18.6 サーバーは pg_tblspc/<oid> シンボリックリンクのみを出力し、テーブルスペースの内容は別のアーカイブに格納します。BASE_BACKUP を話す悪意のあるソースは、後続の通常メンバーを同じ tar に入れることができます。それが残り物です。
python3 postgres-basebackup-symlink-Abraxas-Labs.py
または
cd lab
./run.sh
postgres:18.6 をソースイメージとして使用し、BASE_BACKUP スピーカーを実行します。クライアントは同じタグのツリー内 pg_basebackup(pg_basebackup (PostgreSQL) 18.6)です。ループバック 127.0.0.1:19370。Compose プロジェクト postgres-basebackup-symlink。-D を稼働中のデータディレクトリに向けないでください。
SUCCESS postgres-basebackup-symlink control-inside=yes oracle-outside=yes dest-is-symlink=yes image=postgres:18.6 how=pg_basebackup POSTGRES-BASEBACKUP-SYMLINK-WITNESS
絶対パスのシンボリックリンクターゲットは、--tablespace-mapping によって書き換えられない限り安全でないものとして扱います。抽出ファイルは O_NOFOLLOW / lstat で開き、仕込まれたリンクを辿れないようにします。path_is_safe_for_extraction を path だけでなく link の巻き戻しにも適用します。-D の外に出たシンボリックリンクを経由するパスを持つ通常メンバーは拒否します。
724edf9bde9d356724ad384a2e196edc3c9f80f7)src/fe_utils/astreamer_file.c · src/fe_utils/astreamer_tar.csrc/bin/pg_rewind/file_ops.cGNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。