• 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細

このWikiはいつでも誰でも編集できます

データ検証

提供: WordPress Codex 日本語版
2009年4月15日 (水) 02:44時点におけるLily (トーク | 投稿記録)による版 (新規翻訳)

(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

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

出力の無害化

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

整数値

intval( $int ) or (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 ) (preferred)
<, &, > をエンコードします。これらを二重にエンコードすることはありません。(訳注: 数値実体参照を使うため、古い携帯電話ではエンコード結果が認識されないことがあります)
htmlspecialchars( $text, ENT_NOQUOTES )
<, &, > をエンコードします。2回実行すると、二重にエンコードされます。

属性値

attribute_escape( $text ) (preferred)
<, &, >, ", ' をエンコードします。これらを二重にエンコードすることはありません。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, ... )
$formatsprintf() 形式に似た文字列です。%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 ) or force_balance_tags( $html )
正当な XML 出力になるよう、HTML タグの開き/閉じの釣り合いを取ります。
tag_escape( $html_tag_name )
HTML タグ名を無害化します (関数名と違って、エスケープは何もしません)。

Email

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最新版との差分