From 37e9218665ee794eb0827ffba5621f9cdea3f2ea Mon Sep 17 00:00:00 2001 From: boburning Date: Mon, 31 Aug 2026 02:06:54 -0400 Subject: [PATCH] security(network): retire stale HTTP Tweaks exposure (NET-10) --- docs/1.0_TEST_MATRIX.md | 2 +- docs/SECURITY.md | 4 +- src/tweaks/appstate.h | 2 - src/tweaks/network.h | 61 --------------- src/tweaks/tweaks.c | 1 - test/shell/bloom_shell_runtime.bats | 12 +++ test/shell/branding_copy.bats | 2 +- test/test_ci_scope.sh | 4 + tools/ci-scope.sh | 4 +- website/docs/01-features/index.md | 2 +- .../07-apps/01-included-in-onion/tweaks.mdx | 6 -- .../02-http-file-server.md | 76 +++---------------- .../07-apps/03-network-features/04-ftp.md | 2 +- 13 files changed, 34 insertions(+), 144 deletions(-) diff --git a/docs/1.0_TEST_MATRIX.md b/docs/1.0_TEST_MATRIX.md index 6886fcada..87eae64c7 100644 --- a/docs/1.0_TEST_MATRIX.md +++ b/docs/1.0_TEST_MATRIX.md @@ -52,7 +52,7 @@ shoulder button. | Critical lifecycle | Exact 640x480 and 752x560 built-in projections; source/target/path and legacy-file rejection; boot/shutdown/save/low-battery/recovery/Safe Mode ignore theme/config/media; charging reflects bounded actual level; installer uses one deterministic surface; missing optional text/font fallback; signed Full-update boot/charging/shutdown/recovery checkpoint | | Settings | One sectioned surface; inline values; capability filtering; one-layer details; hidden Developer section; optional overlapping L1/R1 list paging | | Quick Settings | START from core surfaces; immediate brightness/volume/mute; capability-gated Wi-Fi opens the dedicated detail surface; Wi-Fi left/right never mutates the radio; readable battery; B/START close | -| Network services | Desired/runtime separation; carrier without IPv4 remains acquiring/not-ready; canonical DHCP restart and bounded post-address listener reconciliation; SSH shell and SFTP independent key-only states; canonical transfer roots and modes; Saves read-only; private roots denied; traversal/symlink/path bounds; same-filesystem atomic publication; authorized-key import; quiesce/health; stale FTP/Telnet/FileBrowser/inherited-Samba/WPS/hotspot flags cannot activate listeners; process-aware listener audit; dormant Telnet launcher/Tweaks exposure, FileBrowser HTTP, and rejected Samba payloads absent from newly assembled stable artifacts while older-card remnants remain locked down | +| Network services | Desired/runtime separation; carrier without IPv4 remains acquiring/not-ready; canonical DHCP restart and bounded post-address listener reconciliation; SSH shell and SFTP independent key-only states; canonical transfer roots and modes; Saves read-only; private roots denied; traversal/symlink/path bounds; same-filesystem atomic publication; authorized-key import; quiesce/health; stale FTP/Telnet/FileBrowser/inherited-Samba/WPS/hotspot flags cannot activate listeners; process-aware listener audit; dormant Telnet and FileBrowser HTTP launcher/Tweaks exposure plus rejected Samba payloads absent from newly assembled stable artifacts while older-card remnants remain locked down | | Wi-Fi profile store | JFFS2 private root; stdin-only bounded replacement and `bloomctl network profile upsert ID`; requested/document ID binding; explicit `network forget ID`; inactive-ID deletion with active-profile refusal; active forget only after a separately confirmed fallback connection; schema/unknown-field/count/size enforcement; WPA2-PSK, explicit open, and manual hidden WPA2; WEP and hidden open denial; unique IDs/SSIDs; redacted status; explicit local credential-free UI list with one active marker; sanitized `network connect status` with internal profile-handle validation and public omission; mode-0600 atomic single-profile supplicant projection; symlink, occupied-slot, live-lock, invalid-profile, and prior-byte preservation | | Wi-Fi scan API | Asynchronous start; redacted status; explicit ID-scoped local results; cancel and terminal discard; one active worker; five-second rate limit; 15-second runtime; 64-KiB raw ceiling; 32 unique printable SSIDs; eight-operation history; open/WPA2-PSK/unsupported classification; duplicate signal reconciliation; backend failure, timeout, oversize, unsafe-path, stale/live-lock, and unsupported-hardware handling | | Wi-Fi UI | Original Mini hidden; Settings, Shell Quick Settings, and GameSwitcher Quick Settings converge on `--settings-wifi`; direct radio toggle removed; bounded fixed-argv profile-list load outside render; connection state and saved-network detail; selectable Scan/Cancel row and read-only discovered networks; active-only 100-ms SDL wake; deferred GameSwitcher until cancellation discard; single-flight nonblocking fixed-argv scan client; 16-KiB output and five-second deadline; child process-group cleanup; controller-owned start/status/results/discard and cancel-during-start sequencing; 250-ms status opportunities; exact profile/scan/ack schemas; 16 profiles and 32 networks; unique bounded IDs/SSIDs; one active profile; fixed scan phases/errors; terminal history discarded; open/WPA2 profile form with shared keyboard, masked secret, fixed profile-upsert argv, escaped stdin JSON, strict ID/SSID/PSK validation, explicit secret clearing, nonblocking submit/poll, 4-KiB acknowledgement cap, exact upsert response, timeout process-group cleanup, exact saved-ID reuse, 104-bit no-follow random new handles, collision/security/full-store rejection, one editing/submitting controller with 100-ms poll opportunities, exact cancellation, terminal clearing, bounded focus return, supported scan-result selection, explicit saved-not-connected result, and no implicit association; explicit inactive-profile X/confirm forget flow; active-row refusal in Shell and store; fixed nonblocking delete; exact acknowledgement; terminal projection reload; graceful TERM cleanup before bounded KILL; exact guarded-connect status model with fixed phases/operations/failures, lease consistency, 64-byte transaction-ID and 300-second deadline ceilings, and discarded transaction/overlay identity; fixed no-follow `network connect status` loader with less-than-4-KiB output, five-second read ceiling, and stale-state clearing; separately typed single-flight nonblocking status request with process-group timeout and generic-poller refusal; controller-owned single request, 100-ms opportunities, duplicate-begin refusal, typed terminal state, teardown reaping, explicit guarded-state presentation, one-second freshness, fail-closed mutation gating for stale/unavailable/lease-armed/rollback-failed results, read-only refresh without queued intent, and exit teardown; credential and unknown-field rejection; passwords absent from arguments, logs, screenshots, durable Shell state, and evidence | diff --git a/docs/SECURITY.md b/docs/SECURITY.md index b72e57bc6..49224a1bc 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -20,7 +20,9 @@ stops their known processes. `bloom-listener-audit` provides a bounded, process-aware check that names service classes without publishing addresses. The dormant FileBrowser executable, database, web theme, icon, and boot-time initializer are excluded from newly assembled stable payloads; detection and -process cleanup remain for rollback-compatible remnants on older cards. +process cleanup remain for rollback-compatible remnants on older cards. Its +HTTP state, authentication controls, default-credential text, and Tweaks menu +are no longer exposed by the stable UI. The inherited Telnet environment launcher, dormant start logic, and visible Tweaks toggle are also excluded; stale-state cleanup and exact BusyBox `telnetd` termination remain for older-card compatibility. diff --git a/src/tweaks/appstate.h b/src/tweaks/appstate.h index ab11096b9..7d2f361c8 100644 --- a/src/tweaks/appstate.h +++ b/src/tweaks/appstate.h @@ -19,7 +19,6 @@ static List _menu_network; static List _menu_wifi; static List _menu_ftp; static List _menu_wps; -static List _menu_http; static List _menu_smbd; static List _menu_vnc; @@ -29,7 +28,6 @@ void menu_network_free_all(void) list_free(&_menu_wifi); list_free(&_menu_ftp); list_free(&_menu_wps); - list_free(&_menu_http); list_free(&_menu_smbd); list_free(&_menu_vnc); } diff --git a/src/tweaks/network.h b/src/tweaks/network.h index 344fb8527..2c311baff 100644 --- a/src/tweaks/network.h +++ b/src/tweaks/network.h @@ -28,14 +28,12 @@ static struct network_s { bool smbd; - bool http; bool ftp; bool hotspot; bool ntp; bool ntp_wait; bool auth_smbd; bool auth_ftp; - bool auth_http; bool manual_tz; bool check_updates; bool keep_alive; @@ -53,14 +51,12 @@ void network_loadState(void) return; network_state.smbd = config_flag_get(".smbdState"); - network_state.http = config_flag_get(".httpState"); network_state.ftp = config_flag_get(".ftpState"); network_state.hotspot = config_flag_get(".hotspotState"); network_state.ntp = config_flag_get(".ntpState"); network_state.ntp_wait = config_flag_get(".ntpWait"); network_state.force_wifi_on_startup = config_flag_get(".ntpForce"); network_state.auth_ftp = config_flag_get(".authftpState"); - network_state.auth_http = config_flag_get(".authhttpState"); network_state.manual_tz = config_flag_get(".manual_tz"); network_state.check_updates = config_flag_get(".checkUpdates"); network_state.keep_alive = config_flag_get(".keepServicesAlive"); @@ -248,11 +244,6 @@ void network_setSmbdState(void *pt) network_commonEnableToggle(&_menu_smbd, (ListItem *)pt, &network_state.smbd, "smbd", ".smbdState"); } -void network_setHttpState(void *pt) -{ - network_commonEnableToggle(&_menu_http, (ListItem *)pt, &network_state.http, "http", ".httpState"); -} - void network_setFtpState(void *pt) { network_commonEnableToggle(&_menu_ftp, (ListItem *)pt, &network_state.ftp, "ftp", ".ftpState"); @@ -301,12 +292,6 @@ void network_setFtpAuthState(void *pt) network_execServiceAuth("ftp"); } -void network_setHttpAuthState(void *pt) -{ - network_setState(&network_state.auth_http, ".authhttpState", ((ListItem *)pt)->value); - network_execServiceAuth("http"); -} - void network_wpsConnect(void *pt) { system("sh " NET_SCRIPT_PATH "/wpsclient.sh"); @@ -431,37 +416,6 @@ void menu_smbd(void *pt) header_changed = true; } -void menu_http(void *pt) -{ - ListItem *item = (ListItem *)pt; - item->value = (int)network_state.http; - if (!_menu_http._created) { - _menu_http = list_create(2, LIST_SMALL); - strcpy(_menu_http.title, "HTTP"); - list_addItemWithInfoNote(&_menu_http, - (ListItem){ - .label = "Enable", - .item_type = TOGGLE, - .value = (int)network_state.http, - .action = network_setHttpState}, - item->info_note); - list_addItemWithInfoNote(&_menu_http, - (ListItem){ - .label = "Enable authentication", - .item_type = TOGGLE, - .disabled = !network_state.http, - .value = (int)network_state.auth_http, - .action = network_setHttpAuthState}, - "Username: admin\n" - "Password: admin\n" - " \n" - "It's recommended you change this\n" - "at first login."); - } - menu_stack[++menu_level] = &_menu_http; - header_changed = true; -} - void menu_ftp(void *pt) { ListItem *item = (ListItem *)pt; @@ -608,21 +562,6 @@ void menu_network(void *_) " \n" "Username: onion\n" "Password: onion\n"); - list_addItemWithInfoNote(&_menu_network, - (ListItem){ - .label = "HTTP: Web-based file sync...", - .item_type = TOGGLE, - .disabled = !settings.wifi_on, - .alternative_arrow_action = true, - .arrow_action = network_setHttpState, - .value = (int)network_state.http, - .action = menu_http}, - "HTTP file server allows you to manage your\n" - "files through a web browser on your phone,\n" - "PC or tablet.\n" - " \n" - "Think of it as a website hosted by BloomOS,\n" - "simply enter the IP address in your browser."); list_addItemWithInfoNote(&_menu_network, (ListItem){ .label = "FTP: File server...", diff --git a/src/tweaks/tweaks.c b/src/tweaks/tweaks.c index df1a066fb..21c4dbd7b 100644 --- a/src/tweaks/tweaks.c +++ b/src/tweaks/tweaks.c @@ -47,7 +47,6 @@ void check_networkChanged(void) bool modified = temp_flag_get("network_changed"); modified |= check_menuHasChanges(&_menu_network); modified |= check_menuHasChanges(&_menu_ftp); - modified |= check_menuHasChanges(&_menu_http); modified |= check_menuHasChanges(&_menu_date_time); temp_flag_set("network_changed", modified); } diff --git a/test/shell/bloom_shell_runtime.bats b/test/shell/bloom_shell_runtime.bats index 0dfe268c4..13f1c23bb 100644 --- a/test/shell/bloom_shell_runtime.bats +++ b/test/shell/bloom_shell_runtime.bats @@ -203,6 +203,7 @@ @test "prohibited whole-card FileBrowser HTTP is absent from stable payloads" { runtime=/workspace/static/build/.tmp_update/runtime.sh + tweaks=/workspace/src/tweaks/network.h [ ! -e /workspace/static/build/.tmp_update/bin/filebrowser ] [ ! -e /workspace/static/configs/.tmp_update/config/filebrowser ] @@ -216,6 +217,17 @@ ! grep -F 'check_httpstate()' "$network" ! grep -F 'http_authed()' "$network" ! grep -F 'is_noauth_enabled()' "$network" + ! grep -F 'network_state.http' "$tweaks" + ! grep -F 'network_state.auth_http' "$tweaks" + ! grep -F 'network_setHttpState' "$tweaks" + ! grep -F 'network_setHttpAuthState' "$tweaks" + ! grep -F 'menu_http' "$tweaks" + ! grep -F 'HTTP: Web-based file sync' "$tweaks" + http_doc=/workspace/website/docs/07-apps/03-network-features/02-http-file-server.md + grep -F 'BloomOS does not ship or start the inherited FileBrowser HTTP server' "$http_doc" + grep -F '/docs/network/ssh' "$http_doc" + ! grep -F 'Enabling HTTP file server' "$http_doc" + ! grep -F 'HTTP: Web-based file sync' /workspace/website/docs/07-apps/01-included-in-onion/tweaks.mdx } @test "boot reconciles signed application declarations before Bloom Shell reads the catalog" { diff --git a/test/shell/branding_copy.bats b/test/shell/branding_copy.bats index 0b07ed92f..706275610 100644 --- a/test/shell/branding_copy.bats +++ b/test/shell/branding_copy.bats @@ -5,7 +5,7 @@ [ "$status" -eq 0 ] [[ "$output" == "branding copy validate: 10 classified legacy literals" ]] - grep -F 'website hosted by BloomOS' /workspace/src/tweaks/network.h + ! grep -F 'website hosted by' /workspace/src/tweaks/network.h grep -F 'between BloomOS and a PC' /workspace/src/tweaks/network.h grep -F 'Reset all BloomOS system settings' /workspace/src/tweaks/menus.h grep -F 'BloomOS save folder map' /workspace/static/configs/Saves/CurrentProfile/saves/README.txt diff --git a/test/test_ci_scope.sh b/test/test_ci_scope.sh index 75a84db87..31b45916f 100755 --- a/test/test_ci_scope.sh +++ b/test/test_ci_scope.sh @@ -116,6 +116,8 @@ expect "none" static-analysis "tools/legacy_manifest.py tools/ci-scope.sh" expect "none" build "tools/legacy_manifest.py tools/ci-scope.sh" +expect "none" build "website/docs/07-apps/03-network-features/02-http-file-server.md" +expect "none" static-analysis "website/docs/07-apps/03-network-features/02-http-file-server.md" expect "none" static-analysis "build/core-selection-policy.schema.json tools/validate_core_selection_policy.py test/fixtures/core-selection-policy/valid.json" @@ -137,6 +139,7 @@ expect "full" build "tools/build-retroarch-parallel.sh" expect "full" build "tools/build-ci-arm.sh" expect "0" risk "docs/ARCHITECTURE.md" +expect "0" risk "website/docs/07-apps/03-network-features/02-http-file-server.md" expect "1" risk "src/bloomShell/bloom_shell_root.c" expect "2" risk "src/bloomShell/bloom_shell_settings.c" expect "2" risk "src/bloomLibrary/bloom_library_query.c" @@ -265,6 +268,7 @@ expect "/workspace/test/shell/bloom_platform.bats /workspace/test/shell/core_sel expect "1" risk "docs/validation/ui/plus-ui12-lifecycle-surfaces-20260829.json" expect "/workspace/test/shell/bloom_platform.bats /workspace/test/shell/core_selection_policy.bats /workspace/test/shell/critical_surfaces.bats /workspace/test/shell/ra_evidence.bats" shell-tests "docs/validation/ui/plus-ui12-lifecycle-surfaces-20260829.json" expect "none" shell-tests "docs/DEVELOPMENT.md" +expect "none" shell-tests "website/docs/07-apps/03-network-features/02-http-file-server.md" expect "3" risk "docs/DEVELOPMENT.md static/build/.tmp_update/runtime.sh" diff --git a/tools/ci-scope.sh b/tools/ci-scope.sh index 8654a113a..41aab80f6 100755 --- a/tools/ci-scope.sh +++ b/tools/ci-scope.sh @@ -297,7 +297,7 @@ while IFS= read -r path; do build/save-migration-policy*.json|\ build/transfer-policy*.json|\ build/display-profile-policy.json|build/display-built-in-profiles.json|build/display-visual-pack-providers.json|\ - static/*|assets/ui/*|test/*|docs/*|tools/legacy_manifest.py|\ + static/*|assets/ui/*|test/*|docs/*|website/*|tools/legacy_manifest.py|\ tools/generate_bloom_ui_assets.py|tools/project_bloom_lifecycle_assets.py|tools/validate_bloom_ui_assets.py|tools/requirements-ui-assets.txt|\ tools/validate_core_selection_policy.py|tools/validate_core_inventory_disposition.py|tools/validate_save_migration_policy.py|tools/validate_transfer_policy.py|\ tools/display_profile_policy.py|tools/display_built_in_profiles.py|tools/display_visual_pack_providers.py|tools/ci-scope.sh) @@ -450,7 +450,7 @@ while IFS= read -r path; do add_shell_target /workspace/test/shell/critical_surfaces.bats add_shell_target /workspace/test/shell/ra_evidence.bats ;; - docs/*|README.md|LICENSE) + docs/*|website/*|README.md|LICENSE) raise_risk 0 ;; test/shell/*.bats) diff --git a/website/docs/01-features/index.md b/website/docs/01-features/index.md index 2984b48f0..948642585 100644 --- a/website/docs/01-features/index.md +++ b/website/docs/01-features/index.md @@ -210,7 +210,7 @@ For the Miyoo Mini Plus (equipped with wifi) Onion offers many additional possib - [Automatic date/time synchronisation](apps/tweaks#set-automatically-via-the-internet) (NTP, via Tweaks app) - [Retroachivements](https://www.retroarch.com/?page=achievements) - [Scraper](/docs/apps/scraper): import game covers directly from your MMP -- [Network Services](network-features): [Samba/SMB share](network/samba), [http server](network/http), [SSH](network/ssh), [FTP](network/ftp), [Hotspot](network/hotspot), [VNC server](network/vnc)... +- [Network Services](network-features): [Samba/SMB share](network/samba), [HTTP server (retired)](network/http), [SSH](network/ssh), [FTP](network/ftp), [Hotspot](network/hotspot), [VNC server](network/vnc)... ::: diff --git a/website/docs/07-apps/01-included-in-onion/tweaks.mdx b/website/docs/07-apps/01-included-in-onion/tweaks.mdx index d2b88df35..4af3c5412 100644 --- a/website/docs/07-apps/01-included-in-onion/tweaks.mdx +++ b/website/docs/07-apps/01-included-in-onion/tweaks.mdx @@ -180,12 +180,6 @@ It can be MainUI, [GameSwitcher](./game-switcher), [Retroarch](./retroarch) or [
-### HTTP: Web-based file sync... - -
HTTP file server allows you to manage your files through a web browser on your phone, PC, or tablet. Think of it as a website hosted by Onion; simply enter the IP address in your browser.
-
-
- ### SSH: Secure shell...
SSH provides a secure command line host for communicating with your device remotely. SFTP provides a secure file transfer protocol.
diff --git a/website/docs/07-apps/03-network-features/02-http-file-server.md b/website/docs/07-apps/03-network-features/02-http-file-server.md index 8885788c3..42cddef76 100644 --- a/website/docs/07-apps/03-network-features/02-http-file-server.md +++ b/website/docs/07-apps/03-network-features/02-http-file-server.md @@ -2,73 +2,15 @@ slug: /network/http --- +# HTTP file server (retired) -# HTTP file server +BloomOS does not ship or start the inherited FileBrowser HTTP server. It +exposed the whole SD card through a browser-facing service and did not meet the +stable product's listener, privacy, provenance, or least-privilege boundaries. -![](https://github.com/OnionUI/Onion/assets/47260768/27adb5f7-2665-4b82-a8e0-9311651d89e1) +Use the reviewed public-key-only [SSH / SFTP service](/docs/network/ssh) for +remote file access. BloomOS still detects and stops FileBrowser remnants on +older cards. -The built-in HTTP file server will allow you to manage your files through a web browser on your phone, a PC or a tablet. Think of it as a website, hosted by your Miyoo Mini+. - - -## Features - -*![](https://github.com/OnionUI/Onion/assets/47260768/04c1fcd7-94ee-440d-9fdc-ea281de44ee1)* - -- Download anything, anywhere. - -- Upload anything, anywhere. - -- Built in text editor. - -- Built in terminal. - -- Authentication (or none!) - -- User creation - - -## Enabling HTTP file server - -You'll find it in **Apps** › **Tweaks** › **Network** › **HTTP: Web-based file sync** and you'll have 2 options: -1. **Enable** - Activate the file server -2. **Enable authentication** - Activate authentication (username/password) - -![](https://github.com/OnionUI/Onion/assets/47260768/4a19bd3e-52f7-4681-bd9d-8d0274fe37d3) - - -## Logging in - -Once you've activated your file server in Tweaks (and exited tweaks!) you'll now be able to browse to the IP address of your device. -If you're not sure what the IP address is, you'll find it at the top of the "Network" page within Tweaks. - -![](https://github.com/OnionUI/Onion/assets/47260768/2b8e3d38-7be2-43f5-ab94-d7e506bc02cb) - -Open up your preferred web browser and browse to the IP address! -You'll be met with the below, at which point you can login with the default username of `admin` and password of `admin`. - - -## Disabling authentication - -Although this is not recommended on other peoples Wi-Fi, when you're at home on your own Wi-Fi this is absolutely fine (or any other secure Wi-Fi!) - -Head over to **Tweaks** › **Network** › **HTTP file server** and toggle: - -![](https://github.com/OnionUI/Onion/assets/47260768/5625ca83-7ba4-49ac-8b9e-b11f6abc3c4f) - - -## Changing the default password - -HTTP file browser has built in user management. By default your username will be u:`admin` p:`admin`. It's recommended you change this when you first login by heading over to: - -![](https://github.com/OnionUI/Onion/assets/47260768/78bf6c9a-fadc-4d9d-a769-32f271f072ba) - -And then opening up user management: - -![](https://github.com/OnionUI/Onion/assets/47260768/021dae7e-9a8a-42a4-a470-06229b0a3328) - - -## Security - -:::caution Network security -Although we've taken every precaution to offer as much security as possible, remember to keep your Onion safe. It may not be advisable to use the file server on public/open Wi-Fi! -::: +The earlier Onion 4.2 behavior remains available in the versioned historical +documentation. diff --git a/website/docs/07-apps/03-network-features/04-ftp.md b/website/docs/07-apps/03-network-features/04-ftp.md index ef52e10f5..3b6a62652 100644 --- a/website/docs/07-apps/03-network-features/04-ftp.md +++ b/website/docs/07-apps/03-network-features/04-ftp.md @@ -7,7 +7,7 @@ slug: /network/ftp ![](https://github.com/OnionUI/Onion/assets/47260768/7bfac01d-bfaa-4565-b10b-b2b2a0ea7f9c) -Much like the HTTP server, FTP provides a method of transferring files between your Miyoo Mini+ and other devices such as a PC/Phone/Tablet. You'll need an FTP client installed on the second device. +FTP provides a method of transferring files between your Miyoo Mini+ and other devices such as a PC/Phone/Tablet. You'll need an FTP client installed on the second device. ## Features