Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-65321-pyathena — DefaultParameterFormatterを介したPyAthenaのSQLインジェクション (CVE-2026-65321) | Kitploit
ツール/GitHubGitHub/rahulreddykarne/cve-2026-65321-pyathena
脆弱性分析エクスプロイトクラウドセキュリティ学習と教育データベースセキュリティ
GitHubrahulreddykarne/cve-2026-65321-pyathena

CVE-2026-65321-pyathena

DefaultParameterFormatterを介したPyAthenaのSQLインジェクション (CVE-2026-65321)

リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
131ヶ月前未レビュー
共有

CVE-2026-65321: 非SELECTステートメント向けバックスラッシュ引用符エスケープを介したPyAthenaにおけるSQLインジェクション

深刻度: 緊急、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)そのステートメントに攻撃者の影響を受けるデータを文字列パラメータとして渡すもの。

影響を受けないユーザー:

  • PyAthena 3.35.4以降を使用しているすべての人。
  • パラメータ化されたステートメントが常にSELECT/WITH/INSERT/UPDATE/MERGEで始まる アプリケーション。これらは安全な引用符2重化エスケーパにルーティングされます。
  • 信頼できない値をPyAthenaのクライアント側補間ではなく、Athenaのネイティブな サーバー側クエリパラメータを通じてのみ渡すアプリケーション。
  • 信頼できない値や攻撃者の影響を受ける値をパラメータとして渡すことがない アプリケーション(すべてのパラメータが信頼された定数である場合)。

到達範囲

指標値ソース
全期間ダウンロード数740.6Mpepy.tech/projects/pyathena
直近30日間のダウンロード数22.3Mpepy.tech
直近24時間のダウンロード数221.0Kpepy.tech
持続的なインストール率8.95/秒pepy.tech
注目すべきダウンストリームdbt-athenaはpyathena.formatterから_escape_hiveと_escape_prestoを直接インポートしますconnections_legacy.py#L23-L27

技術的詳細

根本原因

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回インストールされるパッケージに残存した理由です。

悪用の前提条件

攻撃者には以下が必要です:

  1. デフォルトのクライアント側パラメータフォーマッタ(pyformat/named paramstyle)を 使用するPyAthena < 3.35.4を使用するターゲットアプリケーション。
  2. SELECT/WITH/INSERT/UPDATE/MERGEで始まらないステートメント(実際にはDELETEまたはCTAS)を 構築するコードパス。
  3. そのステートメントに渡される文字列パラメータに影響を与える能力。
  4. 注入されたSQLを意味のあるものにする権限を持つAthenaワークグループ/IAMロール (例: ターゲットテーブルに対する削除権限、または外部持ち出し経路のための他のテーブルに対する読み取り権限)。

数値パラメータと、安全なエスケーパにルーティングされるステートメントは、 この欠陥を介して悪用できません。

概念実証

この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、および プレフィックス選択分岐を出力するため、読者はアドバイザリの言葉を信じるのではなく、 ライブラリ自身のソース内の矛盾を目にします。

影響A/I: 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述部は無効化され、すべての行が削除されます。

影響C: CTAS外部持ち出しの突破

攻撃者制御パラメータ: 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.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で 始まらないステートメントにパラメータとして信頼できないデータを渡さないようにしてください。 破壊的なステートメントについては、サーバー側で入力を検証/許可リストするか、クライアント側 フォーマッタに依存しない経路で操作を実行してください。影響を受けるバージョンでエスケーパ 選択を変更する設定フラグはありません。アップグレードが信頼できる修正です。

ツールをダウンロード