
これはCVE-2025-29927スキャナーです。
これは、Next.js アプリケーションにおける CVE-2025-29927 ミドルウェアバイパス脆弱性を検出するために設計された、プロフェッショナルグレードのスキャナーです。
X-Middleware-Subrequest ヘッダーを使用して内部パスをテストし、Next.js ミドルウェアをバイパスしますpip install -r requirements.txt playwright install
### スキャナーを実行する```bash
python main.py --domain https://example.com --threads 10 --timeout 10 --save
python main.py --help
| オプション | 説明 |
|----------------|--------------------------------------------|
| `--domain` | 対象サイトのベースURL(必須) |
| `--user-agent` | カスタムUser-Agent(デフォルト: Chrome文字列) |
| `--timeout` | リクエストタイムアウト(デフォルト: 10秒) |
| `--proxy` | プロキシアドレス(任意) |
| `--save` | 結果を `results.txt` に保存 |
| `--threads` | スレッド数(デフォルト: 10) |
| `--wordlist` | 一般的なパスを含むワードリスト |
---
## 🐳 Docker の使い方
### Docker イメージのビルド```bash
docker build -t cve-scanner .
docker run -it --rm cve-scanner --domain https://example.com --save
---
## ⚙️ GitHub Actions
このプロジェクトには、プッシュ時のセットアップをテストするためのGitHub Actionsワークフローが含まれています。次の処理を行います:
- 依存関係をインストールします
- Playwrightブラウザをインストールします
- `--help`チェックを実行します
`.github/workflows/python.yml` を参照してください。
---
## 🧱 構造```
.
├── main.py # Entry point
├── config.py # CLI parser
├── crawler.py # Playwright crawler
├── scanner.py # Multi-threaded vulnerability testing
├── requirements.txt
├── Dockerfile
└── .github/workflows
CVE-2025-29927 脆弱性の概要
CVE-2025-29927 は、Next.js の重大なセキュリティ欠陥であり、攻撃者がミドルウェアベースの認証および認可をバイパスすることを可能にします。HTTP リクエストに特別な内部ヘッダー(X-Middleware-Subrequest)を含めることで、攻撃者は Next.js サーバーを欺いてミドルウェアの実行をスキップさせ、保護されたルートへのアクセスを獲得することができます。実際には、通常であれば認証ミドルウェアによってブロックされるリクエスト(例:401/403 を返す、またはログインへリダイレクトする)は、このヘッダーが存在する場合には正常に処理され、実質的にセキュリティチェックをバイパスします。この脆弱性は Next.js バージョン 11.1.4 から 15.2.2 に影響し、管理者はアプリケーションを保護するためにパッチ適用または緩和策(プロキシでこのヘッダーを除去するなど)を実施するよう求められています。
Web アプリケーションでこの脆弱性を検出するには、内部エンドポイントを発見し、悪意のあるヘッダーを付与してテストし、不正アクセスが可能かどうかを確認する必要があります。以下は、ターゲット Web サイトをクロールし(JavaScript フルサポート付き)、CVE-2025-29927 をスキャンして、指定されたすべての要件を満たす高度な Python スクリプトの設計プランです。
JavaScript レンダリングコンテンツを含むディープクロールの要件を満たすために、Playwright を使用します(速度とモダンな API の点で Selenium よりも推奨されます)。Playwright は、動的 Web アプリやモダンな JS フレームワークを処理できる強力なヘッドレスブラウザ自動化ライブラリです。Selenium と比較して、Playwright はよりモダンな API(Chrome DevTools Protocol 上に構築)を提供し、同期および非同期の両方の操作をサポートしており、このユースケースではより良いパフォーマンスを発揮できます。主要なライブラリとそのインストール手順は以下のとおりです:
playwright – ヘッドレスブラウザ自動化用(SPA や JS を必要とするページの読み込み用)。(インストール: pip install playwright を実行し、playwright install でブラウザバイナリを取得)。
requests または httpx – スキャン段階で HTTP リクエストを送信するため。シンプルさなら requests、非同期サポートなら httpx/aiohttp を使用できます。(インストール: pip install requests または pip install httpx)。
bs4 (BeautifulSoup) – HTML を解析し、必要に応じてリンクを抽出するため。Playwright は直接 DOM をクエリできますが、ページの HTML コンテンツに対して BeautifulSoup を使用するとアンカータグを簡単に見つけられます。(インストール: pip install beautifulsoup4)。
concurrent.futures (組み込み) または asyncio – 並行処理を実装するため。マルチスレッドには、Python の concurrent.futures.ThreadPoolExecutor を使用します(追加インストール不要)。非同期アプローチを使用する場合は、Python の asyncio を httpx と組み合わせて並行リクエストを実行できます。
(任意) argparse – インタラクティブメニューの代わりに CLI インターフェースを希望する場合、コマンドライン引数の解析用。(組み込みモジュール)
(任意) rich または colorama – 可読性を高めるためのカラーまたはフォーマット済みコンソール出力用。(インストール: pip install rich または pip install colorama)。
根拠: Playwright は、複雑さを伴わずに動的コンテンツをスクレイピングできるため選択されました。「Playwright を使用すると、ヘッドレスブラウザを自動化して...人間と同じようにウェブを操作できるため、動的な JavaScript 駆動の Web サイトのスクレイピングに最適です」。これにより、スクリプトによって生成されたリンクや UI 要素(単純な requests ベースのクローラーでは見逃すもの)を確実に確認できます。
クローラーモジュールは、Playwright をヘッドレスモードで使用してターゲットサイトのディープクロールを実行します。目的は、JS 実行後にのみ明らかになるものも含め、テスト対象の内部パス(エンドポイント)を発見することです。クローラーの主要な設計ポイント:
ヘッドレスブラウザナビゲーション: Playwright を介して Chromium などのブラウザインスタンスをヘッドレスモードで起動します。ユーザーが指定した場合にはカスタム User-Agent を持つブラウザコンテキストを使用します(詳細は次のセクション)。例えば、browser.new_context(user_agent=<user_agent_string>) でコンテキストを作成し、選択した User-Agent をエミュレートできます。プロキシが設定されている場合は、起動時に適用します(Playwright はブラウザまたはコンテキストの起動時にプロキシサーバーの設定をサポートしています)。
再帰的クロール戦略: 指定されたベース URL(シード)から開始します。page.goto(base_url, timeout=<T>) を使用してページを読み込みます(タイムアウトは設定可能)。必要に応じて、動的コンテンツの読み込みを待つためにネットワークアイドル状態または短い遅延を待機します。その後、リンクを抽出します。リンク抽出は以下のいずれかの方法で行えます:
links = page.evaluate("Array.from(document.querySelectorAll('a[href]'), a => a.href)")、または<a href> 属性を見つける。リンクのフィルタリング: ターゲットドメイン外のリンク(内部に留めるため)を除外します。また、画像、CSS、JS などの静的ファイル URL を無視します。例えば、.css, .js, .jpg, .png, .gif, .svg, .woff などのファイル拡張子を含む URL はスキップします。実用的なアプローチ(ProjectDiscovery テンプレートに着想を得たもの)は、最初のスラッシュの後に「ドット」を含むパスを無視することです。彼らは正規表現パターン href=['"](https://github.com/houmanpashaei/cve-2025-29927/blob/main/%5C/%5B%5E.%5C%22%27%5D%2B)['"] でエンドポイントを抽出しました – これはピリオドを含まない内部パスをキャプチャするため、アセットをスキップします。コード内でも同様のロジックを実装し、静的リソースや外部リンクをキューに入れないようにします。
追跡と深さの制御: 無限ループや繰り返しを避けるために、訪問済み URL のセットを維持します。サイトのリンクグラフを BFS で走査するためにキュー(FIFO)を使用します。必要に応じて、ユーザーがクロール深さの制限や訪問する最大ページ数を指定できるようにし、大規模サイトで無限に実行されるのを防ぎます。
JavaScript レンダリングコンテンツ: 実際のブラウザを使用するため、スクリプトによって DOM に追加されたリンク(例えば、データ取得後にメニューをレンダリングする React アプリなど)もクローラーに表示されます。必要に応じてクリックや操作を検討する必要があります(例:特定のページがユーザーアクション後にのみ読み込まれる場合)。ただし、シンプルかつ高速にするため、初期設計では各読み込みページの href の収集に焦点を当てます。ターゲットアプリケーションが求める場合には、後で無限スクロールやクリックの背後にあるコンテンツの処理に拡張できます。
効率性: Playwright は非同期 API を使用した複数ページ/タブの並列実行をサポートしています。asyncio.gather で複数のページをインスタンス化し、複数のリンクを同時に取得できます。初期実装では、順次クロール(実装が簡単)の方がシンプルで、パフォーマンスはマルチスレッドスキャンに依存する方が良いでしょう。必要に応じて、高度な最適化として非同期クロール(async with async_playwright() を使用し、複数の page.goto 呼び出しを await)が考えられます。ただし、ブラウザ自動化はリソースを多く消費するため、システムに過負荷をかけないよう、一度に 1 つまたは数個のブラウザページに抑える慎重なアプローチが適切です。
スクリプトは起動時にユーザーフレンドリーな設定メニューを表示し、ユーザーがスキャンパラメータをカスタマイズしたりデフォルトを受け入れたりできるようにします。これは、インタラクティブなコンソールメニュー(input() プロンプトを使用)またはコマンドライン引数(よりプロフェッショナルな CLI 感覚のために argparse を使用)で実現できます。オプションには以下が含まれます:
カスタム User-Agent: ユーザーはクローラーとスキャナーが使用するカスタム User-Agent 文字列を指定できます。これは Playwright のブラウザコンテキストと直接の HTTP リクエストの両方に適用されます。非デフォルトの User-Agent を使用すると、簡単なボット検出を回避するのに役立ちます。(デフォルトでは、Playwright は識別可能なものを使用する可能性があるため、上記のように簡単に上書きできます。)例えば、ユーザーが Windows 上の Chrome として識別される文字列を入力し、それを Playwright のコンテキスト作成に渡します。
リクエストタイムアウト: ユーザーはページ読み込みおよび HTTP リクエストのタイムアウト(秒単位)を設定できます。これにより、応答しないエンドポイントでスキャナーが長時間ハングするのを防ぎます。クロールでは page.goto(timeout=...) に、スキャンではリクエスト(例:requests.get(timeout=...))にこの設定を適用します。
プロキシ設定: ユーザーがトラフィックをプロキシ経由でルーティングしたい場合(匿名性のため、または内部ホストに到達するため)、プロキシ URL(および必要に応じて資格情報)を入力できます。スクリプトは Playwright ブラウザを起動時にこのプロキシを使用するように設定します(例:browser.launch(proxy={"server": "http://<proxy_host>:<port>", "username": "...", "password": "..."}) の例のように)。同様に、requests では、それに応じて proxies パラメータ(または環境変数)を設定します。
ファイルへの出力: メニューは、結果をファイル(例:results.txt)に保存するかどうかを尋ねます。「はい」の場合、スクリプトは発見された脆弱なエンドポイントと詳細を画面への表示に加えてこのファイルに書き込みます。そうでない場合、結果は stdout にのみ出力されます。(必要に応じてスキャンされたすべてのパスを詳細ログに記録することはありますが、ファイルはユーザーの好みに応じて陽性結果または完全なレポートを具体的に記録します。)