Harden dashboard WebView (disable file/content access, mixed content, JS popups)#54
Merged
Conversation
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.
📝 WalkthroughWalkthrough
ChangesWebView Security Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardens the Clash/yacd dashboard WebView — the app's highest-risk web surface, since it
loads a user-editable URL (
DataStore.yacdURL) with JavaScript + DOM storage enabled.The yacd dashboard genuinely needs JS + DOM storage + localhost network, so those stay on.
Everything else is now explicitly disabled so the loaded page can never:
allowFileAccess = false)allowContentAccess = false)file://origins (allowFileAccessFromFileURLs = false,allowUniversalAccessFromFileURLs = false)mixedContentMode = MIXED_CONTENT_NEVER_ALLOW)javaScriptCanOpenWindowsAutomatically = false,setSupportMultipleWindows(false))Why
Previously only
javaScriptEnabled/domStorageEnabledwere set; all other WebView settingsrelied on platform defaults (and
allowFileAccessdefaults to true below API 30). Auser-supplied dashboard URL with JS enabled + filesystem access is a real exfiltration surface.
Testing
(
MetaCubeX/yacd0.3.6) loads and runs normally fromhttp://127.0.0.1:9090/ui— nonet::ERR_ACCESS_DENIED, no mixed-content blocks. The lockdown doesn't break the dashboard.Notes
WebSettings); did not addandroidx.webkit. SafeBrowsing/WebSettingsCompat could be a later enhancement but isn't needed to close the file/content
access surface.
Greptile Summary
This PR hardens the Clash/yacd dashboard
WebViewby explicitly disabling a set of insecure-by-default settings — file-system access, content-provider access, file-URL origin escalation, mixed content, and JS-initiated popups — while leavingjavaScriptEnabledanddomStorageEnabledon because the dashboard SPA requires them.allowFileAccess = false,allowContentAccess = false,allowFileAccessFromFileURLs = false, andallowUniversalAccessFromFileURLs = falseto prevent the user-supplied dashboard URL from reading device files or content providers (especially important below API 30, where these default totrue).mixedContentMode = MIXED_CONTENT_NEVER_ALLOWand disablesjavaScriptCanOpenWindowsAutomatically/setSupportMultipleWindowsto close the remaining popup and downgrade surfaces.Confidence Score: 5/5
Safe to merge — the change is additive security hardening with no functional regressions on the normal dashboard path.
Each new setting is applied correctly inside the WebSettings.apply block (including setSupportMultipleWindows, which is a WebSettings method, not a WebView method). The deprecated allowFileAccessFromFileURLs/allowUniversalAccessFromFileURLs flags are suppressed appropriately and still matter for pre-API-30 devices. The mixedContentMode change only affects pages served over HTTPS that try to load HTTP subresources; the default dashboard on http://127.0.0.1 is unaffected. No pre-existing logic (URL loading, menu handling, error callbacks) is altered.
No files require special attention.
Important Files Changed
applyscope to add explicit security hardening: file/content access disabled, deprecated file-URL cross-origin escalation flags suppressed, mixed-content blocked, and JS popups disabled. No logic changes to URL loading or menu handling.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[WebviewFragment.onViewCreated] --> B[WebView.setWebContentsDebuggingEnabled\nDEBUG builds only] B --> C[mWebView.settings.apply] C --> D[javaScriptEnabled = true\ndomStorageEnabled = true\nREQUIRED for Clash SPA] C --> E[allowFileAccess = false\nallowContentAccess = false\nPREVENTS filesystem/provider reads] C --> F[allowFileAccessFromFileURLs = false\nallowUniversalAccessFromFileURLs = false\nPREVENTS file:// origin escalation] C --> G[mixedContentMode = NEVER_ALLOW\nPREVENTS http downgrade on https pages] C --> H[javaScriptCanOpenWindowsAutomatically = false\nsetSupportMultipleWindows = false\nPREVENTS JS popup windows] D & E & F & G & H --> I[mWebView.loadUrl\nDataStore.yacdURL]%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A[WebviewFragment.onViewCreated] --> B[WebView.setWebContentsDebuggingEnabled\nDEBUG builds only] B --> C[mWebView.settings.apply] C --> D[javaScriptEnabled = true\ndomStorageEnabled = true\nREQUIRED for Clash SPA] C --> E[allowFileAccess = false\nallowContentAccess = false\nPREVENTS filesystem/provider reads] C --> F[allowFileAccessFromFileURLs = false\nallowUniversalAccessFromFileURLs = false\nPREVENTS file:// origin escalation] C --> G[mixedContentMode = NEVER_ALLOW\nPREVENTS http downgrade on https pages] C --> H[javaScriptCanOpenWindowsAutomatically = false\nsetSupportMultipleWindows = false\nPREVENTS JS popup windows] D & E & F & G & H --> I[mWebView.loadUrl\nDataStore.yacdURL]Reviews (1): Last reviewed commit: "security(webview): lock down the dashboa..." | Re-trigger Greptile