Summary
ThemeRemoteInstallPolicy.isAllowedUrl() correctly blocks localhost and private IPs when allowLocalhostInDebug: false, but production code constructs ThemeRemoteInstallService with the constructor default allowLocalhostInDebug: true.
ThemeController.importRegistryThemeFromUrl() uses:
remoteInstallService ?? ThemeRemoteInstallService(_registryService);
So in release builds, remote theme install can fetch from https://127.0.0.1, https://192.168.x.x, etc. — enabling SSRF-style access to local services if a user installs a theme from a malicious URL.
Affected code
lib/core/theme/theme_remote_install_service.dart (line 30 — default true)
lib/core/theme/theme_controller.dart (line 468)
lib/core/theme/theme_remote_install_policy.dart
Proposed fix
- Change default to
allowLocalhostInDebug: kDebugMode (match policy API default).
- Audit all call sites; ensure tests inject explicit flag where needed.
- Add release-mode test: localhost URL is rejected.
Acceptance criteria
Severity
Medium — SSRF to local services via user-triggered theme URL install.
Related
Summary
ThemeRemoteInstallPolicy.isAllowedUrl()correctly blocks localhost and private IPs whenallowLocalhostInDebug: false, but production code constructsThemeRemoteInstallServicewith the constructor defaultallowLocalhostInDebug: true.ThemeController.importRegistryThemeFromUrl()uses:So in release builds, remote theme install can fetch from
https://127.0.0.1,https://192.168.x.x, etc. — enabling SSRF-style access to local services if a user installs a theme from a malicious URL.Affected code
lib/core/theme/theme_remote_install_service.dart(line 30 — defaulttrue)lib/core/theme/theme_controller.dart(line 468)lib/core/theme/theme_remote_install_policy.dartProposed fix
allowLocalhostInDebug: kDebugMode(match policy API default).Acceptance criteria
Severity
Medium — SSRF to local services via user-triggered theme URL install.
Related