
DefaultParameterFormatterを介したPyAthenaのSQLインジェクション (CVE-2026-65321)
深刻度: 緊急、CVSS v4.0 9.3 / CVSS v3.1 9.8 (CNAであるVulnCheckが割り当て)
ベクター (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
ベクター (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
影響を受けるバージョン: PyAthena <= 3.35.3 (3.35.3までの全バージョン)
修正バージョン: 3.35.4
CWE: CWE-89 (SQLコマンドに使用される特殊要素の不適切な無効化、'SQLインジェクション')
報告者: Rahul Karne
CNA: VulnCheck
公開日: 2026年8月3日
PyAthenaはSELECTクエリでは信頼できない入力を正しくエスケープしていましたが、
DELETEクエリでは誤ってエスケープしていました。
PyAthenaは、Amazon Athena向けの広く使われているPython DB-APIクライアントであり、
ステートメントの先頭キーワードから文字列エスケープルーチンを選択します。
SELECT、WITH、INSERT、UPDATE、MERGEで始まるステートメントには
Trinoで正しいエスケープが適用され、単一引用符は2重化('')によって無害化されます。
その他のすべてのステートメント(最も一般的なのはDELETEまたはCREATE TABLE … AS SELECT(CTAS))は、Hiveスタイルのバックスラッシュエスケープ(\')にフォールスルーします。
AthenaのエンジンはTrinoであり、単一引用符で囲まれた文字列内のバックスラッシュを
通常の文字として扱うため、バックスラッシュエスケープは何も無害化しません。
このようなステートメントの文字列パラメータに影響を与えられる攻撃者は、
リテラルを終了させて任意のSQLを注入でき、認証もユーザー操作も不要です。
したがって、この欠陥は読み取り経路には存在せず、最も大きな被害をもたらす 破壊的なステートメントタイプに正確に存在します。このパッケージは月間2,230万回 ダウンロードされています。
PyAthenaはAmazon Athena向けのサードパーティ製コミュニティクライアントライブラリです。 AWS製品ではなく、これはAWSやAthena自体の脆弱性では ありません。
脆弱なステートメントに渡される文字列パラメータを制御できる攻撃者は、
意図された文字列リテラルを抜け出してステートメントのロジックを変更できます。
最も直接的で確実に実証可能な影響は不正なデータ削除です。
DELETE … WHERE token = %(token)sクエリにおけるmissing' OR 1=1 -- のような
ペイロードは、WHERE述部を無効化し、AthenaワークグループのIAMロールが削除を
許可されているすべての行(たとえばIcebergテーブルのすべての行)を削除します。
ステートメントタイプとロールの権限によっては、攻撃者はCTASインジェクションを
介して攻撃者定義のテーブルを作成できる可能性があり、その後結果のテーブルを
読み取れる場合は、ロールがアクセスできる他のテーブルからデータを外部に
持ち出すこともできます。
すべての影響は、クライアントが使用するAthenaワークグループ/IAMロールの権限に よって制限されます。これはAthenaのSQLエンジンへのデータプレーン注入であり、 PyAthenaを実行しているホストでのコード実行や、AWS自体の侵害には つながりません。
影響を受けるユーザー: デフォルトのDefaultParameterFormatter(クライアント側の
pyformat/namedパラメータ置換)を使用するPyAthena < 3.35.4を使用する
アプリケーションで、(1)SELECT/WITH/INSERT/UPDATE/MERGEで始まらない
ステートメント(実際にはDELETE、CTAS、CREATE VIEW、DROP、ALTER)を構築し、
(2)そのステートメントに攻撃者の影響を受けるデータを文字列パラメータとして渡すもの。
影響を受けないユーザー:
3.35.4以降を使用しているすべての人。SELECT/WITH/INSERT/UPDATE/MERGEで始まる
アプリケーション。これらは安全な引用符2重化エスケーパにルーティングされます。DefaultParameterFormatter.format()は、ステートメントの先頭キーワードのみから
文字列エスケープ関数を選択します。プレフィックスの許可リストのみがTrinoで正しい
エスケーパを受け取り、その他のすべてのステートメントはHiveスタイルの
バックスラッシュエスケープにフォールスルーします。
# src/pyathena/formatter.py, DefaultParameterFormatter.format(), lines ~271-275 (v3.35.2)
operation_upper = operation.upper()
if operation_upper.startswith(("SELECT", "WITH", "INSERT", "UPDATE", "MERGE")):
escaper = _escape_presto # safe: doubles single quotes
else:
escaper = _escape_hive # UNSAFE for Trino: backslash-escapes quotes
# src/pyathena/formatter.py, lines ~157-165 (v3.35.2)
def _escape_hive(val: str) -> str:
escaped = (
val.replace("\\", "\\\\")
.replace("'", "\\'") # produces \' (not a quote escape in Trino)
.replace("\r", "\\r")
.replace("\n", "\\n")
.replace("\t", "\\t")
)
return f"'{escaped}'"
Amazon AthenaのSQLエンジンはTrino(以前のエンジンバージョンではPresto)です。
Trinoでは、単一引用符で囲まれた文字列リテラル内の単一引用符の唯一のエスケープ方法は
2重化('')であり、バックスラッシュはリテラル文字です。したがって、_escape_hiveは
Athenaでは引用符をまったく無害化せず、... = 'missing\' OR 1=1 -- 'を出力します。
Trinoはこれを文字列リテラル'missing\'の後に OR 1=1 -- 'が続くものとして解析します。
つまり攻撃者制御のSQLです。
この設計はフェイルデンジャラスです。安全な経路を許可リストし、それ以外をすべて
安全でないエスケーパにデフォルト設定します。上流の修正はこれをフェイルセーフに
反転させ(Trinoエスケーパをデフォルトにし、CREATE DATABASE/DROP TABLE/MSCK REPAIR
のような真のHive DDLにのみHiveエスケープを使用し、CTASとCREATE VIEWはTrinoとして扱う)、
さらに先頭のSQLコメントを除去して/* … */ DELETE …プレフィックスがステートメント
タイプの検出を無効化できないようにします。
_escape_hiveはサニタイズの欠落ではなく、サニタイズそのものです。これはHiveの
文字列リテラル文法にとって正しく適切に形成されたエスケープルーチンであり、
Trinoの文法を使用するエンジンに適用されています。テイント追跡ツールはSQLインジェクションを、
エスケーパを通過せずにシンクに到達する信頼できないデータとしてモデル化します。
ここではデータはすべての経路でエスケーパを通過し、そのエスケーパは誤った方言用の
修正コードそのものであるため、修正コードとまったく同じに見えます。
方言の正確性はテイントの特性ではないため、テイントルールはそれを評価しません。 この欠陥は、CodeQL、Semgrep、Snyk、Socketによって単に見落とされているのではなく、 構造的に不可視であり、それが約毎秒9回インストールされるパッケージに残存した理由です。
攻撃者には以下が必要です:
pyformat/named paramstyle)を
使用するPyAthena < 3.35.4を使用するターゲットアプリケーション。SELECT/WITH/INSERT/UPDATE/MERGEで始まらないステートメント(実際にはDELETEまたはCTAS)を
構築するコードパス。数値パラメータと、安全なエスケーパにルーティングされるステートメントは、 この欠陥を介して悪用できません。
このPoCは、実際の修正されていないPyAthenaフォーマッタ(再構築ではなく公開された PyPIリリースからインポート)を呼び出し、その出力をローカルのインメモリDuckDB データベースに対して実行します。AWSアカウントも、認証情報も、ネットワークアクセスも 不要です。完全な再現は2つのコマンドです:
pip install pyathena==3.35.2 duckdb
python poc_pyathena_cna_demo.py --no-pause
ソース: poc_pyathena_cna_demo.py
記録デモ: デモを見る
DefaultParameterFormatterのdocstringは、SQLインジェクションを防ぐためにパラメータを
エスケープすると述べています。PoCはそのdocstringを出力し、その後、inspect.getsourceを
介してインストールされたパッケージから直接_escape_presto、_escape_hive、および
プレフィックス選択分岐を出力するため、読者はアドバイザリの言葉を信じるのではなく、
ライブラリ自身のソース内の矛盾を目にします。
DELETE述部の突破攻撃者制御パラメータ: missing' OR 1=1 --
DELETE FROM sessions WHERE token = 'missing\' OR 1=1 -- '
Trinoのレクサーは、単一引用符で囲まれた文字列リテラル内の単一引用符のエスケープとして、
2重化('')の1つだけを認識します。バックスラッシュはエスケープの意味を持ちません。
したがって、リテラルはmissing\に続く引用符で終了し、OR 1=1 --はSQLとして
解析されます。DuckDBもこの特性を共有しており、2行がシードされたsessionsテーブルに
対する結果は次のとおりです:
Rows before executing generated SQL: 2
Rows after executing generated SQL: 0
WHERE述部は無効化され、すべての行が削除されます。
攻撃者制御パラメータ: nobody' UNION SELECT secret FROM admin_credentials --
CREATE TABLE leaked AS SELECT name FROM users WHERE name = 'nobody\' UNION SELECT secret FROM admin_credentials -- '
注入されたUNIONは、元のステートメントが参照していなかったテーブルから行をコピーします。
デモでは、admin_credentialsのDEMO_SECRET_VALUEが攻撃者に見えるleakedテーブルに
入ります。Athenaでは、これはワークグループのIAMロールが読み取れるものに制限されます。
同じペイロードをSELECTとUPDATEにルーティングすると_escape_prestoに到達し、
引用符2重化によって正しく無害化されます:
SELECT name FROM users WHERE name = 'nobody'' UNION SELECT secret FROM admin_credentials -- '
UPDATE update_control SET token = 'x'' OR 1=1 -- ' WHERE id = 999
両方のペイロードは文字列リテラル内に留まります。SELECTは0行を返し、UPDATEは0行を
変更し、突破は発生しません。これらの対照実験は、ハーネスが健全であり、欠陥がテスト設定
ではなくエスケーパ選択に固有であることを立証します。
3.35.4に対する同じ3つのペイロードは、すべて2重引用符出力を生成します:
DELETE FROM sessions WHERE token = 'missing'' OR 1=1 -- '
CREATE TABLE leaked AS SELECT name FROM users WHERE name = 'nobody'' UNION SELECT secret FROM admin_credentials -- '
この修正は、先頭コメントのプレフィックスにも耐えます。そうでなければステートメント タイプの検出を無効化できたはずです:
/* hi */ DELETE FROM sessions WHERE token = 'missing'' OR 1=1 -- '
すべてのケースでペイロードはデータとして封じ込められ、注入は発生しません。
PyAthena 3.35.4以降にアップグレードしてください:
pip install --upgrade "pyathena>=3.35.4"
すぐにアップグレードできない場合: SELECT/WITH/INSERT/UPDATE/MERGEで
始まらないステートメントにパラメータとして信頼できないデータを渡さないようにしてください。
破壊的なステートメントについては、サーバー側で入力を検証/許可リストするか、クライアント側
フォーマッタに依存しない経路で操作を実行してください。影響を受けるバージョンでエスケーパ
選択を変更する設定フラグはありません。アップグレードが信頼できる修正です。
エスケーパを直接インポートするプロジェクトへの注意。 3.35.4の修正は、
DefaultParameterFormatter.format()内のエスケーパ選択を変更します。_escape_hive自体は
変更されず、設計上Hiveには正しくTrinoには誤ったままです。pyathena.formatterから
_escape_hiveまたは_escape_prestoをインポートして独自のステートメントタイプディスパッチを
実行するダウンストリームプロジェクトは、PyAthenaのアップグレードでは修正されないため、
同じ方言の問題について独自のディスパッチロジックを監査する必要があります。
影響を受けているかどうかの確認方法:
pip show pyathena # check the installed version
pip-audit # flags CVE-2026-65321 once it propagates to the advisory feeds
CNAであるVulnCheckは2つのスコアを公開しており、両方とも緊急です:
CVSS v4.0 = 9.3 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N) および
CVSS v3.1 = 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)。
この攻撃はリモートかつ未認証でユーザー操作が不要であり(AV:N/PR:N/UI:N)、攻撃者側の
特別な前提条件も不要です(AC:L/AT:N)。脆弱なシステムへの影響は、機密性、完全性、
可用性のすべてにおいて高です(v4.0ではVC:H/VI:H/VA:H、v3.1ではC:H/I:H/A:H)。
注入されたDELETEはデータを破壊でき、注入されたCTAS/UNION SELECTはワークグループの
ロールがアクセスできるデータを読み取ってコピーできます。v4.0ベクターでは、後続システムの
メトリクスはすべてNone(SC:N/SI:N/SA:N)であり、この欠陥はAthenaのSQLおよび認可境界内に
限定され、ホストでのコード実行やAWS自体へのピボットにはつながりません。
このSC/SI/SA:Nの3つ組こそが、v4.0が最大の10.0ではなく9.3になる理由であり、
「これは完全なシステム侵害を意味するのか?」に対する正直な答えです。そうではありません。
v3.1スコアが9.8に達するのは、そのバイナリスコープフラグ(S:U/S:C)が、v4.0が3つの
別々の後続システムメトリクスに分割するものを1ビットに潰すためです。2つのスコアは矛盾では
なく一貫しています。
先に述べる価値のある注意点が1つあります。現実世界での悪用可能性には、消費側アプリケーションが
信頼できない入力を非SELECTパラメータ化ステートメント(DELETE/CTAS/DROP/ALTER)に
ルーティングすることが必要であり、具体的な爆発半径はAthenaワークグループのIAM権限によって
制限されます。基本スコアは合理的な最悪ケースをモデル化しています。最小権限のデプロイメントは
影響がより軽微です。
発見および報告: Rahul Karne、セキュリティ研究者、IEEEシニアメンバー。彼の研究は 高依存性オープンソースパッケージのインジェクションおよび入力処理の欠陥に焦点を当てており、 以前の開示にはconfluent-kafka(11.2億ダウンロード)、datamodel-code-generator(1億8,500万)、 およびElementsKit ElementorアドオンWordPressプラグイン(100万以上のアクティブインストール)の CVEが含まれます。
連絡先: [email protected] · GitHub: rahulreddykarne
メディア問い合わせ: [email protected]。高解像度のデモ録画、PoC、および追加の 技術的詳細はリクエストに応じて提供されます。
| 指標 | 値 | ソース |
|---|
| 全期間ダウンロード数 | 740.6M | pepy.tech/projects/pyathena |
| 直近30日間のダウンロード数 | 22.3M | pepy.tech |
| 直近24時間のダウンロード数 | 221.0K | pepy.tech |
| 持続的なインストール率 | 8.95/秒 | pepy.tech |
| 注目すべきダウンストリーム | dbt-athenaはpyathena.formatterから_escape_hiveと_escape_prestoを直接インポートします | connections_legacy.py#L23-L27 |
| 日付 | イベント |
|---|
| 2026年7月19日 | 脆弱性を特定 |
| 2026年7月20日 | メンテナに報告 |
| 2026年7月20日 | メンテナが確認 |
| 2026年7月31日 | 修正をコミット |
| 2026年7月31日 | パッチ適用版3.35.4をリリース |
| 2026年8月2日 | VulnCheckがCVE-2026-65321を割り当て |
| 2026年8月3日 | 公開開示 |