ControlPanelFragment.afterView (SmartRemoteControl/src/main/java/com/github/timnew/smartremotecontrol/ControlPanelFragment.java) configures the panel WebView with:
settings.setJavaScriptEnabled(true);
settings.setAllowContentAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
panel.addJavascriptInterface(emitter, "ir");
...
panel.loadUrl(layoutUrl);
layoutUrl is built from PANEL_PATH_TEMPLATE = "file:///android_asset/panels/%s/index.html", so the WebView's main frame is a file:// document. The ir JS bridge is attached.
The panel JS (assets/js/Panel.coffee) does:
loadJson: (jsonFile, callback) ->
url = @resolveUrl jsonFile
$.getJSON url, (data) =>
callback data
resolveUrl resolves the JSON descriptor relative to the panel's own URL, so it ends up as file:///android_asset/panels/<name>/<file>.json. That XHR is file:// to file://, which needs setAllowFileAccessFromFileURLs(true).
setAllowUniversalAccessFromFileURLs(true) is the strictly broader flag: it lets a file:// page XHR any origin, not just other file:// resources. The panel JS only ever fetches a sibling .json from android_asset, so this flag is not load-bearing for any existing panel. With the ir bridge attached, leaving it on would let an attacker-controlled panel exfiltrate IR command data or anything else the bridge exposes to a remote host (CWE-200).
Suggested fix
Drop setAllowUniversalAccessFromFileURLs(true). Keep setAllowFileAccessFromFileURLs(true) so the sibling-JSON loading continues to work.
A PR is open at #10.
ControlPanelFragment.afterView(SmartRemoteControl/src/main/java/com/github/timnew/smartremotecontrol/ControlPanelFragment.java) configures the panel WebView with:layoutUrlis built fromPANEL_PATH_TEMPLATE = "file:///android_asset/panels/%s/index.html", so the WebView's main frame is afile://document. TheirJS bridge is attached.The panel JS (
assets/js/Panel.coffee) does:resolveUrlresolves the JSON descriptor relative to the panel's own URL, so it ends up asfile:///android_asset/panels/<name>/<file>.json. That XHR isfile://tofile://, which needssetAllowFileAccessFromFileURLs(true).setAllowUniversalAccessFromFileURLs(true)is the strictly broader flag: it lets afile://page XHR any origin, not just otherfile://resources. The panel JS only ever fetches a sibling.jsonfromandroid_asset, so this flag is not load-bearing for any existing panel. With theirbridge attached, leaving it on would let an attacker-controlled panel exfiltrate IR command data or anything else the bridge exposes to a remote host (CWE-200).Suggested fix
Drop
setAllowUniversalAccessFromFileURLs(true). KeepsetAllowFileAccessFromFileURLs(true)so the sibling-JSON loading continues to work.A PR is open at #10.