diff --git a/docs/1.0_TEST_MATRIX.md b/docs/1.0_TEST_MATRIX.md
index 6886fcad..87eae64c 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 b72e57bc..49224a1b 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 ab11096b..7d2f361c 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 344fb852..2c311baf 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 df1a066f..21c4dbd7 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 0dfe268c..13f1c23b 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 0b07ed92..70627561 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 75a84db8..31b45916 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 8654a113..41aab80f 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 2984b48f..94864258 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 d2b88df3..4af3c541 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 8885788c..42cddef7 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.
-
+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
-
-**
-
-- 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)
-
-
-
-
-## 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.
-
-
-
-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:
-
-
-
-
-## 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:
-
-
-
-And then opening up user management:
-
-
-
-
-## 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 ef52e10f..3b6a6265 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

-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