Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
POC-CVE-2026-65971 — CVE-2026-65971 の概念実証(PoC)および技術解説 — power-components/livewire-powergrid(< 6.10.4)の sortDirection Livewire プロパティを介した SQLインジェクション | Kitploit
ツール/GitHubGitHub/biitts/poc-cve-2026-65971
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト論文と研究学習と教育
GitHubbiitts/poc-cve-2026-65971

POC-CVE-2026-65971

CVE-2026-65971 の概念実証(PoC)および技術解説 — power-components/livewire-powergrid(< 6.10.4)の sortDirection Livewire プロパティを介した SQLインジェクション

リポジトリを見る
192ヶ月前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有

CVE-2026-65971 — Livewire PowerGrid の sortDirection を介したSQLインジェクション

CVE-2026-65971 / GHSA-7fgc-3h6c-698r の概念実証および完全な技術解説。これは power-components/livewire-powergrid におけるSQLインジェクションであり、公開されたLivewireプロパティ sortDirection を介して到達可能です。

CVECVE-2026-65971
GHSAGHSA-7fgc-3h6c-698r
パッケージpower-components/livewire-powergrid (Composer / Packagist)
影響を受けるバージョン>= 6.0.0, < 6.10.4
修正済みバージョン6.10.4
脆弱性CWE-89 — SQLコマンドで使用される特殊要素の不適切な無害化
深刻度7.6 高 — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
報告者Caio Fabrício (@BiiTts)
開示調整済み(GitHub プライベートセキュリティアドバイザリ経由)
├── poc/exploit_powergrid_sqli.py working exploit — confirm + blind extraction
├── lab/ build the vulnerable app to reproduce it yourself
├── evidence/EVIDENCE.txt raw lab notes from confirmation
├── patch/security-fix-v6.10.4.diff the security-relevant portion of the official fix
└── detection/ Sigma rules + Nuclei template for defenders
---

## 🧠 概要

PowerGrid は、Laravel + Livewire 向けの datatable コンポーネントです(約2k スター、Laravel 管理画面で広く使用されています)。そのソート状態は、2つの **public Livewire プロパティ** に保持されています。```php
public string $sortField = 'id';
public string $sortDirection = 'asc';

Livewire では、public プロパティはコンポーネントの wire 形式の一部です。コンポーネントに到達できるクライアントは、POST /livewire/update を通じてその値を設定できます。これは設計によるものであり、セキュリティ境界はサーバーがその値をどう扱うかにあります。

PowerGrid の naturalSort() 機能は、リテラルのプレースホルダー {sortDirection} を含む生の ORDER BY 式を構築し、パイプラインがその文字列を orderByRaw() に渡す前に、そのプレースホルダーを 生の、検証されていないプロパティ値 に置き換えます。そのため、方向キーワードは SQL 内にそのまま埋め込まれます。

Laravel 自身の orderBy() は asc/desc 以外のものを拒否し、その検証によって通常のソート経路は安全になっています。問題は、同じ句に至る検証されていない第二の経路が存在することであり、攻撃者は検証経路を完全にスキップしてそこに到達できます(バイパス を参照)。

結果: ORDER BY 句内での任意の SQL。これはブラインドのブール型/時間ベースのオラクルとして悪用でき、データベースユーザーが読み取れる任意のデータを読み取ることが可能です。


🔥 Impact

naturalSort を使用する PowerGrid テーブルに到達できる者は誰でも、時間ベース/ブール型オラクルを使って、データベースから任意のデータ(他のテーブル、パスワードハッシュ、セッショントークン、API キー、テナント間のレコードなど)を読み取ることができます。

  • 機密性: 高。 DB ユーザーが SELECT できるものはすべて完全に読み取れます。
  • 整合性: 低。 スタッククエリは PDO MySQL のデフォルト設定によってブロックされるため、; UPDATE ... は実行されません。書き込みへの影響は、サブクエリが引き起こせる範囲に限定されます。
  • 可用性: 低。 同じプリミティブによって、攻撃者は SLEEP() や重いサブクエリを実行でき、データベーススレッドを簡単に占有できます。
  • 典型的な配置が悪化要因です。 PowerGrid テーブルは管理パネルやマルチテナントのバックオフィスに配置されます。まさに興味深いデータがある場所です。低権限のテナントユーザーがそのようなテーブルに到達すると、データベース全体を窃取できます。

必要な権限は PR:L です。データテーブルは通常、アプリケーションの認証の背後にあるためです。影響を受けるテーブルが 認証されていない ページで描画される場合は、PR:N で再計算すると 8.2 High(高) になります。


🧩 根本原因 — 完全な汚染チェーン

3つのファイル、3つのステージ。すべての参照は脆弱なタグ v6.10.3 に対するものです。

ステージ 1 — ソース: 攻撃者が制御する public プロパティ

`src/Concerns/Sorting.php````php public string $sortField = 'id'; // line 11 public string $sortDirection = 'asc'; // line 13

どちらのプロパティにもホワイトリスト、検証ルール、正規化セッターはありません。 `sortDirection` は
代入されるか反転されるだけです:```php
public function reverseSort(): string    // line 37
{
    return $this->sortDirection === 'asc' ? 'desc' : 'asc';
}

updatedSortDirection()(103行目)は存在しており、検証を行うのにうってつけの場所ですが、v6.10.3 では遅延ロードに関する簿記処理のみを担当し、その値を検査することはありません。

Livewire はリクエストから直接パブリックプロパティをハイドレートするため、この時点では sortDirection は 任意の文字列として完全に攻撃者によって制御された状態 になります。

ステージ 2 — 素の句: naturalSort() はプレースホルダーを仕込む

src/Providers/Macros.php の 102〜116 行目 — naturalSort カラムマクロ:```php Column::macro('naturalSort', function (bool $when = false, ?string $tableName = null): Column { $this->enableSort();

if ($when) {
    $this->rawQueries[] = [
        'method'   => 'orderByRaw',                          // <-- raw sink
        'sql'      => Sql::sortStringAsNumber($this->dataField),
        'bindings' => [],
    ];
}

return $this;

});

