LoginSignup
3
3

More than 5 years have passed since last update.

iOSアプリのWebViewでのHSTS Super Cookieの取り扱い

Last updated at Posted at 2016-12-05

この記事はWanoグループ Advent Calendar 2016の5日目です。

結論

  • ATS(App Transport Security)をオンにしてたらそもそもhttpのサイトにアクセスできないから考えなくてよくね。

以下検証

そもそもHSTS Super Cookieってなによ

以下参照。
http://dev.classmethod.jp/client-side/browser/hsts-super-cookies/

HSTSという機能を実装しているブラウザは[Strict-Transport-Security]というヘッダがついているWebサイトを記録し、次回にそのサイトへのHTTPアクセスがあった場合はブラウザ側で判断し、直接HTTPSで接続しに行くというセキュリティ技術です。
(中略)
HSTSではアドレスの一文字一文字に対してtrueかfalseのbitに変換、それをバイナリ値(PIN、と言います)としてブラウザ内に保存します。そうすることで20億以上のタグ付けが可能になります。上で表示した組み合わせはこのバイナリ値をbase36変換したものです。

この保存した情報というのは、CookieとかLocal Storageとかとはデータの取り扱われ方が違うので、(対策されていないと)データが残り続ける可能性がある。
これでみんなトラッキングされまくり

事の経緯

会社のSlackのdeveloperチャンネルにこんな情報が投稿されてた。
http://www.radicalresearch.co.uk/lab/hstssupercookies/

先輩エンジニアよりざっくり要約

HSTS Super Cookie はFirefox は対策済み。Safariはやばいと書いているけど実際はやばくないらしい。IEはHSTS未対応なので関係ない。そうだ。

とのこと。
あれ、WebViewは??

というわけで検証してみた。

上記のサイトに各webViewでアクセスして、値が変わるかどうか調べた。
検証コードは以下のように雑に書いた。

  • UIWebView
ViewController.swift
import UIKit

class ViewController: UIViewController {
    var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = UIWebView(frame: UIScreen.main.bounds)
        let url = URL(string: "http://www.radicalresearch.co.uk/lab/hstssupercookies/")!
        let request = URLRequest(url: url)
        webView.loadRequest(request)
        view.addSubview(webView)
    }
}
  • WKWebView
ViewConroller2.swift
import UIKit
import WebKit

class ViewController2: UIViewController {
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = WKWebView(frame: UIScreen.main.bounds)
        let url = URL(string: "http://www.radicalresearch.co.uk/lab/hstssupercookies/")!
        let request = URLRequest(url: url)
        webView.load(request)
        view.addSubview(webView)
    }
}
  • SFSafariViewController
ViewController3.swift
import UIKit
import SafariServices

class ViewController3: UIViewController {
    @IBOutlet weak var containerView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "http://www.radicalresearch.co.uk/lab/hstssupercookies/")!
        let viewController = SFSafariViewController(url: url, entersReaderIfAvailable: true)
        viewController.view.frame = UIScreen.main.bounds

        addChildViewController(viewController)
        containerView.addSubview(viewController.view)
        viewController.didMove(toParentViewController: self)
    }
}
  • SFSafariViewControllerはViewじゃないのでContainerViewを使った。
  • もちろんATSをオフにしてhttpサイトへの接続を許可している。
  • この辺で、あれ、ATSだとそもそもhttpのサイトにアクセス出来ないから関係なくね?って気づいたけど気のせい。

結果

  • あり - 上記サイトで値に変化があった = HSTSで保存された情報がリセットされた
  • なし - 上記サイトで値に変化がなかった = HSTSで保存された情報がリセットされなかった
UIWebView WKWebView SFSafariViewController
webViewインスタンス作り直し なし なし なし
アプリの終了 なし なし なし
アプリの削除&インストール あり あり なし
端末の再起動 なし なし あり

考察

  • UIWebView、WKWebViewのHSTS情報の保存領域はアプリ内っぽい。
  • SFSafariViewControllerのは、そもそもwebView自体がSafariなので、Safariと同じ領域(OSのレイヤー?)に保存されている模様。
  • まぁ、1月から始まるATS必須化に合わせてhttpサイトにアクセスできなくなるから、そもそも関係ないけどな!!!!

余談

UIWebView、WKWebViewのHSTS情報をアプリ削除以外の方法でリセットできないだろうか

以下やってみたこと。
* UIWebViewのキャッシュ削除
* WKWebViewのキャッシュ削除
* /tmp、/Cachesディレクトリの削除

書いたコードはこんな。

AppDelegate.swift
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // UIWebView用キャッシュ削除
        URLCache.shared.removeAllCachedResponses()
        URLCache.shared.diskCapacity = 0
        URLCache.shared.memoryCapacity = 0

        // WKWebView用キャッシュ削除
        let websiteDataTypes = NSSet(array: [
            WKWebsiteDataTypeDiskCache,
            WKWebsiteDataTypeMemoryCache,
            WKWebsiteDataTypeCookies,
            WKWebsiteDataTypeLocalStorage,
            WKWebsiteDataTypeSessionStorage,
            WKWebsiteDataTypeWebSQLDatabases,
            WKWebsiteDataTypeIndexedDBDatabases,
            WKWebsiteDataTypeOfflineWebApplicationCache])
        WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set<String>, modifiedSince: Date(timeIntervalSince1970: 0), completionHandler: {})

        // アプリ全体のキャッシュをとにかく削除
        let pathArray = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, .userDomainMask, true)
        for path in pathArray {
            try? FileManager().removeItem(atPath: path)
        }
        try? FileManager().removeItem(atPath: NSTemporaryDirectory())

        return true
    }

結論

  • 消せない(´・ω・`)
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3