WordPressのHTMLサニタイゼーション関数について
HTMLサニタイゼーション関数は、ユーザーから入力されたHTMLコードから危険な要素を除去し、安全なコンテンツのみを保持する重要なセキュリティ機能です。
WordPressカスタマイズにおいて、この機能はXSS(クロスサイトスクリプティング)攻撃の防止に不可欠です。悪意のあるJavaScriptコードや不正なHTMLタグが投稿やコメントに混入することを防ぎ、サイトの安全性を確保します。
特にカスタムフィールドやユーザー投稿機能を実装する際、wp_kses()、wp_kses_post()、wp_strip_all_tags()などの関数を適切に使い分けることで、必要なHTMLタグのみを許可し、セキュリティリスクを最小限に抑えられます。
これらの関数は単なるセキュリティ対策にとどまらず、コンテンツの品質管理やSEO最適化にも貢献します。メタディスクリプション生成時にHTMLタグを除去したり、検索機能でのテキスト比較を正確に行うなど、WordPress開発における基礎的かつ重要な機能として位置づけられています。
wp_strip_all_tags()
基本機能
すべてのHTMLタグを完全に削除し、純粋なテキストのみを残します。
使用例
$html = '<wp-p>こんにちは<strong>世界</strong>!<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3Ealert(%22%E5%8D%B1%E9%99%BA%22)%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" /></wp-p>'; $clean_text = wp_strip_all_tags($html); // 結果: "こんにちは世界!alert("危険")"
パラメータ
wp_strip_all_tags($string, $remove_breaks = false)
-
$string
: 処理対象の文字列 -
$remove_breaks
: true の場合、改行も削除
適用場面
-
メタディスクリプション生成 -
検索機能での文字列比較 -
プレーンテキストが必要な場面
wp_kses_post()
基本機能
WordPressの投稿で許可されている安全なHTMLタグのみを保持します。
許可されるタグの例
// 許可されるタグ(一部) $allowed_tags = array( 'a' => array('href', 'title', 'class', 'id'), 'p' => array('class', 'id'), 'strong' => array('class'), 'em' => array('class'), 'img' => array('src', 'alt', 'width', 'height', 'class'), 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'blockquote' => array('cite'), // など );
使用例
$html = '<wp-p>安全なコンテンツ</wp-p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3Ealert(%22%E5%8D%B1%E9%99%BA%22)%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />'; $safe_html = wp_kses_post($html); // 結果: "<wp-p>安全なコンテンツ</wp-p>alert("危険")"
適用場面
-
ユーザー投稿の保存前処理 -
コメントの表示 -
カスタムフィールドの出力
wp_kses()
基本機能
指定したHTMLタグとその属性のみを許可する、最も柔軟なサニタイゼーション関数です。
使用例
// 基本的な使用方法 $allowed_html = array( 'p' => array( 'class' => array(), 'id' => array(), ), 'a' => array( 'href' => array(), 'title' => array(), 'target' => array(), ), 'strong' => array(), 'em' => array(), ); $html = '<wp-p class="text">テスト<a href="#" onclick="alert()">リンク</a></wp-p>'; $clean_html = wp_kses($html, $allowed_html); // 結果: '<wp-p class="text">テスト<a href="#">リンク</a></wp-p>'
高度な設定例
// より詳細な制御 $allowed_html = array( 'img' => array( 'src' => array(), 'alt' => array(), 'width' => array(), 'height' => array(), 'class' => array(), 'style' => array(), // CSSも制御可能 ), 'div' => array( 'class' => array(), 'data-*' => true, // data属性を許可 ), ); // プロトコル指定も可能 $allowed_protocols = array('http', 'https', 'mailto'); $clean_html = wp_kses($html, $allowed_html, $allowed_protocols);
実用的な使い分け
1. セキュリティレベル別使い分け
// 最高セキュリティ:HTMLを一切許可しない $title = wp_strip_all_tags($user_input); // 高セキュリティ:投稿レベルのHTMLのみ許可 $content = wp_kses_post($user_input); // カスタムセキュリティ:特定のタグのみ許可 $custom_content = wp_kses($user_input, $custom_allowed_tags);
2. 用途別実装例
// カスタムフィールド保存時 function save_custom_field($value) { $allowed_html = array( 'p' => array('class' => array()), 'br' => array(), 'strong' => array(), 'em' => array(), ); return wp_kses($value, $allowed_html); } // ユーザープロフィール表示 function display_user_bio($bio) { // リンクのみ許可 $allowed_html = array( 'a' => array( 'href' => array(), 'title' => array(), 'target' => array(), ) ); return wp_kses($bio, $allowed_html); } // 検索用テキスト準備 function prepare_search_text($content) { return wp_strip_all_tags($content, true); // 改行も削除 }
3. パフォーマンス考慮
// 重い処理なので、必要な時のみ実行 function sanitize_content($content, $context = 'post') { switch ($context) { case 'title': return wp_strip_all_tags($content); case 'excerpt': return wp_kses_post($content); case 'custom': return wp_kses($content, get_custom_allowed_html()); default: return wp_kses_post($content); } }