Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WebViewを守るSafeBrowsingのコントロール / Control result ...
Search
Aki
February 08, 2019
Technology
1
760
WebViewを守るSafeBrowsingのコントロール / Control result of SafeBrowsing in WebView
DroidKaigi2019 Day2での発表スライドです。
Aki
February 08, 2019
Tweet
Share
More Decks by Aki
See All by Aki
厳しくなったSafetyNet Attestationによる端末チェック
akihiroshiota
2
2.1k
Other Decks in Technology
See All in Technology
Incident Response Practices: Waroom's Features and Future Challenges
rrreeeyyy
0
160
TypeScript、上達の瞬間
sadnessojisan
46
13k
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
2
3.2k
100 名超が参加した日経グループ横断の競技型 AWS 学習イベント「Nikkei Group AWS GameDay」の紹介/mediajaws202411
nikkei_engineer_recruiting
1
170
エンジニア人生の拡張性を高める 「探索型キャリア設計」の提案
tenshoku_draft
1
120
Lexical Analysis
shigashiyama
1
150
【Pycon mini 東海 2024】Google Colaboratoryで試すVLM
kazuhitotakahashi
2
500
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
フルカイテン株式会社 採用資料
fullkaiten
0
40k
オープンソースAIとは何か? --「オープンソースAIの定義 v1.0」詳細解説
shujisado
7
820
これまでの計測・開発・デプロイ方法全部見せます! / Findy ISUCON 2024-11-14
tohutohu
3
370
rootlessコンテナのすゝめ - 研究室サーバーでもできる安全なコンテナ管理
kitsuya0828
3
380
Featured
See All Featured
A Philosophy of Restraint
colly
203
16k
How GitHub (no longer) Works
holman
310
140k
Documentation Writing (for coders)
carmenintech
65
4.4k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Unsuck your backbone
ammeep
668
57k
The Cost Of JavaScript in 2023
addyosmani
45
6.7k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Being A Developer After 40
akosma
86
590k
Faster Mobile Websites
deanohume
305
30k
Transcript
WebViewを守る SafeBrowsingのコントロール DroidKaigi 2019 2019/2/8 17:40 Room4 Akihiro Shiota
自己紹介 ◼塩田 明弘(シオタ アキヒロ) ◼Twitter:@aki_sh_7 ◼セキュリティ系のお仕事をしてます
注意事項 ◼本セッションの内容は2019年1月25日時点の 内容を基にしています。将来のAndroidOS、 JetPack、GMS、chrome、webviewのバージョン によっては動作しない、または異なる動作を する可能性があります。
目次 1. WebViewでのSafeBrowsing 2. SafeBrowsingのコントロール 3. Safetynet SafeBrowsingとの関係 4. まとめ
WebViewでの SafeBrowsing
WebViewの脆弱性 ⚫Fileスキーマでのファイルアクセス ⚫キャッシュの平文での保存 ⚫addJavascriptInterfaceによるメソッド呼び出し ⚫onReceivedSslError ハンドラの安全でない実装 ⚫etc…
コンテンツに対する判断 ◼コンテンツ自体の危険性も判断が必要 (特にアクセス先を限定できないアプリ) ◼PCブラウザ等でも利用されていた、 SafeBrowsing機能がAndroidでも使える
SafeBrowsingとは ◼「安全ではないウェブサイト」へ のアクセス時に警告を出すサービス。 ◼収集したデータベースと合致する サイトを検出。
安全ではないウェブサイト ◼不正なソフトウェアサイト マルウェア 望ましくないソフトウェア ◼フィッシングサイト
WebViewでのSafeBrowsing ◼WebViewでの利用開始(2017)。 サポート対象はAndroid5.0以上 ◼バージョン66以上でデフォルト有効 ◼SafeBrowsingの動作を前提にアプリを開発するなら、 minSDKVersionは21以上に。
SafeBrowsingの使い方 使うだけならマニフェストに以下の記述をすればOK この設定をしておくことで、バージョン66未満の WebViewでも有効になる <manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value=“true" />
... </application> </manifest>
WebViewでのSafeBrowsing
WebViewでのSafeBrowsing シンプルすぎ?
SafeBrowsingの表示条件 ◼この表示はWebViewのViewのサイズが原因。 以下の条件の時だけ、Chromeと同じ表示になる。 ➢RootViewとWidthが同じ ➢HeightがRootViewの7割以上 ◼どちらかでも当てはまらなければ簡易表示になる (Widthがオーバーしていると説明も表示されない)
chrome://interstitials ◼SafeBrowsingの警告ページは、 chrome://interstitialsで確認可能。
SafeBrowsingの コントロール
SafeBrowsingのコントロール APIレベル26・27で挙動をコントロールするAPIが追加 ➢SafeBrowsingの初期化機能 ➢SafeBrowsingで検出された時の挙動にかかわる機能 ➢WebViewインスタンス単位での有効化API ➢SafeBrowsingのホワイトリストによる検査除外 実装時には、JetPackを使うことをお勧めする。 (単純なバージョン分岐でなく、APIレベル26・27未満でも上 記機能が使えるようになる。4.4以下では使えません。) implementation
'androidx.webkit:webkit:1.0.0'
WebViewCompat# startSafeBrowsing SafeBrowsingの初期化を行う WebViewCompatはWebViewの拡張クラスでないので注意 if(WebViewFeature.isFeatureSupported(START_SAFE_BROWSING)) { if(WebSettingsCompat.getSafeBrowsingEnabled(webView.settings)) WebViewCompat.startSafeBrowsing(this) { success
-> mSafeBrowsingIsInitialized = true if (!success) { Log.w("WebView SafeBrowsing", "Unable to initialize Safe Browsing!") } else { Log.i("SafeBrowsing", "SafeBrowsing initialization success!") webView.loadUrl("http://testsafebrowsing.appspot.com/") } }else { Log.w("SafeBrowsing", "SafeBrowsing is disabled") } }else{ Log.w("SafeBrowsing", "SafeBrowsing initialization is not supported...") } 処理開始前に有効化されているか確認。 実行はできる為、リソースが準備されてしまう
WebViewFeature# isFeatureSupported 機能の確認をしてから呼び出す この後出てくる各機能を呼ぶ前にもそれぞれ確認する if(WebViewFeature.isFeatureSupported(START_SAFE_BROWSING)) { if(WebSettingsCompat.getSafeBrowsingEnabled(webView.settings)) WebViewCompat.startSafeBrowsing(this) { success
-> mSafeBrowsingIsInitialized = true if (!success) { Log.w("WebView SafeBrowsing", "Unable to initialize Safe Browsing!") } else { Log.i("SafeBrowsing", "SafeBrowsing initialization success!") webView.loadUrl("http://testsafebrowsing.appspot.com/") } }else { Log.w("SafeBrowsing", "SafeBrowsing is disabled") } }else{ Log.w("SafeBrowsing", "SafeBrowsing initialization is not supported...") }
WebViewClientCompat# onSafeBrowsingHit 安全でないウェブページと判断されると呼ばれる。 override fun onSafeBrowsingHit(view: WebView, request: WebResourceRequest, threatType:
Int, callback: SafeBrowsingResponseCompat){ val dlg = AlertDialog.Builder(view.context) dlg.setTitle("Warning") dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください") dlg.setPositiveButton("詳細確認") { _, _ -> callback.showInterstitial(false) } dlg.setNegativeButton("元のページへ戻る") { _, _ -> callback.backToSafety(true) } dlg.setNeutralButton("ホームへ戻る") { _, _ -> view.loadUrl("https://www.google.co.jp")} dlg.show() }
SafeBrowsingResponseCompat SafeBrowsingResponseCompatは3つのアクションが可能 ⚫showInterstitial:遷移やレポート送付を選択可能なページを表示。 1章でも説明した画面が表示。デフォルトではこれ。 ⚫backToSafety:「セキュリティで保護されたページに戻る」と同じ ⚫Proceed:「安全でないサイトにアクセスする」と同じ
WebViewClientCompat# onSafeBrosingHit その他の引数でリクエスト情報と脅威のタイプを取得可能 override fun onSafeBrowsingHit(view: WebView, request: WebResourceRequest, threatType:
Int, callback: SafeBrowsingResponseCompat){ val dlg = AlertDialog.Builder(view.context) dlg.setTitle("Warning") dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください") dlg.setPositiveButton("詳細確認") { _, _ -> callback.showInterstitial(false) } dlg.setNegativeButton("元のページへ戻る") { _, _ -> callback.backToSafety(true) } dlg.setNeutralButton("ホームへ戻る") { _, _ -> view.loadUrl("https://www.google.co.jp")} dlg.show() }
WebViewClientCompat# onSafeBrosingHit 第二引数:requestからリクエストの情報を取得可能。 override fun onSafeBrowsingHit(view: WebView, request: WebResourceRequest, threatType:
Int, callback: SafeBrowsingResponseCompat){ val dlg = AlertDialog.Builder(view.context) dlg.setTitle("Warning") dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください") dlg.setPositiveButton("詳細確認") { _, _ -> callback.showInterstitial(false) } dlg.setNegativeButton("元のページへ戻る") { _, _ -> callback.backToSafety(true) } dlg.setNeutralButton("ホームへ戻る") { _, _ -> view.loadUrl("https://www.google.co.jp")} dlg.show() }
WebViewClientCompat# onSafeBrowsingHit 第三引数:threatTypeは安全でないページと判断された理由。 以下の4種類が定義されている。 MALWARE、PHISHING、UNWANTED_SOFTWARE、UNKNOWN override fun onSafeBrowsingHit(view: WebView, request:
WebResourceRequest, threatType: Int, callback: SafeBrowsingResponseCompat){ ~~~~~~~~~ val StringThreatType:String = when(threatType){ 0 -> "未知の危険が検出された" 1 -> "マルウェア感染の疑いのある" 2 -> "フィッシングサイトの疑いのある" 3 -> "望まないアプリが配布される疑いのある" else -> "" } ~~~~~~~~~ dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください")
WebViewClientCompat# onSafeBrosingHit SafeBrowsingResponseCompatのアクションを、ダイアログのボタ ンに割り当てて、独自の確認ダイアログの設定も可能 override fun onSafeBrowsingHit(view: WebView, request: WebResourceRequest,
threatType: Int, callback: SafeBrowsingResponseCompat){ val dlg = AlertDialog.Builder(view.context) dlg.setTitle("Warning") dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください") dlg.setPositiveButton("詳細確認") { _, _ -> callback.showInterstitial(false) } dlg.setNegativeButton("元のページへ戻る") { _, _ -> callback.backToSafety(true) } dlg.setNeutralButton("ホームへ戻る") { _, _ -> view.loadUrl("https://www.google.co.jp")} dlg.show() }
WebViewClientCompat# onSafeBrosingHit WebViewインスタンスで直接特定ページに遷移させることも可能 override fun onSafeBrowsingHit(view: WebView, request: WebResourceRequest, threatType:
Int, callback: SafeBrowsingResponseCompat){ val dlg = AlertDialog.Builder(view.context) dlg.setTitle("Warning") dlg.setMessage(StringThreatType + request.url + "にアクセスしようとしています。¥n 元のページに戻る場合には「戻る」、詳しい説明を確認する場合は「詳細確認」をクリックしてください") dlg.setPositiveButton("詳細確認") { _, _ -> callback.showInterstitial(false) } dlg.setNegativeButton("元のページへ戻る") { _, _ -> callback.backToSafety(true) } dlg.setNeutralButton("ホームへ戻る") { _, _ -> view.loadUrl("https://www.google.co.jp")} dlg.show() }
threatTypeの注意事項 ◼WebViewClient(compat)で定義されているのは先に紹介した4つ ◼Chrome 71よりbillingが追加。 ◼不明瞭な支払い登録プロセスが対象 ◼このタイプはonSafeBrosingHitでは 0(UNKNOWN)として返ってきている。
WebSettingsCompat# setSafeBrowsingEnabled WebViewインスタンスごとに、 個別にSafeBrowsingの有効・無効を設定する。 Manifestファイルでの設定よりこっちが優先。 //第1引数に、SafeBrowsingを設定するWebViewインスタンスのWebSettingsを指定する WebSettingsCompat.setSafeBrowsingEnabled(webView.settings,true)
WebViewCompat# setSafeBrowsingWhitelist ホワイトリスト形式で、SafeBrowsingの対象外とするホ ストを指定可能。 ドメインかIPアドレス(v4,v6)での指定のため、一部ペー ジのみ対象とすることは出来ない。 if(WebViewFeature.isFeatureSupported(SAFE_BROWSING_WHITELIST)) { WebViewCompat.setSafeBrowsingWhitelist( ArrayList(Arrays.asList("testsafebrowsing.appspot.com"))
) { result -> Log.i("SafeBrowsing", “Add Whitelist " + result!!.toString()) } }
無効・除外設定の使いどころ ◼使いどころが難しい(安易に設定できない) ◼基本的な考え方は信頼できる対象を設定する。 ◼設定した対象が改ざんされていたら? ◼自サイトが間違って検出されることがあった場合に、 再審査の申請をして、受け入れられるまでのつなぎ? (ただし、その場合も自サイトに問題ないことを確認しないと、 ユーザに被害を及ぼすかもしれないので注意。)
Safeynet SafeBrowsing
◼Androidで使えるSafeBrowsingはもう一つ存在する。 ◼SafetyNet APIの一種であるSafeBrowsing ◼SafetyNet APIなのでGooglePlay開発者サービス ◼GooglePlay開発者サービスver8.1以降で利用可能 SafetyNet SafeBrowsing
◼Android版のchromeでは、SafeBrowsingの実行のために Safetynetを利用している。 ◼WebViewも同様 ◼つまり、WebViewでのSafeBrowsingも GooglePlay開発者サービスが入っていない端末では 利用できない。 SafeBrowsingの関係
まとめ
◼アクセス先のリスクをGoogleのデータベースを用 いて調べることができる機能。アクセス先を限定 できないときに利用するのがよい。 ◼SafeBrowsingのレスポンスを用いて、自アプリの ポリシに従った対応にすることができる。 ◼特定のホストをSafeBrowsingの対象外にすること は可能だが、本当に外しても問題ないかは要検討。 まとめ