Stored XSS は、悪意のあるスクリプトがサーバーに保存され、その後他のユーザーがそのページを開いたときに自動的に実行される脆弱性であり、CWE-79 (Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) に指定されている攻撃の一種です。
WordPress は、世界中で最も人気のあるオープンソース CMS (コンテンツ管理システム) であり、ウェブサイトやブログを簡単に構築・管理できるようにします。ユーザーはコードの知識がなくても、さまざまなプラグインやテーマを通じてサイトを拡張し、カスタマイズできます。
WP Activity Log は、WordPress サイトの管理アクティビティを追跡・記録するプラグインです。管理者はサイトで発生するさまざまなイベントをリアルタイムで監視し、セキュリティ監査やトラブルシューティングのためのログを提供するのに役立ちます。
CVE-2025-0924 は、WP Activity Log プラグイン (バージョン 5.2.2 以下) において、'message' パラメータでの入力検証不足と出力エスケープの不備により発生します。本分析では、この脆弱性がどのように発生するかを調査し、それに対する対応策を検討します。
WordPress でユーザーがサイトタイトルに悪意のあるスクリプトをコピー&ペーストし、その変更が WP Activity Log 5.2.2 を通じてログに記録されると、Stored XSS 攻撃が発生します。例を通して、WP Activity Log を使用してどのように Stored XSS が引き起こされるのかを確認します。
[図1] WordPress 記事作成、DB スクリプト挿入
投稿作成後、データベースを確認すると、コピー&ペーストした投稿の場合、post_title フィールドの値が適切に sanitize (入力値の整理とフィルタリング) されずに保存されている現象を確認できます。
これは、入力方式によってデータの処理が異なる可能性を示唆しており、XSS (クロスサイトスクリプティング) 脆弱性が発生する原因となる可能性があります。
[図2] WP Activity Log ログ作成と攻撃確認
[図3] class-list-events.php - More details... return
[図4] AuditLog.php -> AjaxInspector() - non sanitize
[図4] metadata サンプル
これまで、WordPress のセキュリティログプラグインである WP Activity Log を通じて Stored XSS について見てきました。この場合、ユーザーがページを作成し、ログにスクリプトの内容をアップロードできるだけで発生するため、対応策として WP Activity Log 5.2.2 以上から 5.3.0 へのアップデートを提案します。
[図5] AjaxInspector の変更点 / esc_html() の追加
この事例では、結果の HTML を返す際に esc_html() を使用して適切にサニタイズしなかったために発生した問題と思われます。ただし、この分析が CVE-2025-0924 で説明されている脆弱性と正確に一致するかどうかについては、まだ確信が持てません。
現在、5.3.0 バージョンにアップグレードした後にテストを実施し、対策が行われたことを確認しましたが、CVE-2025-0924 で説明されている脆弱性 Stored Cross-Site Scripting via the ##message## parameter を通じて行われ、class-alert.php、class-alert-manager.php がパスとして明記されています。
しかし、私の分析では、message パラメータではなく meta data が問題であり、過程で問題となるパスの PHP は class-list-events.php、AuditLog.php であるため、NIST の説明と一致する部分は Stored Cross-Site Script 以外はすべて異なります。そのため、正確な一致の有無については、追加の調査が必要です。