当サイト、Codex 日本語版は今後積極的な更新は行わない予定です。後継となる新ユーザーマニュアルは、https://ja.wordpress.org/support/ にあります。
万が一、当サイトで重大な問題を発見した際などは、フォーラムWordSlack #docs チャンネルでお知らせください。</p>

データ検証

提供: WordPress Codex 日本語版
2015年6月13日 (土) 22:39時点におけるMiccweb (トーク | 投稿記録)による版 (出力の無害化: en link)

移動先: 案内検索

信頼できないデータが、さまざまな情報源から入ってきます (ユーザー、第三者のサイト、あなた自身のデータベースも!…)。そして、これらすべては、入力時と出力時の両方で検証する必要があります。

データの無害化 (サニタイズ) をする方法は、データの種類およびそれが使われる文脈 (コンテキスト) に依存します。WordPress における共通の処理と、どのように無害化すべきかを以下に示します。

ヒント : 出力の検証は、可能な限り遅く行うことがよいでしょう。スクリプトでは、出力をする、まさにその時に検証するのが理想です。こうすることで、常にデータが適切に検証/エスケープされていることが確認でき、変数が既に検証されているか覚えておく必要はありません。

整数値

intval( $int ) または (int) $int
整数値を想定するならば、キャストします。
absint( $int )
結果が負でないことを保証します。

HTML/XML

(HTML文書に対して) 多くの形式のXML文書が理解する文字実体参照は &apos;&amp;&gt;&lt;&quot; の5つのみであることに注意してください。テキストを XML 書類として出力するときは、不正な文字実体参照を含むあらゆるテキストを、WordPress の ent2ncr( $text )/en 関数を通してフィルターしてください。

HTML/XML の断片

wp_kses( (string) $fragment, (array) $allowed_html, (array) $protocols = null ) /en
KSES は悪意あるスクリプトを除去します。すべての信頼できない HTML (投稿文、コメント文など) は wp_kses() を通すべきです。使い方やデフォルト値などは wp-includes/kses.php を参照してください。
許可する HTML タグの配列を wp_kses() に渡す代わりに、 wp_kses_post( (string) $fragment ) /en を用いて投稿やページで許可されるタグを定義したり、 wp_kses_data( (string) $fragment ) を用いてコメントで許可されるタグのリストを定義することができます。
wp_rel_nofollow( (string) $html ) /en
あらゆる <a> リンクに "rel='nofollow'" 属性をつけます。
wp_kses_allowed_html( (string) $context ) /en
所定のコンテキストで許可される HTML タグの配列を提供します。許可されるものは、post | strip | data | entitiespre_user_description のようなフィールドフィルターです。

テキスト節

esc_html( $text )/en (Version 2.8 以降)
「< (小ナリ)」、「> (大ナリ)」、「& (アンド)」、「" (ダブルクォーテーション)」、「' (シングルクォーテーション)」 をエンコードします。esc_attr と非常に良く似ています。
esc_html__ /en (Version 2.8 以降)
翻訳、エンコードをします。
esc_html_e /en (Version 2.8 以降)
翻訳、エンコード、出力をします。
esc_textarea /en (Version 3.1 以降)
テキストエリアの要素をエンコードします。
sanitize_text_field /en (Version 2.9.0 以降)
ユーザーからの入力又はデータベースからの入力を無害化します。

属性値

esc_attr( $text ) (Version 2.8 以降)
esc_attr__()
翻訳、エンコードをします。
esc_attr_e()
翻訳、エンコード、出力します。

JavaScript

esc_js( $text ) /en (Version 2.8 以降)

URL

esc_url( $url, (array) $protocols = null ) (Version 2.8 以降)
URL を無害化するときは、常に esc_url を使ってください (テキスト中、属性値、その他あらゆる場所で)。ホワイトリストで提供されたプロトコル(デフォルトは http ならびに httpsftpftpsmailtonewsircgophernntpfeedtelnet)を持たない URL は拒否し、不正な文字を排除し、危険な文字を除去します。3.0 で非推奨とされた clean_url() の代わりに使います。
この関数は文字を HTML 実体にエンコードします。(X)HTML あるいは XML 書類を生成するときはこの関数を使ってください。アンド (&) とシングルクォートは (') 数値実体参照 (&#038, &#039) にエンコードします。
esc_url_raw( $url, (array) $protocols = null ) /en (Version 2.8 以降)
URL をデータベースに格納するための関数です。この関数は文字を HTML 実体にエンコードしません。URL をエンコードしない形で保存したいときはこの関数を使ってください。 この機能は古い関数 clean_url 関数の $contextdb に設定するのと同等です。
urlencode( $scalar ) /en
URL をエンコードします。(例えば、クエリパラメータで使用する、など)
urlencode_deep( $array ) /en
配列の全要素を URL エンコードします。

データベース

$wpdb->insert( $table, (array) $data )
$data は未エスケープとしてください (この関数がエスケープしてくれます)。配列キーがカラム、配列値がデータベース値になります。
$wpdb->update( $table, (array) $data, (array) $where )
$data は未エスケープとしてください。配列キーがカラム、配列値がデータベース値になります。$where は未エスケープとしてください。複数の WHERE 節は AND で連結されます。
$wpdb->update(
  'my_table',
  array( 'status' => $untrusted_status, 'title' => $untrusted_title ),
  array( 'id' => 123 )
);
$wpdb->prepare( $format, (scalar) $value1, (scalar) $value2, ... )
$formatsprintf() 形式に似た文字列です。%s%d のみ理解します。どちらもクォート文字で囲む必要はありません。
$wpdb->get_var( $wpdb->prepare(
  "SELECT something FROM table WHERE foo = %s and status = %d",
  $name, // 未エスケープの文字列 (関数が無害化します)
  $status // 信頼できない整数値 (関数が無害化します)
) );
esc_sql( $sql )
$wpdb->escape() のエイリアス。
$wpdb->escape( $text )
3.6から非推奨になりました。esc_sql() または $wpdb->prepare() を代わりに使ってください。
$wpdb->escape_by_ref( &$text )
返り値はありません。パラメータが参照で渡されるので、テキストが直接変更され、返り値を割り当てる必要がありません。
like_escape( $string )(4.0にて非推奨)
SQL クエリの LIKE 式用に $string を無害化します。さらに SQL エスケープする必要があります (上記のいずれかの関数を使う)。

ファイルシステム

validate_file( (string) $filename, (array) $allowed_files = "" ) /en
ディレクトリートラバーサル攻撃を防止する、あるいはファイル名がホワイトリストにあるか確認します。$filename が正答な相対パスならば 0 を返します。検証後、$filename を相対パスとして扱わなければなりません (MUST) (例えば、ABSPATH の後に繋げる等)。なぜなら、/etc/hosts はこの関数で正当と判定されるからです。返り値が正の整数の場合は、.., ./, あるいは : がパスに含まれているか、または $allowed_files ホワイトリストに含まれていません。この結果を真偽判定する場合は注意してください。false (0) はファイル名が検証を通過したことを示し、true (> 0) は検証されなかったことを示します。

HTTP ヘッダ

ヘッダ分割攻撃は、HTTP クライアントに依存するため、やっかいなものです。 WordPress は、HTTP ヘッダにユーザーが生成した内容を含む必要はほとんどありませんが、それを行うならば、WordPress は HTTP ヘッダの多くにホワイトリストを用います。

WordPress は、HTTP のロケーションヘッダにユーザーが生成した内容を使えますが、以下のように無害化できます。

wp_redirect($location, $status = 302)
あらゆる URL に対する安全なリダイレクト方法です。結果の HTTP ロケーションヘッダが妥当であることを保証します。
wp_safe_redirect($location, $status = 302)
さらに安全です。ホワイトリストにあるドメインしかリダイレクトしません。

入力の検証

出力の無害化に挙げられた多くの関数は、入力の検証にも使えます。 さらに、WordPress は以下の関数を使っています。

スラッグ

sanitize_title( $title )
投稿スラッグなどに使われています。
sanitize_user( $username, $strict = false )
新規ユーザーを作成するときは $strict を使ってください (API でユーザー追加するとき)。

HTML

balanceTags( $html ) or force_balance_tags( $html )
正当な XML 出力になるよう、HTML タグの開き/閉じの釣り合いを取ります。
tag_escape( $html_tag_name )
HTML タグ名を無害化します (関数名と違って、エスケープは何もしません)。
sanitize_html_class( $class, $fallback )
HTML クラス名を無害化し、妥当な文字列のみを含むことを保証します。A-Z,a-z,0-9,'-' に限定します。結果が空文字列になる場合は、第二引数で与えられた代替文字列を返します。

Email

is_email( $email_address )
妥当でない場合は false を返し、妥当な場合は $email_address を返します。

配列

array_map( 'absint', $array )
配列要素がすべて非負であることを保証します。あなたのデータに合うようにコールバック関数 'absint' を入れ替えてください。array_map() は PHP コアの関数で、配列の要素に任意のコールバック関数を実行します。この例ではコールバック関数は absint() です。

その他

その他の、データの無害化に役立つ関数です。

検証の哲学

検証をどのように行うか、いくつか異なった哲学があります。どれが正しいかは筋書によって異なります。

ホワイトリスト

既知および信頼された値の一覧にあるデータのみ受理します。

When comparing untrusted data against the whitelist, it's important to make sure that strict type checking is used. Otherwise an attacker could craft input in a way that will pass the whitelist but still have a malicious effect.

比較演算子

$untrusted_input = '1 malicious string';  // will evaluate to integer 1 during loose comparisons

if ( 1 === $untrusted_input ) {  // == would have evaluated to true, but === evaluates to false
	echo '<p>有効なデータ';
} else {
	wp_die( '不正なデータ' );
}

in_array()

$untrusted_input = '1 malicious string';  // will evaluate to integer 1 during loose comparisons
$safe_values     = array( 1, 5, 7 );

if ( in_array( $untrusted_input, $safe_values, true ) ) {  // `true` enables strict type checking
	echo '<p>有効なデータ';
} else {
	wp_die( '不正なデータ' );
}

switch()

$untrusted_input = '1 malicious string';  // will evaluate to integer 1 during loose comparisons

switch ( true ) {
	case 1 === $untrusted_input:  // do your own strict comparison instead of relying on switch()'s loose comparison
		echo '<p>有効なデータ';
		break;

	default:
		wp_die( '不正なデータ' );
}


ブラックリスト

既知の信頼できない値の一覧にあるデータを拒否します。これがよい方法であることは、めったにありません。

書式の検出

データが正しい書式であるかテストします。正しい場合のみ受理します。

if ( !ctype_alnum( $data ) )
  die( "あなたのデータは※△□%&〒☆" );
if ( preg_match( "/[^0-9.-]/", $data ) )
  die( "浮動小数じゃない? おバカ!" );

書式の訂正

ほとんどのデータを受理し、危険な部分を除去または変更します。

$trusted_integer = (int) $untrusted_integer;
$trusted_alpha = preg_replace( '/[^a-z]/i', "", $untrusted_alpha );
$trusted_slug = sanitize_title( $untrusted_slug );

変更履歴

  • 3.6: $wpdb->escape() の代わりに esc_sql()$wpdb->preapre() が推奨となりました。
  • 3.1: esc_textarea が導入されました。 (#15454)
  • 3.0: clean_url() の代わりに esc_url()esc_url_raw() が推奨となりました。 (#12309)
  • 2.8: 以下の関数が非推奨となりました。(via WordPress Development Updates)
    • sanitize_url() -> esc_url_raw()
    • wp_specialchars() -> esc_html() (also: esc_html__() and esc_html_e())
    • attribute_escape() -> esc_attr() (also: esc_attr__() and esc_attr_e())

外部資料

このページ「データ検証」は一部未翻訳です。和訳や日本語情報を加筆してくださる協力者を求めています

最新英語版: WordPress Codex » Data Validation最新版との差分