XSS in Skype for iOS « Superevr
https://superevr.com/blog/2011/xss-in-skype-for-ios/
Skype XSS Explained « Superevr
https://superevr.com/blog/2011/skype-xss-explained/
Boxcarに学ぶプラットフォーム別セキュリティリスク - 金利0無利息キャッシング – キャッシングできます - subtech
http://subtech.g.hatena.ne.jp/mala/20110428/1304005287
これの話。
どういう実装をすると、このような現象が起きるのか。またどのような対策を施せば攻撃を防げるのか興味があったので自分がわかる範囲で調べた。
書こうと思ってからずいぶん時間がたってしまったし、全体的に知識不足・調査不足なのでツッコミ歓迎。
file://, about://(applewebdata://) などの特権的なURLリクエストでロードされたUIWebView からjavascriptを利用してデバイスのアドレス帳、着信履歴などのデータファイルにアクセスできる為、
開発者が意図しないスクリプトを第三者に実行され、アプリユーザーのデータを盗まれてしまう可能性がある
Phil Purviance の報告によると ローカルのURL file:// を明示しないとこれは起きないという風に読めるけど、
俺がmalaさんに聞きながら確認してたケースではURLを無指定な状態 about:// (applewebdata://) でも起きることが確認できた(サンプルコードをあげておいたのでやってみて)。
UIWebView 以外にも PhoneGAP で作ったアプリで外部データを動的に読み込んでいるもの(file:// になってる)訂正
BoxacarとかSkypeとかがたぶんあてはまる。あと他のiTunes App Storeで公開中のアプリにも該当しそうなものが結構ある。
UIWebViewDelegate で現在のURLを表示してみる
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"Request URL: %@", [webView.request URL]);
NSLog(@"DOM URL: %@", [webView stringByEvaluatingJavaScriptFromString:@"document.URL;"]);
}
アプリに含まれたHTMLファイルを読みこんでUIWebView に読み込ませるケースはこんなかんじ
NSURL* URL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"index.html"];
[_webView loadRequest:[NSURLRequest requestWithURL:URL]];
Request URL: file:///var/mobile/Applications/9CC77062-D748-4E16-92B4-7A043494D739/UIWebView+XSSSample.app/index.html
DOM URL: file:///var/mobile/Applications/9CC77062-D748-4E16-92B4-7A043494D739/UIWebView+XSSSample.app/index.html
あとabout://(applewebdata://) になる例というのは例えばよくある「HTML文字列をその場で整形してUIWebView に読み込ませる」というやり方で画面を実装していたとする
[_webView loadHTMLString:@"<h1>Hello World!</h1>" baseURL:nil];
こういうの。
その時の上記のログ表示はこうなる。
Request URL: about:blank
DOM URL: applewebdata://6A65BE08-DD5B-477B-9C78-888803146C52
これはローカルファイルへのリクエストのかわりに、ローカルファイルを文字列として読み込んでUIWebView に渡すことも同等になる。
NSString* src = [[[NSString alloc] initWithContentsOfURL:[[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"index.html"]
encoding:NSUTF8StringEncoding
error:nil] autorelease];
[_webView loadHTMLString:src baseURL:nil];
baseURL のパラメータをセットして file:// スキームへのアクセスを抑制できる。
[_webView loadHTMLString:src baseURL:[NSURL URLWithString:@"http://"]];
/**
* file://, applewebdata:// だと抑制できない。
* hoge:// とか適当なのスキームにするとWebView自体のロードエラーがでるはず。なので http://〜 がよさそう
*/
Request URL: http://
DOM URL: http://
ただこの場合HTMLの中で <img src="imapge.png"> のようなURLでバンドルリソースのルートを読み込むのを期待していても http://imapge.png というURLに解釈されしまうので動的にフルパスに置き換えないといけなくめんどうくさい。
あと、本来のアプリの実装でXMLHttpRequest を発行している場合リスエクトが失敗してしまう。その時はbaseURL を http://api.example.com まで指定すれば api.example.com にはアクセスできるようになる。
サンプルコードでたいていそうなので baseURL:nil になっているコードは結構ありそう、
loadHTMLString baseURL:nil lang:objectivec - Code Search
http://www.google.co.jp/codesearch#search/&q=loadHTMLString%20baseURL:nil%20lang:objectivec&type=cs
あとはGoogle Toolbox for Mac やらウェブにHTMLエスケープするスニペットやらがあるので入力を描写する際に逐一チェックするというウェブ開発と同じような作法が……
http://code.google.com/p/google-toolbox-for-mac/
https://github.com/laiso/iPhone-UIWebView-XSSSample
前提: 外部からの入力のあるアプリでは
カスタムリソースにはNSURLProtocolを使えば良いのじゃないか? — sklave
のNSURLProtocol でカスタムスキーマの挙動を定義する方法が理想っぽい。参考になる。
iOS5 SDK のリリース版に更新してみたけどかわらずなので、
Bug Reporting Best Practices - Apple Developer
http://developer.apple.com/jp/bugreporter/bugbestpractices.html
に送った
→ "Closed" で処理された。次のバージョンでは直ってるのかな。
PhoneGap について 1.1.0 のバージョンを再確認したところ、
file:// スキームで動作していたものの、リモートのJavascript ファイルを読み込ませる部分は動作しなかった。
どういう実装なのか確認しているけど、上記NSURLProtocol で中間処理をしている為っぽい。
https://github.com/phonegap/phonegap-iphone/blob/master/PhoneGapLib/Classes/PGURLProtocol.m
http://wiki.phonegap.com/w/page/43660891/Security
NSURLProtocol を定義してUIWebView で安全にローカルのリソースを読み込む - laiso - iPhoneアプリ開発グループ
多分OsfooraはTweet本文を一旦ファイルにHTMLファイルに書きだしておいてUIWebViewで表示する実装だと思います。
おそらく問題はloadRequestの実装だったために、任意のファイルが読み出し可能な状態だったのかなと想像してます。
脆弱性問題だけでもないのでUIWebViewを使う限りはGTMなどでHTMLエスケープが必須なような気がしてます。
まあ結局、有料アプリだったので自分購入して検証したわけではないし、既にアップデートされているようなので(XSSが修正されたのかどうかは未確認) わからないのですが……
参考情報ありがとうございました。
アプリに自動リンク処理が入っている為みたい
http://twitter.com/bulkneets/status/121298883602161664
http://twitter.com/bulkneets/status/121298473797681152