[PHP]サーバ設定でmagic_quotes_gpcがOnの時の対策

Read More

'エピソード' っていう文字列が 'エピソ\ード' ってなって表示されるんですけど…

テストをしていたデザイナのSさんがこんな報告を上げてきた。


スラッシュがつくの?なにその文字化け。



…そしてここから悪夢が始まった…




自分はここ最近システム開発としてモバイル版対応の為の作業に携わっていた。

これは具体的にどのような作業かというと、
既に稼働しているモバイル版のソースを利用して、新たなモバイル版のページを生成するという内容。

作成したものは社内の共通ローカル環境でテストを行い、一通りすんだら本番環境へ移す、というのが基本的な流れ。

ただ開発とは名ばかりで実際はコピーコピーの連続。
まあはっきり言って大した作業ではない。

このような作業のさなかでの冒頭の言葉だった。



これを聞いて最初は、
「文字化けかあ。何か変な処理でも走っているのかねー」
と思った。

そしてソースを追った。


しかし別段おかしな処理も見つからなかった。

途中でめんどくさくなってform要素から呼び出されたファイルの開始直後で出力した。
しかしそれでも文字化けしていた。

この結果だと途中の処理で文字化けしているわけではない。
うーん…?


次にphpinfo()で設定を確認してみた。



「あ…」
すごいイヤなもんが目に止まった。



magic_quotes_gpcの設定がOnになってる。




まあ今まで確認していなかった俺も悪いよ。
ああ悪い。

だけどmagic_quotes_gpcをOnにしたまま使う普通?


そういえばこのシステム、SQLのサニタイズ処理がなされていなかったことを今思い出した。
# システムとしてはとんでもなく致命的なこと


当時これに気がついた俺は、
「自分が組んだシステムじゃないしどうでもいいやー」
と思った。流した。


え?
流すなって?


ははは。
いや、そう思わないとやっていられなかった。腹が立って。

システムの作りはこれ以外にもあちこちひどかったのだ。

これを発見したころはもはや
ツッコんだら負け
くらいの境地だった。


だが今考えるとこの時点で俺は気が付くべきだった。
いや、せめて関連くらいは疑うべきだった。

SQLサニタイズをしていない=magic_quotes_gpcがOnになってるかも、ということに。
この点はちょっと自己嫌悪。

うんでもまあそれはSQLサニタイズをしない理由にはならないけどね。




さてここで今更ながらmagic_quotes_gpcについての仕様を確認してみようとおもふ。

以下はmagic_quotes_gpcディレクティブの機能的な説明。


magic_quotes_gpcとはphp.iniなどで設定できるディレクティブ設定の一つ。
GPC(Get/Post/Cookie) 処理に関する magic_quotes の設定を行います。
magic_quotes が on の場合、'(シングルクオート)、" (ダブルクオート)、\(バックスラッシュ) 、NULL には全て自動的に バックスラッシュでエスケープ処理が行われます。
magic_quotes_sybase も on の場合、シングルクオートは、バックスラッシュではなく シングルクオートでエスケープされます。
†PHPマニュアル ほぼ原文ママ
http://www.php.net/manual/ja/info.configuration.php#ini.magic-quotes-gpc


要はmagic_quotes_gpcとはSQLインジェクション対策として利用することを想定して作られたディレクティブ(だと思う)。
# ちなみにmagic_quotes_gpcはPHP 5.4.0で削除された


ただ、これだけではSQLインジェクション対策として十分ではなく、
結局のところSQL作成時には別途サニタイズ処理をやる必要がある。

なのでmagic_quotes_gpcをOnにして使っているヤツは(ほぼ)いない。
サニタイズ処理をやるのにこんなもの邪魔なだけだから。

むしろ画面出力時に弊害が出るのでOffにするのが一般的だ。


しかしまれにこれをOnのまま使ったりしてる人がいる。

理由はいわずもがな、magic_quotes_gpcのちゃんとした仕様や問題を「知らない」のだ。
Shift_JISを扱うまで問題も表面化しにくいしね。
↓この辺にわかりやすく書いてある
ホームページ作成の第一歩http://www.7key.jp/hp/php/memo1.html


