WordPressのwp_kses()がHTML APIで刷新、7.2か7.3で導入へ

ニュース

WordPressのHTMLサニタイズ関数 wp_kses() の中身が、HTML APIを使った新しい実装に置き換わろうとしています。2026年10月7日、Make WordPress Coreに進捗報告が公開されました。結論から言うと、関数の使い方(引数・戻り値)は変わりませんが、出力されるHTMLの細かな形は変わります。投入はWordPress 7.2または7.3の見込みで、従来の実装に戻すためのフィルターも用意されています。この記事では、wp_kses() の新実装で変わる点と、テーマ・プラグイン開発者が今のうちに確認しておきたいことを整理します。

ニュースの概要

報告を書いたのは、今回の変更(プルリクエストとコミット)の作成者であるDennis Snell氏です。WordPressは創設当初から、KSESと呼ばれる仕組みで投稿やコメントのHTMLを無害化してきました。しかし元のKSESは、HTML5のパース規則が正式に決まる前に、正規表現と文字列処理を組み合わせて作られたものです。

チケット #66208 の一環として、wp_kses() の実装をHTML APIベースの新しいものに置き換えるプルリクエスト #13271 の内容が、10月7日に開発版(trunk)へコミットされました(r64233)。報告では、いまの wp_kses() の主な役割は「信頼できない入力から危険を取り除くこと」だと整理し、その目的に合わせて作り直すとしています。正式版に入るのは、テスト期間の結果次第でWordPress 7.2か7.3になる見込みです。

wp_kses() の新実装で何が変わるのか

報告に挙げられている主な挙動の変化は次のとおりです。

  • 出力の正規化: タグ名は小文字に、属性値は二重引用符で囲まれ、void要素(imgなど)の不要な自己終了の記号は取り除かれます。例として <IMG class=bike ...> は <img class="bike" ...> になります。文字参照もいったん解釈してから決まった形で書き直されます。
  • 誤って消えていた文章が残る: <$500 … >5yo のような文では、これまで < から > までの文章がまとめて消えていましたが、新実装ではエスケープされて残ります。
  • scriptとstyleは中身ごと削除: 許可されていないscript・style要素は、タグだけでなく中身も消えます。これまでは中身のJavaScriptが文字として残っていました。section などほかの許可されていないタグは、従来どおりタグだけが外れます。
  • 途中で切れた入力は捨てる: 末尾に <butto のような不完全なタグがあると、エスケープせずに破棄します。
  • アンパサンドの扱い: セミコロンのない文字参照の解釈が、テキストと属性で異なります。たとえばテキスト中の &section は「§ion」と解釈されます。URLのクエリでは &amp; と書くことが推奨されています。
  • SVG・MathML: SVG・MathMLの中で解析が複雑になる箇所に当たると処理を打ち切り、SVG・MathMLが始まる手前までを返します。
  • 不正な形式の入力: 不正な形式のHTMLコメントや、noscript要素を含む入力などは拒否されます。CDATAセクションやplaintext要素の中身は、エスケープしたテキストに書き換えられます。

一方で、閉じタグが欠けたHTMLを自動で補わずにそのまま通す、という意図的に使われてきた挙動は残されます。報告では、判断の基準を「以前より悪くしない」ことに置き、安全側に倒した結果として、安全な入力を誤って拒否する場合があることも受け入れるとしています。

従来の実装に戻したい場合は、次のフィルターを使います。

add_filter( 'wp_kses_force_legacy_parser', '__return_true' );

ただし、この従来実装は「当面」残されるだけで、将来のリリースで削除される予定です。7.2.0で削除される可能性もあると書かれています。テストが順調なら、WordPress 7.2.0で移行期間を設けずに置き換える可能性も書かれています。

読者への影響

影響を受けるのは、wp_kses() や wp_kses_post() を通した出力を、文字列として比較・加工しているコードです。たとえば、サニタイズ後のHTMLを正規表現で書き換えている処理や、出力を文字列で完全一致させるユニットテストは、タグの大文字・小文字や引用符の違いだけで結果が変わることがあります。

パフォーマンスについて、報告では新実装は速く、メモリ使用量も少ないとしています。理由として、トークンを1つずつ処理して大きな配列を持たないこと、ブロックの解析を必要なときだけ行うことなどを挙げています。ただし、コメント欄でベンチマークを問われた報告者のDennis Snell氏は、この変更では計測していないと回答しており、HTMLの処理など計算が重くなる部分もあると認めています。計測値にもとづく比較ではない点に注意が必要です。

関数の基本的な使い方は、wp_kses() の使い方とwp_kses_post() の使い方で解説しています。

確認すること

  • 自作のテーマ・プラグインで、wp_kses() の出力を正規表現や文字列比較で扱っている箇所がないか洗い出しましょう。
  • テストで出力を比較している場合は、コメント欄で紹介されている assertEqualHTML() のように、意味のある差分だけを比べる方法に切り替えると、正規化による失敗を避けやすくなります。
  • テーマやプラグインが出力のたびに wp_kses_post() などを通している箇所や、unfiltered_html 権限を持たないユーザーが投稿する経路で、許可されていないscriptやstyleを扱っていないか確認しましょう。新実装では中身ごと消えます。
  • 10月20日予定の7.2 Beta 1や開発版で動作を試し、問題があればチケット #66208 にフィードバックを送れます。7.2のスケジュールはWordPress 7.2は12月8日リリース予定の記事にまとめています。

筆者の見解

私見では、この変更の影響は「KSESがどのタイミングで動くか」で分けて考えるのが実務的だと考えます。保存時にKSESがかかる経路(unfiltered_html 権限を持たないユーザーの投稿やコメント)なら、すでにデータベースにある本文は保存し直すまで変わりません。一方、テーマやプラグインが出力のたびに wp_kses_post() を通している箇所は、更新した直後から表示が変わるため、点検はこちらを先に行うのが効率的です。従来実装に戻すフィルターは手軽ですが、scriptの中身が文字として表示されるといった既存の不具合の修正も一緒に手放すことになり、7.2.0で消える可能性もあるため、テストを直すまでのつなぎと割り切るべきだと考えます。7.2では NO_BACKSLASH_ESCAPES の既定値の変更も重なるので、Beta 1の段階で文字列の比較に頼ったテストをまとめて洗い出しておくと、原因の切り分けが楽になります。

出典(一次情報)

2026年10月14日時点の情報です。

コメント

タイトルとURLをコピーしました