From 0294bd944e01a4335f2c0dddfbcbcf43d9f500cf Mon Sep 17 00:00:00 2001 From: hawkff <109485367+hawkff@users.noreply.github.com> Date: Sun, 21 Jun 2026 13:39:23 -0400 Subject: [PATCH] security(webview): lock down the dashboard WebView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Clash/yacd dashboard WebView loads a user-editable URL (DataStore.yacdURL) with JavaScript + DOM storage enabled (the yacd SPA requires both). Everything else is now explicitly locked down so that page can never read the device filesystem or content providers, escalate from file:// origins, downgrade to cleartext on an https page, or spawn JS popups: - allowFileAccess = false - allowContentAccess = false - allowFileAccessFromFileURLs = false - allowUniversalAccessFromFileURLs = false - mixedContentMode = MIXED_CONTENT_NEVER_ALLOW - javaScriptCanOpenWindowsAutomatically = false; setSupportMultipleWindows(false) Verified on-device: the yacd dashboard (MetaCubeX/yacd 0.3.6) still loads and runs from http://127.0.0.1:9090/ui — no access-denied / mixed-content errors. --- .../sagernet/ui/WebviewFragment.kt | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/WebviewFragment.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/WebviewFragment.kt index e1f0a6cd5..3f5b85356 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/WebviewFragment.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/WebviewFragment.kt @@ -35,8 +35,25 @@ class WebviewFragment : ToolbarFragment(R.layout.layout_webview), Toolbar.OnMenu // webview WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG) mWebView = binding.webview - mWebView.settings.domStorageEnabled = true - mWebView.settings.javaScriptEnabled = true + mWebView.settings.apply { + // The Clash/yacd dashboard is a JS SPA talking to the local Clash API, so JS + // and DOM storage are required. Everything else is locked down: the dashboard + // (a user-editable URL) must never be able to read the device filesystem or + // content providers, escalate from file:// origins, or downgrade to cleartext + // resources on an https page. + javaScriptEnabled = true + domStorageEnabled = true + allowFileAccess = false + allowContentAccess = false + @Suppress("DEPRECATION") + allowFileAccessFromFileURLs = false + @Suppress("DEPRECATION") + allowUniversalAccessFromFileURLs = false + mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW + // No automatic JS-initiated window.open popups. + javaScriptCanOpenWindowsAutomatically = false + setSupportMultipleWindows(false) + } mWebView.webViewClient = object : WebViewClient() { override fun onReceivedError( view: WebView?, request: WebResourceRequest?, error: WebResourceError?