`Sql::sortStringAsNumber()` は、`src/DataSource/Support/Sql.php` (60〜100行目) 内の
`getSortSqlByDriver()` によって構築されるドライバー別の式に解決されます。すべてのドライバーバリアントは
同じリテラルプレースホルダーで終わります:```php
$default = "$sortField+0 {sortDirection}";                                                          // line 76
'8.0.4'  => "CAST(NULLIF(REGEXP_REPLACE($sortField, '[[:alpha:]]+', ''), '') AS SIGNED INTEGER) {sortDirection}",  // MySQL, line 81
'0'      => "CAST($sortField AS INTEGER) {sortDirection}",                                          // SQLite, line 84
'0'      => "CAST(NULLIF(REGEXP_REPLACE($sortField, '\D', '', 'g'), '') AS INTEGER) {sortDirection}", // PgSQL, line 87
'0'      => "CAST(SUBSTRING(...) AS INT) {sortDirection}",                                          // SQL Server, line 90

この脆弱性は ドライバ非依存 です — すべての分岐が {sortDirection} を補間します。

ステージ 3 — シンク: プレースホルダーは生のプロパティ値で解決される

`src/DataSource/Processors/Database/Pipelines/ColumnRawQueries.php````php private function resolvePlaceholders(?string $sql): ?string // line 56 { if (is_null($sql)) { return null; }

return preg_replace_callback('/\{(\w+)\}/', function ($matches) {
    $property = trim($matches[1]);

    return data_get($this->component, $property, '');   // line 65 — raw property, no escaping
}, $sql);

}

そして実行、52行目:```php
$query->{$method}($resolvedSql, $resolvedBindings);   // $method === 'orderByRaw'

data_get($this->component, 'sortDirection') は攻撃者の文字列を返し、preg_replace_callback はそれを SQL テキストに挿入し、orderByRaw() — 仕様上、その引数をエスケープしない — はそれをデータベースに渡します。

すぐ下の行にある皮肉に注目してください: resolveBindings() (69行目) は存在し、naturalSort は 'bindings' => [] を宣言しています。安全なパラメータ化の仕組みはまさにそこにあるのです。しかし、 方向キーワードには使えません — ORDER BY x ? は有効な SQL ではなく、方向をバインド パラメータにすることは決してできないからです — まさにそのため、方向キーワードは代わりに許可リスト方式にしなければなりません。

一行で表すチェーン```

POST /livewire/update ──▶ public string $sortDirection (Sorting.php:13, no validation) ──▶ data_get($component, 'sortDirection') (ColumnRawQueries.php:65) ──▶ "CAST(...) {sortDirection}" → "CAST(...) asc, (SELECT SLEEP(3))" ──▶ orderByRaw($sql) (ColumnRawQueries.php:52) ──▶ MySQL/MariaDB/PgSQL/SQLite/MSSQL

---

## 🔓 バイパス — Laravelのバリデーションでは救われない理由

ここが「生の補間」を実際に悪用可能なバグへと変える部分であり、成熟した広く使われているパッケージでこの問題が生き残った理由でもあります。

PowerGridはクエリを**パイプライン**で処理します。そのパイプラインの2つのステージがソート方向に触れます。

**`Sorting` パイプライン** — `src/DataSource/Processors/Database/Pipelines/Sorting.php`:```php
public function handle(mixed $query, Closure $next): mixed
{
    // ...
    if (filled($this->component->sortField)) {          // line 21  <-- THE GUARD
        if ($this->component->multiSort) {
            $this->applyMultipleSort($query);
        } else {
            $this->applySingleSort($query, $this->component->sortField, $this->component->sortDirection);
        }
    }

    return $next($query);
}

private function applySingleSort(..., string $sortField, string $direction): void
{
    // ...
    $query->orderBy($this->component->resolveSortField($sortField), $direction);   // line 42
}

orderBy() は Laravel の 検証 API です。asc/desc 以外のものを渡すと、例外が スローされます:``` InvalidArgumentException: Order direction must be "asc" or "desc".

つまり、通常の経路では — ユーザーが列ヘッダーをクリックし、`sortField=name`、`sortDirection=<payload>` —
フレームワークはインジェクションをブロックします。簡単な監査はここで止まり、「Laravel によって緩和されている」と結論づけます。

**`ColumnRawQueries` パイプライン** — 上に示した2番目のステージ — には**そのようなガードはありません**。見てください
その `handle()`(21〜27行目): 列を反復処理し、`rawQueries` を持つすべての列に対して、
それらを*無条件に*適用します。`sortField` を参照することはありません。`Sorting`
パイプラインの結果を参照することもありません。

この非対称性がバグです。

| `sortField` | `Sorting` パイプライン | `ColumnRawQueries` パイプライン | 結果 |
|---|---|---|---|
| `"name"` (入力あり) | 実行 → `orderBy()` が**検証** → ペイロードで例外をスロー | 実行 → インジェクション | ❌ 例外でブロック |
| `""` (空) | `filled('')` は `false` → **完全にスキップ** | 実行 → インジェクション | ✅ **インジェクションが成立** |
ツールをダウンロード