WordPressには、投稿やコメントに含まれるHTMLから危ないものを取り除く wp_kses() という関数があります。テーマやプラグインの中でも広く呼ばれていて、普段は意識することのない裏方です。この関数の中身を丸ごと作り直す変更について、10月7日付でコア開発者のDennis Snell氏が公式の開発ブログに経過を報告しました。開発版にはすでに取り込まれていて、テストの結果しだいでWordPress 7.2か7.3に入る見込みとされています。
古い作りのままだった理由と作り直す理由
kses はもともと独立したライブラリで、名前はXSSとアクセスを組み合わせたものだそうです。書かれたのはHTML5で構文解析のルールが厳密に定まる前で、HTMLを手で打つのが当たり前だった時代でした。そのため、打ち間違いや貼り付けの崩れを整える役目と、信頼できない入力から危険を取り除く役目の二つを担ってきました。
報告によると、今はブロックエディターのような編集画面から書くのが普通になり、主な役目は後者に絞られています。一方で中身は、正規表現と文字列処理をいくつも連ねた複雑な作りのままでした。新しい実装は、WordPressが整備を進めてきたHTML APIの構文解析器を土台にして、入力をいったん構造として読み取り、そこからHTMLを書き出し直す方式に変わります。報告では、より堅牢で速く、メモリの消費も少ないとされています。
出力されるHTMLはどう変わるのか
関数の呼び出し方は変わらないため、プラグインやテーマの側で書き換えは要らない、というのが基本の説明です。ただし処理の考え方が根本から変わるので、出てくるHTMLの細部は変わります。報告に挙がっている例のうち、制作の現場で目にしそうなものを拾ってみます。
- タグ名は小文字にそろい、属性値は二重引用符で囲まれ、
<img />の末尾のスラッシュは付かなくなる - 本文中に「<500ドル」「>5年」のような不等号を書くと、これまではタグの書きかけと誤解されて間の文章ごと消えることがあったが、新しい実装では正しく残る
- 許可されていない
scriptやstyleは、タグだけでなく中身ごと取り除かれる。これまでは中のJavaScriptが文字として画面に残っていた - 途中で切れた入力は、タグの書きかけに見える末尾を捨てる
- SVGやMathMLの埋め込みで解析が複雑になる書き方は、その手前で打ち切られる
文章が消えにくくなる方向の変更が多い一方で、条件によっては、これまで残っていたものが残らなくなる場合もあります。報告では、この関数が信頼できない入力を扱うものである以上、本来は問題のない入力の一部を拒否してでも、危ない入力を確実に止める側に寄せると説明されています。
アンパサンドの書き方は見直しどころ
地味ですが気をつけたいのが、& の扱いです。HTMLにはセミコロンを省略しても認識される文字参照があり、本文中に ?preview=true§ion=... のようなURLをエスケープせずに書くと、§ の部分が節記号の § に置き換わります。ブラウザがもともとそう解釈する仕様なので、新しい実装もそれに合わせました。報告では、アンパサンドは常に & とエスケープし、文字参照には必ずセミコロンを付けるよう勧めています。記事中でURLの例を紹介することが多い技術ブログやマニュアルのページは、一度見ておいて損はなさそうです。
試す手段と制作会社としての備え
移行期間のあいだは、古い実装に戻すためのフィルター wp_kses_force_legacy_parser が用意されています。add_filter( 'wp_kses_force_legacy_parser', '__return_true' ); の一行で以前の動きに戻せますが、報告では、テストで大きな問題が出なければ7.2の正式版の時点で古い実装ごと取り除かれる可能性にも触れています。戻し道があるうちに、手元で確かめておくのがよさそうです。
確認の手段としては、開発者のRyan Welcher氏が、同じHTMLを新旧の両方に通して並べて表示するデモ用のプラグインを公開しています。WordPress Playgroundを使ってブラウザ上で動く版もあり、気になるHTMLを貼り付けるだけで違いを見比べられます。
制作会社の立場で気になるのは、カスタムHTMLブロック、投稿者権限のユーザーが書く記事、フォームの入力内容を表示する部分、そして独自に wp_kses() を呼んでいるテーマやプラグインです。古い案件ほど、以前の挙動を前提に組まれた処理が残っていることがあります。7.2のベータ版が出たら、ステージング環境で代表的なページを表示して、文章が欠けていないか、余計なコードが見えていないかを確かめておくと、本番の更新で慌てずに済みそうです。













