Hatena::ブログ(Diary)

xmallocのプログラミングノート

2010年02月14日

WordPressに学ぶ、magic_quotes_gpcの影響の除去

WordPressプラグインを作成された方はご存知だと思いますが、WordPressではphp.ini等による実行時設定が処理に影響しないようにするため、magic_quotes_gpcが真か偽かに関わらず、$_GETや$_POSTの値を、常にmagic_quotes_gpcが有効であるかのように振る舞うよう前処理します。具体的にはmagic_quotes_gpcが真ならstripslashesを行い、その後addslashesを行います。


WordPressに限らず、どのサーバでも動くようなコードを書こうとすると似たような処理が必要になりますので、関係箇所をまとめてみました。ライセンスの関係(WordPressGPL)でそのままコピペするとまずいプロジェクトも多々あるかと思いますが、知識として仕込んで置くと便利かと思います。

サーバの設定依存という意味では、mbstringの設定値に関係する部分もあわせて前処理しておくと、環境依存箇所のほとんどを無くすことができますが、こちらについては今日は触れません。気が向いたら日を改めて書きたいと思います。


では具体的にWordPressのソースを見ていきます。引用元はWordPress-2.7.1jaですが、より新しいバージョンのWordPressでもこの辺の処理はあまり変わらなかったと思います。

まずwp-settings.phpでstripslashes_deepとadd_magic_quotesを呼び出します。get_magic_quotes_gpcはmagic_quotes_gpcが真か否かを返すPHP関数です。(以下のコードには<?php … ?>が含まれていますが、はてなの構文ハイライトを有効にするためです。実際のコードと<?phpの現れる位置が違いますがあまり気にしないでください。)

<?php
// If already slashed, strip.
if ( get_magic_quotes_gpc() ) {
        $_GET    = stripslashes_deep($_GET   );
        $_POST   = stripslashes_deep($_POST  );
        $_COOKIE = stripslashes_deep($_COOKIE);
}

// Escape with wpdb.
$_GET    = add_magic_quotes($_GET   );
$_POST   = add_magic_quotes($_POST  );
$_COOKIE = add_magic_quotes($_COOKIE);
$_SERVER = add_magic_quotes($_SERVER);
?>

stripslashes_deepはその名のとおりstripslashesを再帰的に適用します。stripslashes_deepはwp-includes/formatting.phpで定義されます。

<?php
function stripslashes_deep($value) {
        $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
        return $value;
}
?>

add_magic_quotesも再帰的にエスケープします。add_magic_quotesはwp-includes/functions.phpで定義されます。実装方法が微妙に違うのはご愛嬌ということでしょうかw

<?php
function add_magic_quotes( $array ) {
        global $wpdb;

        foreach ( (array) $array as $k => $v ) {
                if ( is_array( $v ) ) {
                        $array[$k] = add_magic_quotes( $v );
                } else {
                        $array[$k] = $wpdb->escape( $v );
                }
        }
        return $array;
}
?>

add_magic_quotes関数内でのエスケープ処理に使用される$wpdbオブジェクトはwpdbクラスのインスタンスです。wpdbクラスはwp-includes/wp-db.phpで定義されます。escapeメソッドはaddslashesを呼び出してエスケープしてるだけです。

<?php
        function escape($string) {
                return addslashes( $string );
                // Disable rest for now, causing problems
                /*
                if( !$this->dbh || version_compare( phpversion(), '4.3.0' ) == '-1' )
                        return mysql_escape_string( $string );
                else
                        return mysql_real_escape_string( $string, $this->dbh );
                */
        }
?>

このようなコードを入れておけば、php.iniの設定があーでこーでみたいなトラブルは、少なくともmagic_quotes_gpcに関しては発生しなくなります。

個人的には、普段はWordPressの逆の、常にmagic_quotes_gpcが無効であるようにするための前処理を実装していることが多いのです。いずれの方法にするかは設計判断としていただければ良いと思いますが、この辺はphp.iniで制御するよりもプログラムで制御しておく方が望ましいでしょう。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/xmalloc/20100214/1266149822
Connection: close