電子書籍の厳選無料作品が豊富!

PHP+MySQLを使っています。
管理画面から入力した商品情報のデータをDBに保存し、DBから情報を取得してホームページに反映させたいと思っています。
その管理画面の入力フォームで、商品詳細を記述する入力ボックスをhtml編集できるようにする場合(タグをつけて記述できるようにする場合)、クロスサイトスクリプティングやSQLインジェクションなどの攻撃の対策としてどういった手法がありますか。
html編集できない入力ボックスを作るときは、私は、タグを取り除くなどの処理をしてDBに保存しています。タグをつけたままDBへ保存するというのはセキュリティとしてはよくないのではと思う部分があり、みなさんはどうされているのかと思い、質問させていただきました。
よろしくお願いいたします。

A 回答 (5件)

>クロスサイトスクリプティングの対策になっていないと思うのですが。

。。
本題をすっかり忘れてました、スミマセン。

http://jp2.php.net/strip_tags
とりあえず代表的な方法としては、上記関数を使う方法です。
<?php
$str = strip_tags($str, "<p><a>");
?>
第二引数のタグのみ許可されます。
後はシステムの要件次第ではあるんですが、上記URLの下部のユーザ投稿に様々なXSS対策用のサンプルコードもあります。
一度これらを見てみていただき、使えそうなコードを利用してみるのも良いと思います。

後は、XSSではないですが、「<span style="font-size:10000px">あああ</span>」とか、昔の掲示板荒らし、のような手法などに関しては、正規表現でstyleタグを除去するとか、別途対策が必要かもしれません。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
タグを許可する、という形でやられるのが一般的なのですね。
すごく勉強になりました。
また、何回も親切に対応していただけたのがうれしかったです。
本当にありがとうございました。

お礼日時:2009/09/15 10:30

http://php.benscom.com/manual/ja/info.configurat …
もしかするとコレが原因かもしれません。
PHPには、Get/Post/Cookieの値がそれぞれの変数に格納される前に、自動的にエスケープ処理を行う設定があります。
php.iniでその項目を無効にするか、PHPスクリプト上で、変数に格納された値一つ一つを、stripslashes関数でエスケープされた文字を解除する必要があります。

http://php.benscom.com/manual/ja/function.get-ma …
こちらのページのユーザ投稿の一番最初の「stripper」関数の投稿が参考になると思います。
流れは、もしget_magic_quotes_gpc関数にてGPCのエスケープを行う設定になっているのが確認されたら、stripslashes関数にて、エスケープを解除する
というプログラムです。

この回答への補足

回答ありがとうございます。
いろいろ調べていただきありがとうございます。

magic_quotes_gpcの設定をOFFにしたら上記の問題は解決できました。

しかし、入力ボックス上ではタグで囲まれた値が表示されていても、実際はそれをhtmlで表示する際に、エスケープされてないものを表示するということですよね?

例えば、<script>alert (○○);</script>というような文字が入力された場合は、実行されてしまうと思うのですが、その場合はエスケープすべきものをエスケープしてないということになるかと思います。

クロスサイトスクリプティングの対策になっていないと思うのですが。。。

私の解釈が間違っていたらごめんなさい。
よろしくお願いいたします。

補足日時:2009/09/14 10:50
    • good
    • 0

http://www.​○○○.jp/'​http://www.​○○○.jp/'
入力したタグの中に全角とか混ざってませんか?
自宅の環境で同様にやってみましたが特に問題なく表示されるようでした。

一度取得したHTMLをブラウザの「ソース表示」などで確認し、テキストエディタなど、HTMLの色分されたり、全半角のスペースなどが記号で表現されるようなもので見てみてはいかがでしょうか。

この回答への補足

回答ありがとうございます。
タグの中には全角は入っていません。
そちらではちゃんと表示されるのですね。

もう少し調べてみます。

補足日時:2009/09/13 00:17
    • good
    • 0

■XSS対策に関して


inputタグのvalue要素の囲い文字を「"(ダブルクオート)」としている場合には、
<input type="text" name="hoge" value="<?php echo htmlspecialchars($_POST['hoge'])?>" />
とすればOKです。(textareaでも同様)
実際に、<input type="text" name="hoge" value="&lt;font color='red'&gt;UNKO&lt;/font&gt;" />
とハードコーディングしてから、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/'
(○○○は実際のサイトの英数字を入れてあります)

基本的なタグは入れられるようにしたいのですが、どうすればよいかわかりましたら教えていただけますでしょうか。
また、何か私の捉え方が間違っているようでしたらご指摘ください。
よろしくお願いいたします。

補足日時:2009/09/04 13:35
    • good
    • 0

>タグをつけたままDBへ保存するというのはセキュリティとしてはよくないのではと思う



タグを付けたままDBへ保存するのが問題なのではなく、
タグとして認識される危険性をはらんだままデータを取り扱うことが問題なのです。
タグとして認識されることを避けるため、
通常「<」や「>」(あとエスケープの関係で「&」も)という文字は
エスケープを行いますが、このときエスケープをDB格納前に行うのか
あるいはデータの利用前に行うのかはどちらでも良いことです。

>SQLインジェクションなどの攻撃の対策

上記同様にデータのエスケープを行っても良いのですが
SQLインジェクションの対策にはプリペアードステートメントを利用することが一般的です。
具体的には下記サイト等を参考にしてください。

http://www.thinkit.co.jp/cert/books/2/3/1/3.htm

この回答への補足

回答ありがとうございます。
すみません、初歩的な質問かもしれませんが、
ひとつ教えていただけますか。

>タグとして認識されることを避けるため、通常「<」や「>」
>(あとエスケープの関係で「&」も)という文字はエスケープを
>行いますが、このときエスケープをDB格納前に行うのか
>あるいはデータの利用前に行うのかはどちらでも良いことです。

通常html編集できなくてもよい場合は、データにスクリプトが
埋め込まれていたとしても、エスケープ処理をしていれば、
ソース上では&のついた文字に変換されて出力されるために
スクリプトが実行されないと思うのですが、今回は通常のタグと
して使用する必要があるので、こういったエスケープ処理は
できないのではと思うのですが、それって間違いですか?

もしエスケープ処理をしたとしても、出力前にまたタグとして
認識させなければ、通常のテキストとして処理されてしまうの
ではないですか?

エスケープしないと、スクリプトが入っていたときに実行されて
しまうのではと思うのですが、考え方が間違っているのでしょうか。

プリペアードステートメントについては、少し調べてみます。
ありがとうございます。

よろしくお願いいたします。

補足日時:2009/09/03 02:24
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報