Three foot-guns that turn what looked like a safe binding into an exposed one. Each is silent: nothing alerts you when it happens.
Gotcha 1 — The IPv6 twin
You bound to 127.0.0.1 (IPv4 loopback). You're safe, right? Maybe — but the IPv6 stack has its own loopback (::1) and its own "all interfaces" (::). Some servers default to listening on both stacks. If your IPv6 binding is :: while IPv4 is 127.0.0.1, you have a public IPv6 leak you didn't notice.
Gotcha 2 — UPnP on your router
Universal Plug and Play lets devices on your LAN ask the router to forward inbound ports automatically. It is on by default on most consumer routers. A misbehaving app, a torrent client, or a game can quietly open a public port.
Gotcha 3 — "Bind to 192.168.x.x" lies
Telling your service "bind only to 192.168.1.42" feels safer than 0.0.0.0. It is, but only marginally:
- If you are on public Wi-Fi later with the same DHCP-assigned IP, your service still answers — to whoever else is on that Wi-Fi.
- If your LAN has untrusted devices (guests, IoT, a roommate), they can reach the service.
- If the IP changes (DHCP renewal), your service stops listening and you debug a "broken" app instead.
Gotcha 4 — Reverse proxies that bind 0.0.0.0 for you
You configured your app to bind 127.0.0.1. Then you put nginx / Caddy in front of it. Did you check what nginx binds to? It is 0.0.0.0:80 and 0.0.0.0:443 by default — your app's restricted binding is now bypassed by the proxy in front of it. Reverse proxies need explicit binding too.