Skip to content

fix(security): bind fleetcrown to localhost only, not every interface - #437

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/bind-localhost-only
Aug 29, 2026
Merged

fix(security): bind fleetcrown to localhost only, not every interface#437
github-actions[bot] merged 1 commit into
mainfrom
fix/bind-localhost-only

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

Summary

launch.sh's own comment claimed unset HOSTNAME makes the standalone server "reachable at 127.0.0.1 / localhost" — verified against the actual build artifact (.next/standalone/server.js: const hostname = process.env.HOSTNAME || '0.0.0.0') that it does the opposite: unsetting falls back to Next's own default, 0.0.0.0 (every interface).

Found while auditing why two unrelated services 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 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.

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 convention. Fixed to match.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01Y9rKLxddothnXEtY6KDziN

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y9rKLxddothnXEtY6KDziN
@github-actions
github-actions Bot merged commit a78e8da into main Aug 29, 2026
3 checks passed
@github-actions
github-actions Bot deleted the fix/bind-localhost-only branch August 29, 2026 05:18
github-actions Bot pushed a commit to bitbaum/orangecat that referenced this pull request Aug 29, 2026
…830)

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.


Claude-Session: https://claude.ai/code/session_01Y9rKLxddothnXEtY6KDziN

Co-authored-by: Georgy Butaev <41178744+g-but@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant