FlawOpen

flawopen.com/Incidents/bricksforge-pro-forms-upload-metadata-october-2026

● Bricksforge WordPress plugin · CVE-2026-85097 · 2026-10-07 · CVSS 9.8 · 緊急
セキュリティ研究 · FlawOpen

CVE-2026-85097:Bricksforge Pro Formsのアップロード不備

CVE-2026-85097では、Bricksforge Pro Formsの一時ファイルで、検証済みの内容とクライアントが指定する保存先メタデータの不一致が悪用可能でした。Patchstackは悪用の試行を報告しています。プラグインを更新し、公開状態だったサイトを調査してください。[1], [2], [3], [4], [5]

💡 わかりやすい解説 (ELI5)

荷物の中身が無害な画像だと確認した郵便室が、特定のラベルをプログラムとして開く部署へ送る直前に、差出人がラベルを付け替えられる状況を想像してください。Bricksforgeは一時アップロードを検査していましたが、その後のフォーム送信で別の保存名を指定できました。ファイルの識別情報と保存先を、処理全体を通じてサーバー側で決めることが対策です。[3], [2]

主要な概念と専門用語

一時アップロード
フォーム送信の完了前に一時保存するファイルです。この段階で検査しても、後からクライアントが送るメタデータは信頼できません。[2], [3]
CWE-434
危険な種類のファイルを制限なくアップロードできる弱点です。ファイルが危険な方法で解釈・実行される可能性があります。[1], [2]
メタデータの信頼境界
名前、URL、MIMEタイプ、パスが信頼できるサーバー記録によるものか、信頼できないクライアントによるものかを判断する地点です。[2], [3]
CVE評価と悪用状況
Wordfence CNAのCVE記録はCVSS 3.1を9.8とし、CISA enrichmentは悪用なしと表示しています。Patchstackは10.0を付け、2026年10月7日に初めて観測したテレメトリを報告しています。これらは各情報源に帰属する別の記録であり、CISA KEVへの登録を示すものではありません。[1], [2], [3], [4]
説明用コード
以下のPHP比較は検証境界を一般化した例です。Bricksforgeのソースコードやパッチの再現ではありません。引用した変更履歴には実装の詳細がありません。[2], [3], [5]

フレームワーク対応

  • このガイドで説明する弱点の CWE 参照: CWE-434

報告されたバージョン情報と運用上の対応

根拠資料記載内容防御側の対応
Wordfence CNA / CVEレコード未認証の任意ファイルアップロードを記載し、登録された影響範囲は3.1.8.9までです。CNAが記録した範囲として扱い、稼働サイトが安全である証拠とはみなさないでください。
Patchstack(2026年10月8日)10月7日に初めて観測した悪用の試みを報告し、3.1.8.10を修正版として示しています。Patchstackが示す修正境界として扱い、各サイトに実際に導入されたプラグインのバージョンを確認してください。
Bricksforge公開変更履歴4.0.1にPro Formsのアップロードに関するセキュリティ修正を記載していますが、3.1.8.10の境界は示していません。変更履歴だけから4.0.1が最初の修正版、または特定の3.x版が安全だと推定しないでください。
外部公開中または侵害が疑われるサイト情報源は悪用の試みを報告していますが、標的となった全サイトの侵害を証明するものではありません。現在サポートされている版へ更新し、復旧完了と判断する前にアップロードとWebサーバーのログを確認し、不審なファイルを調査してください。

インシデントのタイムライン

2026-10-07

Wordfenceはアドバイザリの一般公開日を10月7日と記載しています。Patchstackによると、同日21:47 UTCにテレメトリが最初の試行を観測しました。アドバイザリの公開とテレメトリの観測は別の事象です。[2], [3]

2026-10-08

CVEレコードのdatePublishedは10月8日で、Wordfenceが示す10月7日の一般公開日より1日後です。Patchstackのキャンペーンレポートも公開日を10月8日としています。これは異なるレコードとレポートの公開日です。[1], [2], [3]

2026-10-08

Patchstackの10月8日の分析は、検証の不一致と観測された試行を説明し、3.1.8.10を修正済みとしています。Bricksforgeの変更履歴にはPro Formsのアップロードセキュリティ修正が4.0.1として別途記載されていますが、3.x系列の正確な修正版は確定していません。[3], [4], [5]

ステップ・バイ・ステップの攻撃フロー

ステップ 1

一時ファイルが初期検査を通過する

CNAは、先行する一時アップロードがMIME検証を通過すると説明しています。この検査は、後からファイル名や保存先を任意に変更する権限を与えません。[2], [1]

ステップ 2

フォーム送信で別のメタデータが渡る

Patchstackによると、後続処理はクライアントが送るtemporaryFileUploadsメタデータを信頼し、そのURLは検証済みファイルと異なる場合がありました。検査済みの内容と未検査の保存先が別々に信頼されることが問題です。[2], [3]

ステップ 3

ファイルが危険な名前で配置される

サーバーがアップロード完了時にクライアント指定の保存先を使い、その場所で実行が許可されていると、危険な拡張子によりサーバー側で解釈される可能性があります。ここでは仕組みを高いレベルで説明しており、リクエスト形式やペイロードは不要です。[2], [3]

ステップ 4

公開サイトの侵害につながる可能性

CNAは任意のPHP実行につながる可能性を示しています。Patchstackは試行を報告して更新を推奨していますが、すべての標的サイトの侵害や攻撃者の特定を証明するものではありません。[2], [3]

ソースコード比較:脆弱 vs 堅牢化

この一般的な例は、サーバー管理のアップロード識別子、ユーザー単位の検索、内容タイプの再検証、生成したファイル名、非公開保存を示します。Bricksforgeのコードや実際のパッチではありません。本番コードではサイズ制限、安全な権限、状態遷移の原子性、適切な配信方法も必要です。影響を受けるサイトは、ベンダーがサポートする修正版へ更新してください。[2], [3]

脆弱な実装
function finalize_upload( array $item, string $stagedPath, string $uploadDir ): string {
    // 先行する MIME 検査の後、クライアントのメタデータが最終ファイル名を決めてしまう。
    $name = basename( (string) parse_url( $item['file']['url'], PHP_URL_PATH ) );
    $destination = $uploadDir . DIRECTORY_SEPARATOR . $name;
    if ( ! rename( $stagedPath, $destination ) ) {
        throw new RuntimeException( 'Could not finalize upload' );
    }
    return $destination;
}
堅牢化されたセキュアパッチ
function finalize_upload( string $uploadId, UploadRegistry $registry, string $privateDir ): string {
    // 所有者とパスはサーバー側のレコードから解決し、クライアント URL は使わない。
    $upload = $registry->findPendingForCurrentUser( $uploadId );
    if ( $upload === null || ! is_file( $upload->path ) ) {
        throw new RuntimeException( 'Unknown pending upload' );
    }
    $types = [ 'image/jpeg' => 'jpg', 'image/png' => 'png' ];
    $mime = ( new finfo( FILEINFO_MIME_TYPE ) )->file( $upload->path );
    if ( ! isset( $types[ $mime ] ) ) {
        throw new RuntimeException( 'Unsupported file type' );
    }
    $destination = $privateDir . DIRECTORY_SEPARATOR . bin2hex( random_bytes( 16 ) ) . '.' . $types[ $mime ];
    if ( ! rename( $upload->path, $destination ) ) {
        throw new RuntimeException( 'Could not finalize upload' );
    }
    $registry->markConsumed( $uploadId );
    return $destination;
}

エンジニアリング&システム堅牢化チェックリスト

参考資料