こんにちは
それ以降その値をどう扱おうと絶対安全だと考えて間違いないでしょうか?
あらゆるケースを想定した絶対的な安全などはありません。
リファレンス(esc_html)には
HTML ブロックをエスケープします。
とありますが、何かをセキュアにするとは書かれていません。
エスケープされた結果としてセキュアな状態かどうかは使用する側がケースバイケースで判断するしかないでしょう。
また、「HTML ブロックをエスケープ」と書かれているのであって、SQL インジェクションやディレクトリトラバーサルなどその他もろもろの脆弱性をターゲットにして何かの対応がされているわけでもありません。
esc_html()を通せばそれ以降その値をどう扱おうと絶対安全だと考えて間違いないでしょうか?
こちらは、@munyagu さんの書かれている通りです。esc_html() はあくまでも、HTML ブロックをエスケープするだけです。
WordPress Codex 日本語版の「データ検証」ページが参考になると思います。
もしまとめてesc_html()を通す良い方法がございましたらご教授頂けませんでしょうか。
こちらは、下記のようなコードではどうでしょうか?
function esc_arr( $arr ) {
return filter_var( $arr, FILTER_CALLBACK, ["options" => function( $v ) { return esc_html( $v ); }] );
}
@munyagu様、@ishitaka様
ご忠告くださったお二方にまずは感謝申し上げます。
どうもありがとうございます。
ユーザー投稿型サイトを作るにあたって、本文や検索バーでAJAXを使う予定です。
たとえば下記コードは投稿のフローですが、不安点など見えますでしょうか?
※動くことは確認できているので「コードがあってるかどうか見てくれ」ではなくて、「こういうフローで注意すべきこと」や「esc_html()
以外に通すべき関数」などをお伺いできましたら幸いです。
// AJAX
add_action( 'wp_ajax_get_data', 'get_data' );
function get_data() {
// 入力値をエスケープ
$arr = esc_arr( $_POST['arr'] );
// $post_type, $post_title, $post_content, $term_name_arr が展開
extract( $arr );
// 投稿タイプはどちらかのみOK
if( $post_type != 'custom1' && $post_type != 'custom1' ) die();
// タイトルは必須で50文字以内OK
if( ! empty( $post_title ) ) {
$post_title_mblen = mb_strlen($post_title);
if( ! $post_title_mblen || $post_title_mblen > 50 ){
die();
}
}
else{
die();
}
// 本文はもしあれば1000文字以内OK
if( ! empty( $post_content ) ) {
$post_content_mblen = mb_strlen($post_content);
if( ! $post_content_mblen || $post_content_mblen > 1000 ){
die();
}
}
// 投稿
$my_post = array(
'post_title' => $ttl',
'post_content' => $content,
'post_type' => $post_type',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
);
$insert_id = wp_insert_post( $my_post );
// タームを登録
if( ($insert_id) && !is_wp_error($insert_id) ) {
// タームIDを取得
$book_id_arr = my_insert_terms( 'book', $term_name_arr );
// 登録
wp_set_object_terms($insert_id, $book_id_arr, 'book' );
}
}
// タームIDを取得
function my_insert_terms( $taxonomy, $term_name_arr ){
/*
タームがあればIDを返し、なければ登録して返す
@param
$taxonomy : 'book'のみ
$term_name_arr : ユーザーが投稿したターム名の配列
@return
$book_id_arr : 'book'のタームIDの配列
*/
if( $taxonomy=='book' ){
$parent_book = term_exists( 'en', 'book' );
$book_id_arr = [];
foreach( $term_name_arr as $term_name ){
// 既存ならそのままタームのデータを取得
$book_data = term_exists( $term_name, 'book', 'en' );
// もしなければタームを登録
if( !$book_data ){
$book_data = wp_insert_term( $term_name, 'book', array( 'parent'=> $parent_book["term_id"] ) );
}
// タームのlIDを取得
$book_id_arr[] = intval( $book_data['term_id'] );
}
return $book_id_arr;
}
}
// 入力値をエスケープ
function esc_arr( $arr ) {
return filter_var( $arr, FILTER_CALLBACK, ["options" => function( $v ) { return esc_html( $v ); }] );
}
@ishitaka様
便利なfilter_var
に感動しました。上記の通り使わせて頂きたいと思います。
いつも便利な書き方をありがとうございます。