From e66b2eb662a26d5607b68bb595dd041f633c03f8 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Thu, 19 Mar 2026 18:05:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E9=9D=99=E6=80=81=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=A2=9E=E5=BC=BA=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E9=81=8D=E5=8E=86=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytests/webui/test_app.py | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/pytests/webui/test_app.py b/pytests/webui/test_app.py index eb37305e..48bfaaf4 100644 --- a/pytests/webui/test_app.py +++ b/pytests/webui/test_app.py @@ -1,5 +1,7 @@ from unittest.mock import patch +import pytest + from src.webui import app as webui_app @@ -120,3 +122,52 @@ def test_resolve_static_path_uses_dashboard_dist(monkeypatch, tmp_path) -> None: resolved_path = webui_app._resolve_static_path() assert resolved_path == dashboard_dist + + +def test_resolve_safe_static_file_path_allows_regular_static_file(tmp_path) -> None: + static_path = tmp_path / "dist" + asset_path = static_path / "assets" / "app.js" + asset_path.parent.mkdir(parents=True) + asset_path.write_text("console.log('ok')", encoding="utf-8") + + resolved_path = webui_app._resolve_safe_static_file_path(static_path, "assets/app.js") + + assert resolved_path == asset_path.resolve() + + +def test_resolve_safe_static_file_path_rejects_relative_path_traversal(tmp_path) -> None: + static_path = tmp_path / "dist" + static_path.mkdir() + + resolved_path = webui_app._resolve_safe_static_file_path(static_path, "../secret.txt") + + assert resolved_path is None + + +def test_resolve_safe_static_file_path_rejects_absolute_path_traversal(tmp_path) -> None: + static_path = tmp_path / "dist" + static_path.mkdir() + + resolved_path = webui_app._resolve_safe_static_file_path(static_path, "/etc/passwd") + + assert resolved_path is None + + +def test_resolve_safe_static_file_path_rejects_symlink_escape(tmp_path) -> None: + static_path = tmp_path / "dist" + static_path.mkdir() + + outside_dir = tmp_path / "outside" + outside_dir.mkdir() + outside_file = outside_dir / "secret.txt" + outside_file.write_text("secret", encoding="utf-8") + + link_path = static_path / "escape" + try: + link_path.symlink_to(outside_dir, target_is_directory=True) + except OSError as exc: + pytest.skip(f"symlink is not supported in this environment: {exc}") + + resolved_path = webui_app._resolve_safe_static_file_path(static_path, "escape/secret.txt") + + assert resolved_path is None