[dashboard] Use resolve/relative_to for download path validation

Replace string-based path sanitization (.replace/.lstrip) with
Path.resolve() and relative_to() validation, matching the
pattern used by other dashboard endpoints (e.g. settings.rel_path).

The previous approach was not exploitable but was inconsistent
with the rest of the codebase.
This commit is contained in:
J. Nick Koston
2026-02-08 06:48:38 -06:00
parent 7b40e8afcb
commit a40c87eeed
+7 -2
View File
@@ -1057,14 +1057,19 @@ class DownloadBinaryRequestHandler(BaseHandler):
if file_name is None:
self.send_error(400)
return
file_name = file_name.replace("..", "").lstrip("/")
# get requested download name, or build it based on filename
download_name = self.get_argument(
"download",
f"{storage_json.name}-{file_name}",
)
path = storage_json.firmware_bin_path.parent.joinpath(file_name)
base_dir = storage_json.firmware_bin_path.parent.resolve()
path = base_dir.joinpath(file_name).resolve()
try:
path.relative_to(base_dir)
except ValueError:
self.send_error(403)
return
if not path.is_file():
args = ["esphome", "idedata", settings.rel_path(configuration)]