Agent Wranglers

MOB-46Recommended

Keep web views to your own pages

A web view inside the app loads only pages from an allowlist of your own https origins. Bridges from JavaScript to native code are present only while one of those pages is loaded.

How to do it

A JavaScript bridge, such as addJavascriptInterface on Android or a script message handler on iOS, reaches every frame of the page. A hostile ad, an injected script or a link to an outside site then calls native code with the app's permissions. Leave JavaScript off when the page is static. Open every link outside the allowlist in the system browser. Turn off file access from web content on Android with setAllowFileAccess(false). Accept web messages only from a named origin, never *. Pages shown in the web view follow allow only the scripts you wrote.

Examples

Kotlin example

private val allowedHosts = setOf("help.example.com")

webView.settings.allowFileAccess = false
webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
        val url = request.url
        if (url.scheme == "https" && url.host in allowedHosts) return false
        startActivity(Intent(Intent.ACTION_VIEW, url))
        return true
    }
}

Plain text example

let allowedHosts: Set<String> = ["help.example.com"]

func webView(_ webView: WKWebView, decidePolicyFor action: WKNavigationAction,
             decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let url = action.request.url else { return decisionHandler(.cancel) }
    if url.scheme == "https", let host = url.host, allowedHosts.contains(host) { return decisionHandler(.allow) }
    UIApplication.shared.open(url)
    decisionHandler(.cancel)
}

How to check

A test loads an outside URL in each web view and the page opens in the system browser instead. A test page from an origin outside the allowlist finds no native bridge object.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/mobile-apps/network-links-and-web-views/locked-web-views">Agent Wranglers mobile apps playbook</a>. In code you write, add a comment next to it with the same link.