Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7436,7 +7436,27 @@ def accessibility_test(data_set):



reports_dir = "Accessibility Test Report"
# Get zeuz_download_folder for saving reports (will be uploaded to server)
try:
if sr.Test_Shared_Variables("zeuz_download_folder"):
zeuz_download_folder = sr.Get_Shared_Variables("zeuz_download_folder")
reports_dir = str(Path(zeuz_download_folder))
CommonUtil.ExecLog(sModuleInfo, f"Saving accessibility reports to zeuz_download_folder: {reports_dir}", 1)
else:
CommonUtil.ExecLog(
sModuleInfo,
"zeuz_download_folder not found. Using current directory for reports.",
2,
)
reports_dir = "Accessibility Test Report"
except Exception as e:
CommonUtil.ExecLog(
sModuleInfo,
f"Failed to get zeuz_download_folder: {str(e)}. Using current directory.",
2,
)
reports_dir = "Accessibility Test Report"

try:
os.makedirs(reports_dir, exist_ok=True)
CommonUtil.ExecLog(sModuleInfo, f"Reports directory created/verified: {reports_dir}", 1)
Expand All @@ -7458,7 +7478,7 @@ def accessibility_test(data_set):
json_path = os.path.join(reports_dir, json_filename)
with open(json_path, 'w', encoding='utf-8') as f:
json.dump(result, f, indent=2, ensure_ascii=False)
CommonUtil.ExecLog(sModuleInfo, f"Raw JSON report saved successfully to: {json_path}", 1)
CommonUtil.ExecLog(sModuleInfo, f"Raw JSON report saved to zeuz_download_folder: {json_path}", 1)
except Exception as e:
CommonUtil.ExecLog(sModuleInfo, f"Failed to save raw JSON report: {str(e)}", 3)
return "zeuz_failed"
Expand All @@ -7470,7 +7490,7 @@ def accessibility_test(data_set):
summary_path = os.path.join(reports_dir, summary_filename)
with open(summary_path, 'w', encoding='utf-8') as f:
json.dump(summary, f, indent=2, ensure_ascii=False)
CommonUtil.ExecLog(sModuleInfo, f"Summary JSON report saved successfully to: {summary_path}", 1)
CommonUtil.ExecLog(sModuleInfo, f"Summary JSON report saved to zeuz_download_folder: {summary_path}", 1)
except Exception as e:
CommonUtil.ExecLog(sModuleInfo, f"Failed to create summary report: {str(e)}", 3)
return "zeuz_failed"
Expand All @@ -7482,7 +7502,7 @@ def accessibility_test(data_set):
html_path = os.path.join(reports_dir, html_filename)
with open(html_path, 'w', encoding='utf-8') as f:
f.write(html_report)
CommonUtil.ExecLog(sModuleInfo, f"HTML report saved successfully to: {html_path}", 1)
CommonUtil.ExecLog(sModuleInfo, f"HTML report saved to zeuz_download_folder: {html_path}", 1)
except Exception as e:
CommonUtil.ExecLog(sModuleInfo, f"Failed to create HTML report: {str(e)}", 3)
return "zeuz_failed"
Expand All @@ -7494,11 +7514,12 @@ def accessibility_test(data_set):
[V] Tests Passed: {summary['summary']['passes_count']}
[!] Inapplicable: {summary['summary']['inapplicable_count']}
[~] Incomplete: {summary['summary']['incomplete_count']}
Reports generated:
Reports generated and saved to zeuz_download_folder:
- {json_filename} (raw data)
- {summary_filename} (summary)
- {html_filename} (visual report)
Location: {reports_dir}

"""

CommonUtil.ExecLog(sModuleInfo, summary_message, 5)
Expand Down
2 changes: 2 additions & 0 deletions server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from server.mobile import router as mobile_router, start_ui_dump_uploads
from server.mac import router as mac_router
from server.linux import router as linux_router
from server.serve_accessibility_report import router as debug_reports_router
from server.windows import router as windows_router, upload_windows_ui_dump
from server.installers import router as installers_router
import asyncio
Expand Down Expand Up @@ -44,6 +45,7 @@ def main() -> FastAPI:
v1router.include_router(mobile_router)
v1router.include_router(mac_router)
v1router.include_router(linux_router)
v1router.include_router(debug_reports_router)
v1router.include_router(windows_router)
v1router.include_router(installers_router)
app = FastAPI()
Expand Down
84 changes: 84 additions & 0 deletions server/serve_accessibility_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
API endpoint for serving accessibility HTML reports from the node's filesystem.
"""

from pathlib import Path
import re
from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse
from urllib.parse import unquote

router = APIRouter(prefix="/debug/reports", tags=["debug-reports"])
REPORTS_BASE_DIR = Path("reports/accessibility").resolve()
SAFE_REPORT_FILENAME_RE = re.compile(r"^[A-Za-z0-9._-]+\.html$")


@router.get("/accessibility")
def serve_accessibility_report(file_path: str):

try:
# Decode URL-encoded path
print("Serving accessi file")
decoded_path = unquote(file_path).strip()

# Accept only a safe filename (no directory components)
if not decoded_path:
raise HTTPException(
status_code=400,
detail="Invalid report path"
)

# Reject any path separators or dot-directory tokens
if "/" in decoded_path or "\\" in decoded_path or decoded_path in {".", ".."}:
raise HTTPException(
status_code=400,
detail="Invalid report path"
)

# Ensure it is a basename and matches allowed characters + .html extension
if Path(decoded_path).name != decoded_path or not SAFE_REPORT_FILENAME_RE.match(decoded_path):
raise HTTPException(
status_code=400,
detail="Invalid report path"
)

# Resolve path under a fixed reports directory to prevent traversal
html_file = (REPORTS_BASE_DIR / decoded_path).resolve()

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
try:
html_file.relative_to(REPORTS_BASE_DIR)
except ValueError:
raise HTTPException(
status_code=400,
detail="Invalid report path"
)

# Security check: ensure file exists and is a file (not a directory)
if not html_file.exists():
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
raise HTTPException(
status_code=404,
detail=f"Accessibility report file not found: {file_path}"
)

if not html_file.is_file():
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
raise HTTPException(
status_code=400,
detail=f"Path is not a file: {file_path}"
)

# Verify it's an HTML file
if html_file.suffix.lower() != ".html":
raise HTTPException(
status_code=400,
detail=f"File is not an HTML file: {file_path}"
)

return FileResponse(
str(html_file),
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
media_type="text/html",
filename=html_file.name
)

except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to retrieve accessibility report: {str(e)}")
Loading