Merge pull request #38740 from AarDG10/fix-backup

fix(response): harden download_backup
This commit is contained in:
Aarol D'Souza 2026-04-21 12:11:08 +05:30 committed by GitHub
commit 4358f5bd44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 0 deletions

View file

@ -480,3 +480,16 @@ def find_file_by_url(path: str, name: str | None = None) -> "File" | None:
def get_safe_file_name(file_name: str) -> str:
return re.sub(r"[/\\%?#]", "_", file_name)
def check_path_safety(base_path: str, requested_path: str) -> bool:
"""Util to check path safety by ensuring sandboxing and logging unsuccessful attempts"""
base_path = os.path.realpath(base_path)
requested_path = os.path.realpath(requested_path)
if os.path.commonpath([base_path, requested_path]) != base_path:
frappe.log_error(
title="Attempted Unauthorized File Access",
message=f"Blocked access to: {requested_path}",
)
return False
return True

View file

@ -26,6 +26,7 @@ import frappe.sessions
import frappe.utils
from frappe import _
from frappe.core.doctype.access_log.access_log import make_access_log
from frappe.core.doctype.file.utils import check_path_safety
from frappe.utils import format_timedelta, orjson_dumps
if TYPE_CHECKING:
@ -280,6 +281,13 @@ def download_backup(path):
_("You need to be logged in and have System Manager Role to be able to access backups.")
)
filename = path.split("/backups/", 1)[1]
backup_path = frappe.get_site_path("private", "backups")
requested_path = frappe.get_site_path("private", "backups", filename)
is_safe = check_path_safety(base_path=backup_path, requested_path=requested_path)
if not is_safe:
frappe.throw(_("Invalid backup path"), frappe.PermissionError)
return send_private_file(path)