![]() ![]() ![]() ![]() |
![]() |
|
![]() |
||
![]() |
はてブやらmixiチェックやらgreeいいねやらfacebookのlikeやらのボタンを出力するコードがおかしなことになってる大手サイトが結構ある。
具体的には、こういったコードを使っているサイトが結構ある。
document.write('<a href="http://b.hatena.ne.jp/entry/' + document.URL + '" class="hatena-bookmark-button">はてなブックマーク</a>');
aタグだったりiframeだったり様々だが、共通しているのはdocument.URLやlocation.hrefを「そのまま」出力している点。何がマズイのかというと、document.URLやlocation.hrefにはURLの#以降の部分(location.hash)が含まれていて、URLにダブルクオート(")やシングルクオート(')を含ませることが可能だから(ブラウザによってはURLエンコードされて出来ない)
これによって、aタグやiframeタグを閉じて任意のタグを挿入するということが出来てしまう。この問題を把握したのは今年の2月のことで、悪意のある何者か(自分のことです)によって悪用事例が公開されるなどしているが、一向に修正される気配がないのでブログに書く次第です。
Google ChromeやOperaを使って本来のURLの末尾に
#"><xmp>'><xmp>
と加えてアクセスしてレンダリングがぶっ壊れないかどうかを調べる。
把握してる限りで大手ニュースサイト3件にこの問題があって、この記事を書いている段階で修正されていない。
リンクを開く前にURLを確認していれば怪しいと思われることもあるだろうけど、短縮URLだとどこに飛ぶのか分からない、さらに記事の内容を書き換えた上で history.replaceState を使って#以降のゴミを消すというscriptを仕込んでやれば、URLがおかしいという問題点には全く気付かれないだろう(URLにscriptが含まれていたことが分からなくなる)
こういったものを、そのままdocument.writeやinnerHTMLで出力してはいけない
document.URLやlocation.hrefを使わずに、記事がきちんと正規化されたURLを持つようにする
一般常識として出力時に適切にエスケープしてやれば、こういった問題は防げるんだけど、その一般常識もきちんとやろうとするとなかなか難しい(から色んなサイトで問題がある)
<a href="bookmark.example.com/?url={$article_url}">
こういった形式の場合は「URLエンコード」%xx%xx%xx 形式に変換するのが正しいだろう。encodeURIComponentで出来る。
例えばPATH_INFOで渡す場合
<a href="bookmark.example.com/entry/{$article_url}">
URLエンコードではなく生のままのURLを期待している、ことが多い。が、しかしhref属性値の中に入れるのでHTMLエスケープしてやらないとXSSが可能になるだろう。
現在見ているURLを単純に出力するようなケースだと
document.write("いま見てるURLは" + location.href + "だよ")
この場合はHTMLエスケープとかHTML Entitie encodeと言われるものが必要、JavaScriptにはデフォルトで無いのでreplaceとか使って適当に作れ。
http://news.example.com/artciles/"><script>...</script>.html
になることなんて通常はありえないよね。だから?以降(クエリストリング)や#以降の文字(location.hash)を含まない正規化されたURLを持っておくようにして、ユーザーからの入力で自由に書き換えられるlocation.hrefやdocument.URLを使うのを避ける、というのも手抜きではない立派な対策方法で、もし変なURLでアクセスされても、URLに対するブックマーク数やフィードバック数を表示するようなプラグインが正しく機能するようになるというメリットもある。
なので状況に応じた適切なエスケープやエンコードについて、きちんと理解してなかったりミスをする恐れがあるなら、記事の正式なURLをあらかじめ埋め込んでおく(link rel=canonicalに入れておけば他の用途にも使えるだろう)、というのが手っ取り早い修正方法だな、と考える。もちろん、URL以外にも、ユーザーが自由に入力することが可能なパラメータが沢山あってそれらを出力する場合は適切にエスケープしてやらないとダメだけど。
上記に書いた大手ニュースサイトというのは、この三つ。
中の人にフォローされてるので連絡しといた
gizmodo.jpの件は、Facebookの提供しているJavaScriptライブラリにそもそもバグがあった
たくさんありますね。
把握していて未修正のサイトはまだある。
どれぐらい使われているのか全く把握していないが、jQuery.socialbuttonというjQuery pluginに同様の問題があった。
古いバージョンを使っている場合、外すか、アップデートしないことには直らない。
この手の問題の厄介なのは
例 → 修正済み
http://phpspot.org/blog/archives/2010/11/twittermixiface.html#"</iframe><script>alert(document.domain)</script>
影響度は、そのドメイン上で任意のJavaScriptが実行できたらどうなるのか、によるので、例えば個人のブログとかだったら実際のところ大きな影響はないだろう。ニュースサイトだったら記事内容を改変されることが深刻な問題であると考えることも出来る(動作ブラウザが限定されるので、本気で嘘ニュースをばら撒く用途には使えないだろう)
そもそも他社ドメインから提供されているJavaScriptのソース(hatena, mixi, twitter, evernoteのサーバーに置いてあるjsのことね)を直接組み込む実装になっているので、本当に重要な個人情報を取り扱っているようなサービスにおいては元々使うべきではない(他社サービスがクラックされたり、ドメイン乗っ取られたり、通信経路で改ざんされていたりした場合に安全かどうかを保証できない)
ライブラリを作る側がバグがないように慎重に設計するのはもちろんだけど、使う側に関しても(特に個人情報を扱っているようなサイトを運営しているケースの場合)使っているライブラリが安全なのかどうか検証することをおすすめする。
Debrah2011/09/24 07:41Wow, that's a rlealy clever way of thinking about it!
jnjsks2011/09/24 23:27Fon4gH <a href="http://qurebbwalkwp.com/">qurebbwalkwp</a>
fuetkg2011/09/27 00:39FI3oyD , [url=http://litebxfxvauf.com/]litebxfxvauf[/url], [link=http://pijjfrvokdmc.com/]pijjfrvokdmc[/link], http://cbjfmeulvltw.com/
ikgofkxo2011/10/04 22:559rEISZ , [url=http://svnaoncqrugv.com/]svnaoncqrugv[/url], [link=http://lunieiavezpk.com/]lunieiavezpk[/link], http://ohnwfmywxzjj.com/
Master2012/08/26 11:22I could read a book about this wtiuhot finding such real-world approaches!
qkgybnlwnl2012/08/26 22:43WQS8RV <a href="http://rzpnxzvnatzw.com/">rzpnxzvnatzw</a>
amhofe2012/08/30 10:47iIW7U6 , [url=http://qwxazxvuxfey.com/]qwxazxvuxfey[/url], [link=http://nqcnswatnqqh.com/]nqcnswatnqqh[/link], http://vsmjfjkdowxe.com/