ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

ネットワーク&セキュリティコミュのはてなでやってるXSS対策と同様のXSS対策をしたい

  • mixiチェック
  • このエントリーをはてなブックマークに追加
こんにちは。

VPSのレンタルサーバで、RHEL、PHP5、Apache2でサイトをこれからつくる予定です。

まずはセキュリティ的な部分を、片付けようと思い、

そこで、まずは、XSS対策をしようと思いました。

で、PHP と Web アプリケーションのセキュリティについてのメモ
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html

を見まして<ユーザが HTML タグやスタイルシートを記述できるようにしたい場合のクロスサイトスクリプティング対策としては、「はてなダイアリーXSS対策が」参考になります>
とあったので、

「はてなダイアリーXSS対策」
http://hatenadiary.g.hatena.ne.jp/keyword/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AA%E3%83%BCXSS%E5%AF%BE%E7%AD%96

を見たのですが、部分的に分からないところがあります。

(前述の、PHP と Web アプリケーションのセキュリティについてのメモ
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html
からたどったサイトでもわかりませんでした。ぐぐっても該当するような記述が見あたらず・・・。



下記のとおりで、長文となりますが、お分かりの方いらっしゃいましたら、お教えいただければ幸いです。

よろしくお願いします。

//-----------------------------------------------------------
<?php
function echo_html( $str )
{
echo htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' );
}
?>

なる関数まずをつくっておいて、以下これを使い回す。

<a href="<?php echo_html( $url ) ?>"><?php echo_html( $title ) ?></a>


<各項目の1行目が上記」はてなでの記述>

以(下は<1>以外は、時系列でやればOKでしょうか?)

<1>ヘッダ、フッタ、日記本文の表示時にHTMLを解析し、はてなダイアリー利用可能タグに定めるタグおよび属性のみを出力します。
⇒これは概要ですよね?で、HTMLを出力するときに行う、ということであってますか?

<2>(1)利用可能タグに設定されていない属性は削除し、(2)利用可能タグに設定されていないタグの場合には<script>といった文字列に変換します。

  ⇒「利用可能タグに設定されていない属性は削除」の意味が分かりません。
 「利属可能<属性>に設定されていない属性は削除」
 の書き間違いかと思えるのですが・・・。「いや、これであってる」という場合、具体的なソースをHTML示していただけないでしょうか?

また上記<1>、<2>それぞれの場合で、正規表現がわかりません。
/*
<2>(2)で、<font>が利用不可能タグと仮定した場合、
< color="#FF6600" font >hogehoge</font>
みたいのにも対応できる正規表現がわからいもので。。。
**/


<3>href,src,cite,background,action 属性で外部 URL が参照される場合、URL が適切な文字で構成されているかチェックを行ないます。
 ⇒なぜ、「href,src,cite,background,action」属性だけなのでしょうか?
  (他にもあるような気がして。。。)

<4>
タグ内の属性値は、「<」を「<」に、といった変換を行ないます。

<4>と<2>の違いがわかりません。(<2>(1)が不明なせいもありますが)

<5>
# スタイルシート内の「\69\6D\70\6F\72\74」といった文字参照を、EUC文字列に置換します。
例 UTF-8なら、$str = mb_convert_encoding($str, 'UTF-8', 'HTML-ENTITIES');であってます?

<6>スタイルシート内の 不適切な制御コード(0x00など) を削除します。
「0x00【など】」とありますが、他の不適切な制御コードが分かりません。

<7>は推奨しないということで、何もしません。

<8>
スタイルシート内の「\」文字で、その後に続く文字が「'」「"」「{」「}」「;」「:」「(」「)」「#」「A」「*」でないものを削除します。

これ、理屈というか目的が分かりません。
なので、「A」と書いてますが、B〜Zやa〜zが含まれていないのかふしぎです。

<9>
スタイルシートを解析し、「javascript」「vbscript」「@import」「cookie」「eval」「expression」「behavior」「behaviour」「binding」「include-source」「@i」の文字列をその文字列が無くなるまで削除します

「無くなるまで削除します」という日本語が変な気きがしますが、ようは、これらは全部削除してしまえばOKということでしょうか?


<10>
スタイルシートを解析し、url(...)で指定された URL が適切な文字で構成されているかチェックを行ないます。

これはわかります。
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html
にURI のチェック用関数の例がありましたので。

<11>スタイルシート内の「<」「>」を「<」「>」に変換します。
これはそのまま。

<12>スタイルシート内の「*/」を「*/ 」(コメントを閉じた後に空白二個)に変換します。

???です。
(コメントを閉じた後に空白二個)・・ってなぜでしょうか?
=====
以上です、

コメント(9)

セキュリティの前に、まずは動くものを作ってからのほうが良いと思いますよ。
タグの入力はすべてエスケープする方向に転べば難しい事考えなくても安全になりますし。
それにしてもmixiのエスケープが変なせいで一部意味不明になってるな(ーー;)
えーと、、、

危ないデータは、サーバーに置かない。

それが一番の対策だと思います。

ちまたの間違いは、およそ、公開されたサーバーに見られちゃまずいデータを置いているから起こるわけですが、本当にそのデータを、サーバーに置く必要があるのか? それを吟味するところから、初めては如何でしょうか。

いくら対策しても、いくらでも抜かれますから。。。^_^;


ついでに老婆心、
はてなでも何でも、誰でも書き込めるような所の情報を鵜呑みにしたら、それこそ、はじめからセキュリティホールを、いいように作り「こまされる」リスクすら、あると思いますよ。

せめて、名のある出版社系サイトとか、悪いことされたら名指しで告訴できそうな素性の割れる(名乗っている)サイトの情報で仕事した方が。。。
以下のサイトが参考になると思います。この分野の第一人者であるネットエージェントのはせがわようすけ氏の解説です。質問された内容に関係する項目もあります。

http://www.atmarkit.co.jp/fcoding/articles/webapp/03/webapp03a.html

はてなダイアリーの対策方法が公開されていること自体はとても素晴らしいことで、そのような情報は他ではあまり見ることはできません。しかしながら、その方法が非常に優れているかどうかは話は別で、脆弱性指摘があるたびに継ぎ足しで対策を増やしていったようで、非常に複雑な方法になってしまっています。また、公開されている内容で全てというわけでもないようです。そのあたりのことも、はせがわ氏から次のような言葉で指摘されています。

『スタイルシート内から「expression」をはじめ、危険性にありそうな文字列を削除するという方法になっていますが、そもそもこの対策方法は、前述のさまざまな「expression」の表記方法の模索とともに、破られては改修するという流れを何度も繰り返してできたものです。また、はてなダイアリー自身にXSSが見つかり対策した場合でも、この対策方法の内容が改定されていないこともありました。そのため、この対策方法だけをうのみにスタイルシートの検査を実装することは、正直お勧めできません。』

このような理由から、まずは許容するHTMLタグとCSSの項目を定義し、その定義にあてはまっているもののみを許容するような「ホワイトリスト型」の実装をお勧めします。それが自力でできないということであれば、そのようなライブラリの実装がいくつか公開されているようですので、それらを評価して使用するという方法もあります。私自身はそのようなライブラリを評価したことはありませんが、http://d.hatena.ne.jp/teracc/20070105#1168070785 などが参考になると思います。このブログは信頼のおける方が書いておられますが、なにぶん古い内容なので、今でもそのまま当てはまるかどうかは分かりません。

☆悩める子羊☆さんの質問内容は、まだ世間でもこれという定まった方法がないものですので、自分でがんばって原理から理解するか、既にあるライブラリを使用するか、お金を払ってコンサルタントをやとうかくらいしか選択肢はないと思います。

以上、直接の回答にはなっていませんが、ご参考になれば幸いです。
お返事が遅くなり失礼しました。

>J.P.tomoさん
>タグの入力はすべてエスケープする方向に転べば難しい事考えなくても安全になりますし。
そうですね。。。どうも、トップダウン?的に考えてしまうくせがあり。。。

>それにしてもmixiのエスケープが変なせいで一部意味不明になってるな(ーー;)
すみません、投稿時、確認画面をよくみてなかったです(m_m

===

>杏@政権交代派!さん
>サーバーに置く必要があるのか? それを吟味するところから、初めては如何でしょうか。
そうですね。そういたします。

>いくら対策しても、いくらでも抜かれますから。。。^_^;
そうですね・・・。そういえば、大昔php3のころは、
 <input type=”text” name=”foo” value="ほげほげ" />でフォームをsubmit
されると、$fooで変数取得できたのも今考えると恐ろしい。。。

>はてなでも何でも、誰でも書き込めるような所の情報を鵜呑みにしたら、それこそ、はじめからセキュリティホールを、
>いいように作り「こまされる」リスクすら、あると思いますよ。

そですね。「PHP セキュリティ」でぐぐると、いつもこのページが出てくるので、ここばっかり(だけではないですが)見てましたが

今見つけた、、グーグルで3位の、
http://note.openvista.jp/2008/php-security-memo/
すごくウェブユーザビリティ的に見やすいです。。。はてなブックマークしてる人も800人超えてますね。。。
(詳細はまだ見てませんが)

===

>ockeghemさん

詳細に、ありがとうございます。
<「ホワイトリスト型」の実装>と見て、「あ、そういえばそうだ・・・」と思いました。

どうも自分、ウェブサイトの間違いやバグのたぐいを見つけるのが得意(?)みたいで、
たぶんほとんどの人がしってるECサイト数カ所の致命的なバグや、システム会社のURIのサブドメインのところを
削ったら、なんだかすごいデータベースを発見したりと、思考がブラックリスト的になってしまいました。

>、自分でがんばって原理から理解するか、既にあるライブラリを使用するか、
>お金を払ってコンサルタントをやとうかくらいしか選択肢はないと思います。
お金はないので、ライブラリを使用しつつ原理から理解してみようと思います。

===

ありがとうございました。

再びすみません。
サニタイジングをわすれないように、
スクリプトの最初に以下のように、自己流サニタイジング(?)して、
必要なときに、それをもどすようにすれば、
目立つので、忘れることも少なくなって、ヒューマンエラーがへるかな・・・と、ちょっと前に思ってました。
//====================================================================================
function change_char2tmp( $arr ){
for ($i=1; $i<=count($arr); $i++)
$arr[$i] = str_replace( "\0", _____"NULL_____", $arr[$i] );
$arr[$i] = str_replace( ">", "_____DAINARIL_____", $arr[$i] );
$arr[$i] = str_replace( "<", "_____SYOUNARI_____, $arr[$i] );
$arr[$i] = str_replace( "'", "_____QUOTE_____", $arr[$i] );
$arr[$i] = str_replace( '"', "_____DOUBLEQUOTE_____", $arr[$i] );
$arr[$i] = str_replace( '.', "_____PIRIODO_____", $arr[$i] );
$arr[$i] = str_replace( '/', "_____SLASH______", $arr[$i] );


$arr[$i] = str_replace( "\n\r", "_____KAIGYOU______", $arr[$i] );
$arr[$i] = str_replace( "\n", "_____KAIGYOU______", $arr[$i] );
$arr[$i] = str_replace( "\r", "_____KAIGYOU______", $arr[$i] );

}

return $arr;
}

$_GET = change_char2tmp( $_GET );
$_POST = change_char2tmp( $_POST );
$_COOKIE = change_char2tmp( $_COOKIE );
//====================================================================================
ヌル文字対処とかはしてませんが、これ自体には問題はない・・・ですよね?


ockeghemさんにお教えいただいた、ライブラリ
http://d.hatena.ne.jp/teracc/20070105#1168070785
も、(まだためしてませんが)概要を見ると、一部似てるかなーともおもいまして。
もちろん実際には、
_____"NULL_____ とか_____KAIGYOU______でなく
_____HARUHI______ とか _____MIKURU______ とか、工夫しますがw
> $arr[$i] = str_replace( ">", "_____DAINARIL_____", $arr[$i] );

decodeした結果がencodeする前と同一であることが保障できないdecodeは
使わない方が良いでしょう。
> サニタイジングをわすれないように、

信用できない外部から任意のデータが流れてきて
それを適切に取り扱うべきプログラムではサニタイジングをしてはいけない。
> スクリプトの最初に以下のように

web用のプログラムにアクセスしてくるクライアントの要求に含まれる任意文字列について、
その文字列に含まれる一部の文字が何らかの処理でメタ文字として認識されるために
その処理に渡すまでのどこかで適切にエンコードしなければならない場合、
どの文字がメタ文字として扱われどの文字が一般文字として扱われるのかは
目的としている処理毎に仕様が異なるのだから、
処理の直前で常に規定のエンコードを行うのが適切。
クライアントからのデータがどこでどのように使用されるかを決め付けて
プログラムの最初で固定のエンコードを施すのは間違い。

ハイビスカスハイビスカスハイビスカス眠い?

ハイビスカスハイビスカスハイビスカス素敵な人生を送ろう。suthttp://m.mixi.jp/view_community.pl?id=4606321&

よろしく〜\(^o^)/

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

ネットワーク&セキュリティ 更新情報

ネットワーク&セキュリティのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング