iOSのWKWebViewでURLを扱う際に注意すべき脆弱性

iOSのWKWebViewでURLを扱う際に注意すべき脆弱性

サイバーセキュリティエンジニアリング部の西村です。先日、PacSec 2016というセキュリティカンファレンスでiOS版Firefoxの脆弱性に関する講演をしてきました。

pacsec%e8%ac%9b%e6%bc%94%e8%80%85%e9%9b%86%e5%90%88%e5%86%99%e7%9c%9f

iOS版FirefoxはWebページの表示にiOSのWKWebViewを使用しており、講演の中で紹介した脆弱性はいずれもWKWebViewを利用するiOSアプリで発生しうるものです。この記事では、iOS版Firefoxの脆弱性事例を元に、WKWebViewでURLを取り扱う際に注意すべきポイントを紹介します。

URLのuserinfoフィールドを考慮する

WKWebViewでは、urlというプロパティを用いて、現在表示しているWebページのURLを取得できます。しかし、urlプロパティの値を表示するとき、注意すべき点があります。それは、URLのuserinfoというフィールドです。

URLの仕様を定めるRFC 3986では、「http://user.password@hostname」という形でURLに認証情報(userinfo)を含めることが許されています。しかし、userinfoを画面に表示することは、接続するホストの誤認を招き、フィッシングに悪用される可能性がある(※クリックするとIETFのWebサイトに遷移します。)ことから、ブラウザのアドレスバーのようにURLをセキュリティインジケータとして表示する際には特別なケアが求められてきました。たとえば、以下のURLを見てください。このURLは「cnn.example.com」というホストに接続するかのように見えますが、実際は「recruit-tech.co.jp」に接続します。

http://cnn.example.com&story=breaking_news@recruit-tech.co.jp/

userinfoを悪用した攻撃を防ぐため、ブラウザベンダーは様々な対策をしてきました。Internet ExplorerやChromeはuserinfoをアドレスバーに表示しません。Safariは以下のようにフィッシングの疑いを伝える警告画面を表示します。

%e3%83%95%e3%82%a3%e3%83%83%e3%82%b7%e3%83%b3%e3%82%b0web%e3%82%b5%e3%82%a4%e3%83%88%e3%81%ae%e7%96%91%e3%81%84%e8%ad%a6%e5%91%8a%e7%94%bb%e9%9d%a2

しかし、WKWebViewのurlプロパティにはuserinfoを含むURLがそのまま含まれます。このため、urlプロパティの値をそのまま画面に表示すると、悪意のあるWebサイトにURLを偽装されるリスクが生じます。このような攻撃を避けるため、アプリでURLを表示する際は、事前にuserinfoを取り除くことが望ましいでしょう。
iOS版Firefoxの初期バージョンでは、urlプロパティの値をそのままアドレスバーに出力していたため、以下のようにアドレスバーを偽装されるリスクがありました。これは、開発元のMozilla Corporationから正式に脆弱性として認定されました(現在は修正済みです)。

%e3%82%a2%e3%83%89%e3%83%ac%e3%82%b9%e3%83%90%e3%83%bc%e5%81%bd%e8%a3%85

urlプロパティとWKWebViewの内部状態の不一致を考慮する

WKWebViewでは、表示しているWebページが切り替わるとurlプロパティの値も自動的に切り替わりますが、このタイミングには時間差があります。urlプロパティの値はページの遷移を開始した時点で次のページのURLに切り替わるのに対し、WKWebViewの内部状態は、ページの読み込みが完了した時点(サーバからHTTPレスポンスを受信し終えた時点)で切り替わるのです。

wkwebview%e3%81%aeurl%e3%81%a8%e5%86%85%e9%83%a8%e7%8a%b6%e6%85%8b%e3%81%ae%e6%9b%b4%e6%96%b0%e3%82%bf%e3%82%a4%e3%83%9f%e3%83%b3%e3%82%b0%e3%81%ae%e9%81%95%e3%81%84

この更新タイミングの違いは、思わぬ脆弱性の原因となることがあります。過去にiOS版Firefoxのパスワードマネージャーには、異なるWebサイトの読み込みを開始した直後にログインフォームの自動入力を要求すると、他のWebサイトのパスワードをフォームに入力してしまう脆弱性(※クリックするとMozilla FoundationのWebサイトに遷移します。)がありました。

iOS版Firefoxのパスワードマネージャーの脆弱性

この脆弱性は、パスワードマネージャーがログインフォームの自動入力を求められた際、WKWebViewのurlプロパティから要求元のサイトを識別していたためでした。表示中のWebページのURLに基づいてアプリで何らかの処理をする場合は、WKWebViewのurlプロパティは使用せず、各delegate関数に引数として渡されるWKFrameInfoオブジェクトのrequest.URLやsecurityOriginを用いることが望ましいでしょう。

その他の脆弱性について

PacSec 2016の講演では、この他にも、Script Messagesの誤った使い方や、アプリ内部でlocalhostのWebサーバを立てる際の注意点に触れています。ご興味のある方は、是非、講演スライドをご覧ください。

※本文中のリンクは、補足説明用に設置しています