Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
WebViewを守るSafeBrowsingのコントロール / Control result ...
Search
Aki
February 08, 2019
Technology
940
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebViewを守るSafeBrowsingのコントロール / Control result of SafeBrowsing in WebView
DroidKaigi2019 Day2での発表スライドです。
Aki
February 08, 2019
More Decks by Aki
See All by Aki
厳しくなったSafetyNet Attestationによる端末チェック
akihiroshiota
2
2.4k
Other Decks in Technology
See All in Technology
Rust で関数型ドメインモデリング
takonda
0
140
継続的なAIコスト最適化
bgpat
1
340
go-sqletch
moznion
0
140
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
730
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
190
⾮構造化データを価値に変える AI エージェント基盤とその組織
ivry_presentationmaterials
0
190
自作バイナリを動かす「入口」8選
puhitaku
2
1.3k
「事実」を「計測」して、「解釈」する 〜AWS Lambdaのメモリ最適解の見つけ方〜
maimyyym
0
170
Metadata - Section 1: HTML Basics
mohab1
0
120
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.7k
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
150
Featured
See All Featured
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
310
Prompt Engineering for Job Search
mfonobong
0
520
The Pragmatic Product Professional
lauravandoore
37
7.5k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Intergalactic Javascript Robots from Outer Space
tanoku
273
28k
Agile that works and the tools we love
rasmusluckow
331
22k
Design in an AI World
tapps
1
350
Rails Girls Zürich Keynote
gr2m
96
14k
エンジニアに許された特別な時間の終わり
watany
109
250k
Exploring anti-patterns in Rails
aemeredith
4
540
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
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の対象外にすること は可能だが、本当に外しても問題ないかは要検討。 まとめ