From 7ea3054fd807c1b689b7b1506572f33042976425 Mon Sep 17 00:00:00 2001 From: Sebastion Date: Sat, 25 Apr 2026 09:57:55 +0100 Subject: [PATCH 1/2] fix: bind gRPC trace listener to 127.0.0.1 instead of 0.0.0.0 The OTLP/gRPC trace listener was binding to 0.0.0.0 by default, exposing the unauthenticated trace service to the network. This allows any host on the same network to inject fake spans or exfiltrate collected trace data (which may contain sensitive attributes like API keys and HTTP headers). Bind to 127.0.0.1 (localhost) by default so the trace listener is only accessible from the local machine. CWE-287 --- cli/planoai/main.py | 2 +- cli/planoai/trace_cmd.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/planoai/main.py b/cli/planoai/main.py index ea43a1a8a..dfbaf696a 100644 --- a/cli/planoai/main.py +++ b/cli/planoai/main.py @@ -499,7 +499,7 @@ def up( grpc_port=tracing_port ) console.print( - f"[green]✓[/green] Trace collector listening on [cyan]0.0.0.0:{tracing_port}[/cyan]" + f"[green]✓[/green] Trace collector listening on [cyan]127.0.0.1:{tracing_port}[/cyan]" ) except Exception as e: console.print( diff --git a/cli/planoai/trace_cmd.py b/cli/planoai/trace_cmd.py index 425384341..8c79390cf 100644 --- a/cli/planoai/trace_cmd.py +++ b/cli/planoai/trace_cmd.py @@ -599,7 +599,7 @@ def _start_trace_listener(host: str, grpc_port: int) -> None: def start_trace_listener_background( - host: str = "0.0.0.0", grpc_port: int = DEFAULT_GRPC_PORT + host: str = "127.0.0.1", grpc_port: int = DEFAULT_GRPC_PORT ) -> grpc.Server: """Start the trace server in-process and return ``grpc.Server`` handle.""" return _start_trace_server(host, grpc_port) @@ -1117,7 +1117,7 @@ def trace( ) if target == "listen" and not has_show_options: - _start_trace_listener("0.0.0.0", DEFAULT_GRPC_PORT) + _start_trace_listener("127.0.0.1", DEFAULT_GRPC_PORT) return if target in ("stop", "down") and not has_show_options: From ee48227e2786f2568994ebf3be74db4b3fef6338 Mon Sep 17 00:00:00 2001 From: Sebastion Date: Mon, 11 May 2026 14:17:24 +0100 Subject: [PATCH 2/2] test: update trace listen default-host assertion to 127.0.0.1 --- cli/test/test_trace_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/test/test_trace_cmd.py b/cli/test/test_trace_cmd.py index fdcf8c3c6..62d432d40 100644 --- a/cli/test/test_trace_cmd.py +++ b/cli/test/test_trace_cmd.py @@ -104,7 +104,7 @@ def fake_start(host: str, port: int) -> None: result = runner.invoke(trace, ["listen"]) assert result.exit_code == 0, result.output - assert seen == {"host": "0.0.0.0", "port": trace_cmd.DEFAULT_GRPC_PORT} + assert seen == {"host": "127.0.0.1", "port": trace_cmd.DEFAULT_GRPC_PORT} def test_trace_down_prints_success_when_listener_stopped(runner, monkeypatch):