Skip to content

auto-forward: optional non-loopback (0.0.0.0/LAN) bind, opt-in + security review #191

Description

@pofallon

Tracked deferral from up --auto-forward (spec 015-auto-forward-ports, task T057; shipped in #188). v1 binds loopback only; this adds an explicit opt-in to bind a non-loopback address.

Goal / acceptance

An explicit opt-in binds host listeners on 0.0.0.0 (or a chosen interface) so other machines on the LAN can reach the forwarded service directly, with a documented security review.

Hidden issues / gotchas

  • It's a deliberate security downgrade. v1's 127.0.0.1-only bind (crates/core/src/port_forward/registry.rs::try_reserve, hard-coded "127.0.0.1") is what keeps a container's services off the network. Binding 0.0.0.0 exposes them to anyone routable to the host. Must be off by default, opt-in, and loud.
  • Privileged-port story still applies. We always remap <1024 to >=1024 to avoid host root; LAN exposure doesn't change that.
  • Most "remote access" use cases don't need this. Reaching a forwarded port from a laptop is better done over SSH (ssh -L laptop:127.0.0.1:host you@devhost) — SSH resolves the target on the remote host's loopback, so the existing loopback bind already works and stays private. LAN bind is only for direct, un-tunneled access by other hosts (teammate on the same network, a phone testing a mobile build).
  • Event-reporting/contract: host_ip in PORT_EVENT and the registry/contracts/*.schema.json assume 127.0.0.1; a non-loopback bind must thread the real bind address through reporting (the stderr mapping line and PortEvent.host_ip).

Recommended path forward

  1. Add an explicit flag, e.g. --auto-forward-bind <127.0.0.1|0.0.0.0|IP> (default 127.0.0.1), threaded into registry::allocate/try_reserve and the daemon's dial/report paths.
  2. Emit a one-time WARN when binding non-loopback, and document the exposure + the SSH-tunnel alternative in README.md / SECURITY.md (extend the existing "Dynamic port forwarding" section).
  3. Update PORT_EVENT.host_ip + the stderr mapping line + registry schema docs to carry the actual bind address.
  4. Docker integration test: bind 0.0.0.0, assert reachable via a non-loopback host IP; assert default stays loopback-only.

Security

Requires security review per the spec's Out-of-Scope note. Recommend defaulting off and gating behind the explicit flag only (no env-var/implicit enablement).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions