- 赤色のリンクは、まだ日本語Codex に存在しないページ・画像です。英語版と併せてご覧ください。(詳細)
- この Wiki はいつでも誰でも編集できます。ログインアカウントの取得からどうぞ :)
- 5月23日に MySQL 4.0 → 5 へ移行しました。動作不良等があればご一報ください (連絡先)
データ検証
出典: WordPress Codex 日本語版
信頼できないデータが、さまざまな情報源から入ってきます (ユーザー、第三者のサイト、あなた自身のデータベースも!…)。そして、これらすべては、入力時と出力時の両方で検証する必要があります。
目次 |
出力の無害化
データの無害化 (サニタイズ) する方法は、データの種類およびそれが使われる文脈 (コンテキスト) に依存します。WordPress における共通の処理と、どのように無害化すべきかを以下に示します。
整数値
-
intval( $int )または(int) $int - 整数値を想定するならば、キャストします。
-
absint( $int ) - 結果が非負であると保証されます
HTML/XML
多くの形式の XML 書類 (HTML 書類に対するものとして) は、非常に限られた数の HTML 文字実体参照しか理解しないことに注意してください。テキストを XML 書類として出力するときは、不正な文字実体参照を含むあらゆるテキストを、WordPress の ent2ncr( $text ) 関数を通してフィルターしてください。
HTML/XML の断片
-
wp_kses( (string) $fragment, (array) $allowed_html, (array) $protocols = null ) - KSES は悪意あるスクリプトを除去します。すべての信頼できない HTML (投稿文、コメント文など) は
wp_kses()を通すべきです。使い方やデフォルト値などはwp-includes/kses.phpを見てください。 -
wp_rel_nofollow( (string) $html ) - あらゆる <a> リンクに "rel='nofollow'" 属性をつけます。
テキスト節
-
wp_specialchars( $text )(推奨) - <, &, > をエンコードします。これらを二重にエンコードすることはありません。(訳注: 数値実体参照を使うため、古い携帯電話ではエンコード結果が認識されないことがあります)
-
htmlspecialchars( $text, ENT_NOQUOTES ) - <, &, > をエンコードします。2回実行すると、二重にエンコードされます。
属性値
-
attribute_escape( $text )(推奨) - <, &, >, ", ' をエンコードします。これらを二重にエンコードすることはありません。URL の場合は clean_url() を使ってください (訳注: 数値実体参照を使うため、古い携帯電話ではエンコード結果が認識されないことがあります)
-
htmlspecialchars( $text, ENT_QUOTES ) - <, &, >, ", ' をエンコードします。2回実行すると、二重にエンコードされます。URL の場合は clean_url() を使ってください
JavaScript
-
js_escape( $text ) - ' をエスケープし、" をエンコードします。行末を修正します。
URL
-
clean_url( $url, (array) $protocols = null, $context = 'display' ) - URL を無害化するときは、常に
clean_urlを使ってください (テキスト中、属性値、その他あらゆる場所で)。ホワイトリストで提供されたプロトコル (デフォルトは http, https, ftp, ftps, mailto, news, irc, gopher, nntp, feed, と telnet) を持たない URL は拒否し、不正な文字を排除し、危険な文字を除去します。$contextは以下のいずれかです。 - "display": アンド記号 (&) をエンコードします。
- "url": アンド記号 (&) をエンコードしません。「生」の URL を返します。
- "db": データベースに挿入するとき使います。
-
urlencode( $scalar ) - URL 用にエンコードします (例えば、クエリー文字列に使う場合)
-
urlencode_deep( $array ) - すべての配列要素に urlencode を適用します。
データベース
-
$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, ... ) -
$formatは sprintf() 形式に似た文字列です。%sと%dのみ理解します。どちらもクォート文字で囲む必要はありません。
$wpdb->get_var( $wpdb->prepare( "SELECT something FROM table WHERE foo = %s and status = %d", $name, // 未エスケープの文字列 (関数が無害化します) $status // 信頼できない整数値 (関数が無害化します) ) );
-
$wpdb->escape( $text ) - SQL クエリ用に、1つの文字列をエスケープします。
addslashes()の見せかけです。 -
$wpdb->escape_by_ref( &$text ) - 返り値はありません。
-
like_escape( $string ) - SQL クエリの LIKE 式用に
$stringを無害化します。さらに SQL エスケープする必要があります (上記のいずれかの関数を使う)。
ファイルシステム
-
validate_file( (string) $filename, (array) $allowed_files = "" ) - ディレクトリートラバーサル攻撃を防止します。
$filenameが正当ならば 0 を返します。検証後、$filenameを相対パスとして扱わなければなりません (MUST) (例えば、ABSPATH の後に繋げる等)。なぜなら、"/etc/hosts" はこの関数で正当と判定されるからです。
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 )またはforce_balance_tags( $html ) - 正当な XML 出力になるよう、HTML タグの開き/閉じの釣り合いを取ります。
-
tag_escape( $html_tag_name ) - HTML タグ名を無害化します (関数名と違って、エスケープは何もしません)。
-
is_email( $email_address ) - 真偽値を返します
配列
-
array_map( 'absint', $array ) - 配列要素がすべて非負であることを保証します。あなたのデータに合うようにコールバック関数を入れ替えてください。
検証の哲学
検証をどのように行うか、いくつか異なった哲学があります。どれが正しいかは筋書によって異なります。
ホワイトリスト
既知および信頼された値の一覧にあるデータのみ受理します。
$possible_values = array( 'a', 1, 'good' );
if ( !in_array( $untrusted, $possible_values ) )
die( "やっちゃダメ!" );
// ここで break 文と default アクションに着目
switch ( $untrusted ) {
case 'a' :
...
break;
...
default :
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 );
原文・最新版: WordPress Codex » Data_Validation (最新版との差分)

