- ベストアンサー
管理画面の入力フォームをHTML編集可能にする場合の攻撃対策
- 管理画面の入力フォームをHTML編集可能にする際の攻撃対策について考えましょう。クロスサイトスクリプティング(XSS)やSQLインジェクションなどの攻撃を防ぐためには、以下の手法があります。
- まず、データの入力時に入力値のバリデーションを行うことが重要です。タグや特殊文字などの不正な入力をチェックし、適切な処理を行うことで攻撃を防ぐことができます。
- さらに、データの表示時にも適切なエスケープ処理を行う必要があります。HTMLエスケープやSQLプレースホルダを使用することで、入力データに含まれる悪意のあるコードを無効化することができます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>クロスサイトスクリプティングの対策になっていないと思うのですが。。。 本題をすっかり忘れてました、スミマセン。 http://jp2.php.net/strip_tags とりあえず代表的な方法としては、上記関数を使う方法です。 <?php $str = strip_tags($str, "<p><a>"); ?> 第二引数のタグのみ許可されます。 後はシステムの要件次第ではあるんですが、上記URLの下部のユーザ投稿に様々なXSS対策用のサンプルコードもあります。 一度これらを見てみていただき、使えそうなコードを利用してみるのも良いと思います。 後は、XSSではないですが、「<span style="font-size:10000px">あああ</span>」とか、昔の掲示板荒らし、のような手法などに関しては、正規表現でstyleタグを除去するとか、別途対策が必要かもしれません。
その他の回答 (4)
- hogehoge78
- ベストアンサー率80% (433/539)
http://php.benscom.com/manual/ja/info.configuration.php#ini.magic-quotes-gpc もしかするとコレが原因かもしれません。 PHPには、Get/Post/Cookieの値がそれぞれの変数に格納される前に、自動的にエスケープ処理を行う設定があります。 php.iniでその項目を無効にするか、PHPスクリプト上で、変数に格納された値一つ一つを、stripslashes関数でエスケープされた文字を解除する必要があります。 http://php.benscom.com/manual/ja/function.get-magic-quotes-gpc.php こちらのページのユーザ投稿の一番最初の「stripper」関数の投稿が参考になると思います。 流れは、もしget_magic_quotes_gpc関数にてGPCのエスケープを行う設定になっているのが確認されたら、stripslashes関数にて、エスケープを解除する というプログラムです。
補足
回答ありがとうございます。 いろいろ調べていただきありがとうございます。 magic_quotes_gpcの設定をOFFにしたら上記の問題は解決できました。 しかし、入力ボックス上ではタグで囲まれた値が表示されていても、実際はそれをhtmlで表示する際に、エスケープされてないものを表示するということですよね? 例えば、<script>alert (○○);</script>というような文字が入力された場合は、実行されてしまうと思うのですが、その場合はエスケープすべきものをエスケープしてないということになるかと思います。 クロスサイトスクリプティングの対策になっていないと思うのですが。。。 私の解釈が間違っていたらごめんなさい。 よろしくお願いいたします。
- hogehoge78
- ベストアンサー率80% (433/539)
>http://www.○○○.jp/'http://www.○○○.jp/' 入力したタグの中に全角とか混ざってませんか? 自宅の環境で同様にやってみましたが特に問題なく表示されるようでした。 一度取得したHTMLをブラウザの「ソース表示」などで確認し、テキストエディタなど、HTMLの色分されたり、全半角のスペースなどが記号で表現されるようなもので見てみてはいかがでしょうか。
補足
回答ありがとうございます。 タグの中には全角は入っていません。 そちらではちゃんと表示されるのですね。 もう少し調べてみます。
- hogehoge78
- ベストアンサー率80% (433/539)
■XSS対策に関して inputタグのvalue要素の囲い文字を「"(ダブルクオート)」としている場合には、 <input type="text" name="hoge" value="<?php echo htmlspecialchars($_POST['hoge'])?>" /> とすればOKです。(textareaでも同様) 実際に、<input type="text" name="hoge" value="<font color='red'>UNKO</font>" /> とハードコーディングしてから、POST値をそのままechoなどで出力してみてください。エンコードした文字が戻ってタグとして認識されているのが分かると思います。 ■SQLインジェクション対策にかんして OKbokuzyoさんの仰るとおり、プリペアドステートメントを利用するのが良いと思います。 ただ、提示されたURLのようにSQL文として記述するよりは、PDOクラスなどで実装されているprepareメソッドなどを活用されたほうが、今後MySQLをPostgreSQLに変更する際などに以降しやすいと思いますので、PDOクラスの使い方を調べたほうがよさそうです。 尚、標準のmysql関数でエスケープする方法は、下記 <?php $escape_str = mysql_real_escape_string($_POST['hoge']); ?> 尚、POSTされた値とDBの文字エンコードが違う場合には、関数に流し込む前に文字コードを変換しておく必要があります。(これはPDOのPrepareなどでも同様)
補足
回答ありがとうございます。 何回もごめんなさい、もう少しだけ教えてもらってもいいですか? ■XSS対策について <input type="text" name="hoge" value="<?php echo htmlspecialchars($_POST['hoge'])?>" />とコーディングし、 実際に表示された入力のボックスに例えば「<b>aaa</b>」と入力したときは、確かにタグを認識して太字になっていましたが、 例えば「<a href='http://www.○○○.jp'>サイトはこちら</a>」などを入力したときは、飛び先が以下のようになっていました。 http://www.○○○.jp/'http://www.○○○.jp/' (○○○は実際のサイトの英数字を入れてあります) 基本的なタグは入れられるようにしたいのですが、どうすればよいかわかりましたら教えていただけますでしょうか。 また、何か私の捉え方が間違っているようでしたらご指摘ください。 よろしくお願いいたします。
- OKbokuzyo
- ベストアンサー率43% (130/296)
>タグをつけたままDBへ保存するというのはセキュリティとしてはよくないのではと思う タグを付けたままDBへ保存するのが問題なのではなく、 タグとして認識される危険性をはらんだままデータを取り扱うことが問題なのです。 タグとして認識されることを避けるため、 通常「<」や「>」(あとエスケープの関係で「&」も)という文字は エスケープを行いますが、このときエスケープをDB格納前に行うのか あるいはデータの利用前に行うのかはどちらでも良いことです。 >SQLインジェクションなどの攻撃の対策 上記同様にデータのエスケープを行っても良いのですが SQLインジェクションの対策にはプリペアードステートメントを利用することが一般的です。 具体的には下記サイト等を参考にしてください。 http://www.thinkit.co.jp/cert/books/2/3/1/3.htm
補足
回答ありがとうございます。 すみません、初歩的な質問かもしれませんが、 ひとつ教えていただけますか。 >タグとして認識されることを避けるため、通常「<」や「>」 >(あとエスケープの関係で「&」も)という文字はエスケープを >行いますが、このときエスケープをDB格納前に行うのか >あるいはデータの利用前に行うのかはどちらでも良いことです。 通常html編集できなくてもよい場合は、データにスクリプトが 埋め込まれていたとしても、エスケープ処理をしていれば、 ソース上では&のついた文字に変換されて出力されるために スクリプトが実行されないと思うのですが、今回は通常のタグと して使用する必要があるので、こういったエスケープ処理は できないのではと思うのですが、それって間違いですか? もしエスケープ処理をしたとしても、出力前にまたタグとして 認識させなければ、通常のテキストとして処理されてしまうの ではないですか? エスケープしないと、スクリプトが入っていたときに実行されて しまうのではと思うのですが、考え方が間違っているのでしょうか。 プリペアードステートメントについては、少し調べてみます。 ありがとうございます。 よろしくお願いいたします。
お礼
回答ありがとうございます。 タグを許可する、という形でやられるのが一般的なのですね。 すごく勉強になりました。 また、何回も親切に対応していただけたのがうれしかったです。 本当にありがとうございました。