diff --git a/CHANGELOG.md b/CHANGELOG.md index 2872553c..7230a56f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ Status of the `main` branch. Changes prior to the next official version change w and `workspace/configuration` pulls. Enables Yarn PnP setups with `typescript.tsdk` pointing at the Yarn-generated SDK. -* Dashboard: - - Fix: Host validation required a local host regardless of the listen address (regression introduced in v1.5.2), - preventing remote connections +* Dashboard: + - Make list of trusted hosts configurable, fixing host validation introduced in v1.5.2 allowing only + default local hostnames, effectively preventing remote connections # v1.5.3 (2026-05-26) diff --git a/src/serena/agent.py b/src/serena/agent.py index ce4c1191..9542d37f 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -669,6 +669,7 @@ class SerenaAgent: agent=self, tool_usage_stats=self._tool_usage_stats, host=self.serena_config.web_dashboard_listen_address, + trusted_hosts=self.serena_config.web_dashboard_trusted_hosts, ).run_in_thread() self._dashboard_manager = DashboardManager( port, diff --git a/src/serena/config/serena_config.py b/src/serena/config/serena_config.py index ff63f523..7207a9b1 100644 --- a/src/serena/config/serena_config.py +++ b/src/serena/config/serena_config.py @@ -720,6 +720,7 @@ class SerenaConfig(SharedConfig, ModeSelectionDefinitionWithBaseModes): web_dashboard_open_on_launch: bool = True web_dashboard_interface: str | None = None web_dashboard_listen_address: str = "127.0.0.1" + web_dashboard_trusted_hosts: list[str] = field(default_factory=lambda: ["127.0.0.1", "localhost"]) jetbrains_plugin_server_address: str = "127.0.0.1" tool_timeout: float = DEFAULT_TOOL_TIMEOUT diff --git a/src/serena/dashboard.py b/src/serena/dashboard.py index f7c5c3cc..8b15166b 100644 --- a/src/serena/dashboard.py +++ b/src/serena/dashboard.py @@ -198,15 +198,15 @@ class SerenaDashboardAPI: agent: "SerenaAgent", tool_usage_stats: ToolUsageStats | None = None, host: str = "127.0.0.1", + trusted_hosts: list[str] | None = None, ) -> None: self._memory_log_handler = memory_log_handler self._tool_names = tool_names self._agent = agent self._host = host self._app = Flask(__name__) - local_hosts = ["127.0.0.1", "localhost"] - if self._host in local_hosts: - self._app.config["TRUSTED_HOSTS"] = local_hosts + if trusted_hosts: + self._app.config["TRUSTED_HOSTS"] = trusted_hosts self._tool_usage_stats = tool_usage_stats self._loaded_news: dict[str, str] = {} self._news_ready = threading.Event() diff --git a/src/serena/resources/serena_config.template.yml b/src/serena/resources/serena_config.template.yml index a24ed313..8664fea3 100644 --- a/src/serena/resources/serena_config.template.yml +++ b/src/serena/resources/serena_config.template.yml @@ -67,6 +67,14 @@ web_dashboard_interface: # the address the web dashboard will listen on (bind address). web_dashboard_listen_address: 127.0.0.1 +# trusted hosts used to access the web dashboard. +# By default, only allow access via local addresses for security reasons. +# If you want to allow access from remote machines, add the hostname used to access the dashboard to this list. +# If the list is empty/undefined, all hosts are trusted. +web_dashboard_trusted_hosts: + - 127.0.0.1 + - localhost + # address where JetBrains plugin servers are running (only relevant when using the JetBrains language backend) jetbrains_plugin_server_address: 127.0.0.1