- ベストアンサー
PHPとMySQLで自作ブログを作ろうと試みている中でHTMLタグの取り扱いに困っています
- 記事投稿ページからMySQLに保存し、ブログ記事として表示するためにHTMLタグの取り扱い方法について教えてください。
- htmlspecialchars()でエスケープすることでXSSを防止できますが、出力時にhtml_entity_decode()を使用するとXSS対策が無効になります。
- 一般的なブログサービスでは、どのようにHTMLをデータベースに保存しているのか教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
様々な方法がありますが、PHPに限らず一般的には次のような手順を踏みます。 (1) まず、ユーザーにどのようなHTMLを使わせたいかを厳密に正確に決めます。たとえば、太字を使わせたいので<b>だけを許可するのであればそのように定義します。(逆に禁止タグを決める方法もありますが、相当のスキルが無いと危険なのでよした方がよいでしょう) (2) ユーザーの投稿テキストを受け取ったら、文字列のどこに(今の例だと)<b>と</b>があるのかを正確に把握します。そして「ここに"<b>"があるよ」とマーキングしておきます。他のタグは残すも良し、削除するも良しです。この処理はDBにテキストを格納する前でも、DBの内容を表示する直前でもいいです。 (3) 最終的に投稿を画面に表示する時、<b>と</b>の位置はマーキングで分かっていますから、それらはHTMLタグとして表示します。そしてそれ以外の部分は、(PHPの場合なら)htmlspecialchars()でエスケープして表示します。 このようにすれば、必要なタグだけをHTMLとして表示し、それ以外の部分は適切にXSSを防ぐことが出来るというわけです。ちょっと難しいかもしれませんがお分かりいただけるでしょうか? とはいえ、これを自分でキッチリ開発するのはかなり骨が折れます。特にいろんな種類のHTMLを書かせたい場合は挑戦してもセキュリティホールを作ってしまう可能性が高いでしょう。ライブラリを探した方が良いです。さて、実は私はもう長い間PHPを使っていないため、ここからはGoogle検索結果だけを頼りに書いてしまいますが、以下のライブラリは広く使われていて信頼できるようです。 HTML Purifier http://htmlpurifier.org/ http://phpspot.org/blog/archives/2007/03/htmlxssphphtml.html また、HTMLの代わりにHTMLに似た別の言語を使って対応するというのは、英語圏の掲示板/ブログソフトウェアではわりと一般的なようですね。これはPEARにもライブラリがあるようです。 BBCode http://pear.php.net/HTML_BBCodeParser http://ja.wikipedia.org/wiki/BB%E3%82%B3%E3%83%BC%E3%83%89
その他の回答 (2)
- mpx
- ベストアンサー率71% (149/209)
>> 一般のブログサービスでは、どうやってデータベースにHTMLを保存しているのでしょうか? >> 解決するいい方法があればどなたか教えてください。 既に求める回答は得られているようですが、いくつか紹介だけ。。 単にブログといっても、誰に書き込み権限を与えるかに依ります。 本文への書き込みを管理者にしか与えていないものでは、特にHTMLのサニタイジングを 施していない物も少なくありません。 不特定多数に書き込み権限がある場合や書き込み者が不明なコメント、トラックバックなどは当然 サニタイジングを施します。 不特定多数の人に書き込みを許可している物の代表として、掲示板などが有りますが いたずら防止も兼ねて、BBcode(Bulletin Board Code)を使う場合も有ります。 http://ja.wikipedia.org/wiki/BB%E3%82%B3%E3%83%BC%E3%83%89 htmlタグはすべてエスケープ処理してしまい、BBcodeのうち 許されたタグだけは表示時にhtmlタグに変換するという方法です。 オープンソースで開発されている掲示板などに多く使われています。
お礼
ご回答ありがとうございます。 BBcode、Wikipediaの説明をよく読んでみましたが、 大変勉強になりました。 確かに掲示板はブログよりもさらに危険そうですし、 「HTMLタグをまず全てエスケープ処理してしまい、 許可したタグだけをHTMLタグに再変換する」 というのは、非常に効率的な方法ですね。 ありがとうございました。
- public_sa
- ベストアンサー率52% (13/25)
問題箇所の切り分けが大切だと思います XSS対策が必要なのは表示の時でDB登録の時ではない ということ。 DB登録の時に必要なのはSQLインジェクションであってクロスサイトスクリプトじゃない って事。 簡単に言えばDB登録の時は SQLインジェクション対策を施した文字列を登録して 表示するときはXSS対策した HTMLを表示してあげれば良いと思いますが。 No1さんの言うとおりXSS対策すべき部分・XSS対策すべきタグの 選定・切分けもいりますし結構危険ですよ。
お礼
ご回答ありがとうございます! 確かに、XSS対策は、DBから表示するときでいいような気がします。 そう切り分けると、余計な処理が省けそうですね。 ご指摘ありがとうございます。 選定・切り分けは大変そうなので、 やはりライブラリに頼るのが一番安全で確実な気がしてきました。
お礼
ご回答ありがとうございます! なるほど、ホワイトリストのような物を作って、その中で決められたタグだけをマーキングして、その他をエスケープ処理するということですね。 確かにそれならXSSも防げる上に、使いたいHTMLタグも実行できますね! これは考えませんでした。目からウロコです(涙) ちなみにマーキングというと、例えば<b>を(b)などに変換しておけばいいのでしょうか? ご紹介いただいたライブラリはすごいですね! 無理に自作で作るよりも、こうした便利なライブラリを使いこなせるようになる方が 結局はいいかもしれませんね。試してみます!