magic_quotes_gpc をエミュレートしたい
pho5.4以降で大きく変更された箇所の一つとしてマジッククォートの廃止があります。
magic_quotes_gpc = on
を前提に書いていたコードは軒並み変更する必要があります。
これを回避するために、magic_quotes_gpc 相当の機能をエミュレートできないか考えてみました。
注意: 検証は十分に行えていないので、参考程度にご覧ください
マジッククオートとは
オンの場合、全ての' (シングルクオート), " (ダブルクオート), \ (バックスラッシュ)およびNULL 文字がバックスラッシュで自動的にエスケープされます。 これは、addslashes() の機能と同じです。
https://www.php.net/manual/ja/security.magicquotes.what.php
magic_quotes_gpc とは
GPC(Get/Post/Cookie) 処理に関する magic_quotes の設定を行います。 magic_quotes が on の場合、'(シングルクオート)、" (ダブルクオート)、(バックスラッシュ) 、NULL には全て自動的に バックスラッシュでエスケープ処理が行われます。magic_quotes_sybase も on の場合、シングルクオートは、バックスラッシュではなく シングルクオートでエスケープされます。
https://www.php.net/manual/ja/info.configuration.php#ini.magic-quotes-gpc
試してみる
- index.php
<?php var_dump($_GET['hoge']); var_dump($_POST['huga']); var_dump($_COOKIE['piyo']); var_dump($_REQUEST);
リクエスト
curl 'http://localhost/?hoge=ho"ge' -X POST -d "huga=hu'ga" -b 'piyo=pi\yo'
レスポンス
magic_quotes_gpc = On
の場合
string(6) "ho\"ge" string(6) "hu\'ga" string(6) "pi\\yo" array(2) { ["hoge"]=> string(6) "ho\"ge" ["huga"]=> string(6) "hu\'ga" }
magic_quotes_gpc = Off
の場合
string(5) "ho"ge" string(5) "hu'ga" string(5) "pi\yo" array(2) { ["hoge"]=> string(5) "ho"ge" ["huga"]=> string(5) "hu'ga" }
これをエミュレートするにはどうすればよいか
やっていること
参考になりそうなコードやドキュメントを色々みていく
- php-magic-quotes-gpc
マジッククオートは内部で addslashes()
を使ってほしいのですが、mysql_real_escape_string()
を使っていたりと magic_quotes_gpc の実装とは乖離がありました。
https://github.com/yidas/php-magic-quotes-gpc
- merciful-polluter
今回の要件では magic_quotes_gpc
だけ、エミュレートして欲しいのですが、register_globals
のエミュレートまでされてしまいました。
https://github.com/gongo/merciful-polluter
($_REQUEST
の値がエスケープされていなかったのでこの箇所については修正が必要かもです。)
string(6) "ho\"ge" string(6) "hu\'ga" string(6) "pi\\yo" array(2) { ["hoge"]=> string(5) "ho"ge" ["huga"]=> string(5) "hu'ga" }
現在もどうかはわかりませんが、wordpressでは、magic_quotes_gpc
の設定に関わらず、magic_quotes_gpc
相当の処理が有効になっているとのことでした。
https://www.ilovex.co.jp/blog/system/php/wordpress%20php%20magicquotes.html
該当のコードを見てみると、$_SERVER
を加えてエスケープしているものの、magic_quotes 相当の処理をしています。
https://developer.wordpress.org/reference/functions/wp_magic_quotes/
https://developer.wordpress.org/reference/functions/add_magic_quotes/
- php.net
除去フィルタの項目に FILTER_SANITIZE_MAGIC_QUOTES
というのを発見。
https://php.net/manual/ja/filter.filters.sanitize.php
addslashes() を適用します。
ということでやりたいことも実現できている。
filter_var_array
にこの定数を指定してあげれば、よさそう。
https://www.php.net/manual/ja/function.filter-var-array.php
こんなイメージ
$_GET = filter_var_array($_GET, FILTER_SANITIZE_MAGIC_QUOTES); $_POST = filter_var_array($_POST, FILTER_SANITIZE_MAGIC_QUOTES); $_COOKIE = filter_var_array($_COOKIE, FILTER_SANITIZE_MAGIC_QUOTES); $_REQUEST = filter_var_array($_REQUEST, FILTER_SANITIZE_MAGIC_QUOTES);
phpの実行前に読み込ませるようにする
上記で、magic_quotes_gpc 処理自体はできましたが、どこで読み込ませるかが課題になってきます。 できれば、phpのメイン処理が実行する前に読み込んでおきたいです。
実は、php.ini
に auto_prepend_file
というディレクティブがあり、ここにphpのメイン処理の実行前に実行したいphpファイルを指定することができます。
ここに、上記で作成した処理を実行させるようにします。
例:
auto_prepend_file = /var/www/app/init.php
最後に
これで magic_quotes_gpc 相当の処理をエミュレートすることができました。
ここに、今回実装したサンプルを置いておきます。
余談ですが、もし、SQLインジェクション対策として、magic_quotes_gpc や addslashes() を使っている場合は、Shift_JISを使っているケースなどで、十分に対策されないことがあるので注意が必要です。
(そうでなくても、SQLインジェクション対策は、Prepared Statement
を使うのが望ましいです。)
https://t-komura.hatenadiary.org/entry/20060122/1137944280
https://codeday.me/jp/qa/20181226/77247.html