From a7486100713d8bc39d6ef2a301d8507367ab45f5 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 23 Feb 2024 07:38:24 +1300 Subject: [PATCH] Merge pull request from GHSA-8p25-3q46-8q2p --- esphome/dashboard/web_server.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index c16461d174..aca3a7a3a8 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -808,8 +808,16 @@ class EditRequestHandler(BaseHandler): @bind_config async def get(self, configuration: str | None = None) -> None: """Get the content of a file.""" - loop = asyncio.get_running_loop() + if not configuration.endswith((".yaml", ".yml")): + self.send_error(404) + return + filename = settings.rel_path(configuration) + if Path(filename).resolve().parent != settings.absolute_config_dir: + self.send_error(404) + return + + loop = asyncio.get_running_loop() content = await loop.run_in_executor( None, self._read_file, filename, configuration ) @@ -835,14 +843,20 @@ class EditRequestHandler(BaseHandler): @bind_config async def post(self, configuration: str | None = None) -> None: """Write the content of a file.""" + if not configuration.endswith((".yaml", ".yml")): + self.send_error(404) + return + + filename = settings.rel_path(configuration) + if Path(filename).resolve().parent != settings.absolute_config_dir: + self.send_error(404) + return + loop = asyncio.get_running_loop() - config_file = settings.rel_path(configuration) - await loop.run_in_executor( - None, self._write_file, config_file, self.request.body - ) + await loop.run_in_executor(None, self._write_file, filename, self.request.body) # Ensure the StorageJSON is updated as well await async_run_system_command( - [*DASHBOARD_COMMAND, "compile", "--only-generate", config_file] + [*DASHBOARD_COMMAND, "compile", "--only-generate", filename] ) self.set_status(200)