From 850be0b7a401ea3808233f48428e01993e8f32ca Mon Sep 17 00:00:00 2001 From: Georgy Butaev <41178744+g-but@users.noreply.github.com> Date: Sat, 29 Aug 2026 07:27:54 +0200 Subject: [PATCH] fix(security): bind orangecat to localhost only, not every interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit launch.sh did `unset HOSTNAME` before starting the standalone server. That does not default to localhost — Next's standalone server reads HOSTNAME as the bind address, and unsetting it falls back to Next's own default, 0.0.0.0 (every interface). Confirmed against the actual bind on the box: orangecat-app was listening on 0.0.0.0:4003, not 127.0.0.1:4003 like every other app in the fleet. Not an active incident — ufw's default-deny only allows 22/80/443, so the port was never actually internet-reachable — but relying on the firewall alone to cover a bind-address mistake is exactly the kind of thing that breaks quietly the day firewall config changes for an unrelated reason. Already applied directly to the running box (this file is vendored TO the box, not FROM it on regular deploys — deploy-selfhost.sh preserves whatever launch.sh is already there rather than overwriting it from the repo, per its own comment). This commit is the repo catching up to what's already live, so the next full box provision starts from the correct file instead of reintroducing the bug. Same fix shipped for fleetcrown (bitbaum/fleetcrown#437) — this repo had the identical bug, independently. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Y9rKLxddothnXEtY6KDziN --- scripts/systemd/launch.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/systemd/launch.sh b/scripts/systemd/launch.sh index 6f72a00d7..4dad817a3 100755 --- a/scripts/systemd/launch.sh +++ b/scripts/systemd/launch.sh @@ -11,6 +11,10 @@ if [ -f "$HERE/.env" ]; then source "$HERE/.env" set +a fi -unset HOSTNAME +# `unset` does NOT bind 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 +# orangecat reachable on all interfaces, mitigated only by ufw's +# default-deny (not something to rely on as the actual boundary). +export HOSTNAME=127.0.0.1 export NODE_ENV="production" exec /usr/bin/node --max-http-header-size=65536 "$HERE/server.js"