From af9270a9a47fc3136c1e9b725124fd101fea9d23 Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Sat, 29 Aug 2026 06:54:23 +0200 Subject: [PATCH] fix(security): bind fleetcrown to localhost only, not every interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit launch.sh's own comment claimed `unset HOSTNAME` makes the standalone Next server "reachable at 127.0.0.1 / localhost" — it does the opposite. Next's standalone server reads HOSTNAME as the bind address; unsetting it does not default to localhost, it falls back to Next's own default of 0.0.0.0 (every interface). Found 2026-08-29 while auditing why two unrelated services (revampit, aoz-demo) were listening on all interfaces — fleetcrown itself turned out to be one too. Not an active incident: ufw's default-deny only allows 22/80/443, so port 4002 was never actually internet-reachable. But relying on the firewall to cover a bind-address mistake is exactly the kind of thing that breaks quietly the day the firewall config changes for an unrelated reason. Every other app in the fleet already gets this right — sync-infra.sh sets `HOSTNAME=127.0.0.1` for every site it provisions. fleetcrown launches itself outside that shared script and never picked up the same convention. Fixed to match: export HOSTNAME=127.0.0.1 instead of unsetting it. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Y9rKLxddothnXEtY6KDziN --- scripts/fleetcrown-app.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/fleetcrown-app.sh b/scripts/fleetcrown-app.sh index c9166e32..cb36a1fc 100755 --- a/scripts/fleetcrown-app.sh +++ b/scripts/fleetcrown-app.sh @@ -28,9 +28,16 @@ fi # Defaults for production server — override in .env.local if needed. export PORT="${PORT:-3000}" -# HOSTNAME is a bash builtin (set to machine name) — unset it so the standalone -# server defaults to 0.0.0.0 and is reachable at 127.0.0.1 / localhost. -unset HOSTNAME +# HOSTNAME is a bash builtin (set to the machine name, e.g. "bitbaum") and +# Next's standalone server reads it as the bind address. `unset` does NOT +# make that default to localhost — it makes Next fall back to ITS OWN +# default, which is 0.0.0.0 (every interface). Found 2026-08-29: this left +# fleetcrown reachable on all interfaces (mitigated only by ufw's +# default-deny, which happened to block the port anyway — not something to +# rely on). Every other app in the fleet already does this correctly via +# sync-infra.sh's `HOSTNAME=127.0.0.1`; fleetcrown just never matched its +# own convention because it launches itself outside that shared script. +export HOSTNAME=127.0.0.1 # NEXTAUTH_URL must match the local URL so auth callbacks work. export NEXTAUTH_URL="${NEXTAUTH_URL:-http://localhost:${PORT}}" export NEXTAUTH_SECRET="${NEXTAUTH_SECRET:-${AUTH_SECRET:-}}"