Summary
src/tcp_tunnel_tools.ts exposes createTunnel() as a localhost helper, but it actually calls server.listen(0) with no host and returns the resulting unspecified bind address.
Repro
- Call
createTunnel('http://user:pass@proxy.example.com:8000', 'service.example.com:356').
- Check the implementation in
src/tcp_tunnel_tools.ts:
- the documented
hostname / port options are not present in the function signature
server.listen(0) is called without a host
getAddress() returns the bound address verbatim
- On current Node, an omitted host binds the listener to the unspecified address (
:: / 0.0.0.0), not to loopback.
Expected
createTunnel() should default to a loopback-only listener, consistent with the README's hostname: localhost contract and the localhost:56836 example.
Actual
The helper creates a listener on an unspecified address and returns that externally reachable endpoint.
Likely Cause
src/tcp_tunnel_tools.ts, createTunnel() and getAddress()
Source / Trigger
The caller controls proxyUrl and targetHost, then createTunnel() opens a local relay that forwards every incoming TCP connection through the configured upstream proxy to that target.
Control Gap
The code never supplies a loopback host to server.listen(...), and the documented hostname / port options from README.md are no longer implemented in the exported API.
Impact
This turns a helper that looks localhost-scoped into an all-interfaces tunnel. If the caller points it at an internal target or at an authenticated upstream proxy, any peer that can reach the caller's machine can reuse that relay and reach the tunneled destination unexpectedly.
Fix Direction
Bind createTunnel() to loopback by default (127.0.0.1 / ::1 or localhost), restore or implement the documented hostname / port options, and add a regression test that fails if the returned tunnel endpoint is not loopback-scoped by default.
Summary
src/tcp_tunnel_tools.tsexposescreateTunnel()as a localhost helper, but it actually callsserver.listen(0)with no host and returns the resulting unspecified bind address.Repro
createTunnel('http://user:pass@proxy.example.com:8000', 'service.example.com:356').src/tcp_tunnel_tools.ts:hostname/portoptions are not present in the function signatureserver.listen(0)is called without a hostgetAddress()returns the bound address verbatim::/0.0.0.0), not to loopback.Expected
createTunnel()should default to a loopback-only listener, consistent with the README'shostname: localhostcontract and thelocalhost:56836example.Actual
The helper creates a listener on an unspecified address and returns that externally reachable endpoint.
Likely Cause
src/tcp_tunnel_tools.ts,createTunnel()andgetAddress()Source / Trigger
The caller controls
proxyUrlandtargetHost, thencreateTunnel()opens a local relay that forwards every incoming TCP connection through the configured upstream proxy to that target.Control Gap
The code never supplies a loopback host to
server.listen(...), and the documentedhostname/portoptions fromREADME.mdare no longer implemented in the exported API.Impact
This turns a helper that looks localhost-scoped into an all-interfaces tunnel. If the caller points it at an internal target or at an authenticated upstream proxy, any peer that can reach the caller's machine can reuse that relay and reach the tunneled destination unexpectedly.
Fix Direction
Bind
createTunnel()to loopback by default (127.0.0.1/::1orlocalhost), restore or implement the documentedhostname/portoptions, and add a regression test that fails if the returned tunnel endpoint is not loopback-scoped by default.