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);
}
}