と、まあ今回はその「まれ」にぶつかってしまったわけだ。
こんな設定、レアケースと思いたい。


さてmagic_quotes_gpcがOnになっていた場合、その対策には以下のようなものが思いつく。

対策1)
magic_quotes_gpcをOffに変更する。

対策2)
プログラムの入口で$_POST, $_GET, $_COOKIEにアンエスケープして入れ直す。

対策3)
モバイルの画面出力の時のみ利用する変数毎にアンエスケープ処理をかます。




さてまず対策1の
「magic_quotes_gpcをOffに変更する」。

これは超がつくほど当たり前の対応。
そして個人的にはこれ以上ないベストな対策だと思う。

しかし既に稼働しているシステムな以上、このディレクティブ設定を簡単にOffに変更することはできない。
もしmagic_quotes_gpcの設定を変更した場合、その設定効果はシステム全体に及ぶものになるからだ。

自分が組んできたものならいざしらず他の人が組んだもの。

どこにどのような影響が出るかなどわかるはずもない。
わかりたくもない。
というか提案すらする気にならない。しない。

ということで対策1は却下。


次は対策2の、
「プログラムの入口で$_POST, $_GET, $_COOKIEをアンエスケープして入れ直す」というもの。

世の中にはmagic_quotes_gpcの設定が変えれないサーバというものがたまにある。
.htaccessが使えないものやPHPのVerによる制限とかね。

このようなサーバに対して行う常套手段の一つなんだけど、今回はちょっと遠慮したい。

というのも、先ほど書いたように既にmagic_quotes_gpcがOnなのが前提として全てのSQLが組まれているからだ。

つまり対策2をやるとSQLサニタイジングを全SQLに対して入れる必要が出てくる。
いや、現在の状態でも必要なんだけど。

俺はSQLクエリの実行処理のすべてに関わりたくない。顔をつっこみたくない。
責任の一旦でも被るような作業はごめんこうむるってのが本音。

ということで対策2も却下。


次は対策3の、
「モバイルの画面出力の時のみ利用する変数毎にアンエスケープ処理をかます」。

これは全てのモバイルの画面出力が対象だから本気でやるとなったら修正箇所が多い。
修正内容としては、テンプレート側で変数として出力してる部分にstripslashes()をかませばいいだけ。

このシステムはSmartyを利用しているので、
Smarty修飾子としてssを定義し、{$var|ss}とかって感じにすれば一応対応できる。

しかしまだ問題がある。

このシステム、option要素やcheckbox, radioボタンなんかをテンプレート側のforeach()で回しているんじゃなくてSmartyのhtml_checkboxesとかhtml_optionsとかを使っている。

つまりプログラム側で部品から何からをひとまとめに作っているのだ。
これバラすのめんどくせえ。

selected属性の為の比較の時もいちいちstripslashes()をせんといけんのか。



まあ今回は自分がやったとこだけ対策3をやって済ませよう。
それでも修正範囲が多いな。



あー俺は諸事情から対策3を選んだけど、
このような問題にぶつかった人は迷わず対策1をとるように。

あとあと絶対にとんでもなく面倒なことになる。
俺はわかってる。だが断る。




…だから悪夢は終わらない…
そう問題が発覚するその日まで。
あ、問題が発覚する時はすごい致命的な時かも知れないけど。




と、ここまで徹底してほっとくのには理由がある。


世の中には痛い目をみないとわからない人種もいるのだ。

助言をしたところで、
「なぜそうしなければならないのか」というところまで考えようとしない。

だから運よく問題を回避できてもそれは一時的なものだ。
本人の根本が変わっていないので結局また似たような問題が発生する。

だから何も言わない。





ちなみにシステム組んだ人はMさんです。にっこり^^




Comments(1)

1  115ちゃん  2012/05/02 (水) 00:58 ID:XXXXXXXXX
恐ろしい。。。
私もはっきり言って分かっていないですが、トラウマがありますから。。。
恐ろしい。。。