2
0
mirror of https://github.com/frappe/bench.git synced 2025-01-10 00:37:51 +00:00

fix: add safety filter for untarring

This commit is contained in:
18alantom 2024-01-23 17:20:16 +05:30
parent 36c3cf4415
commit e8ea98552c
2 changed files with 33 additions and 2 deletions

View File

@ -24,6 +24,7 @@ from bench.exceptions import NotInBenchDirectoryError
from bench.utils import ( from bench.utils import (
UNSET_ARG, UNSET_ARG,
fetch_details_from_tag, fetch_details_from_tag,
get_app_cache_extract_filter,
get_available_folder_name, get_available_folder_name,
get_bench_cache_path, get_bench_cache_path,
is_bench_directory, is_bench_directory,
@ -343,7 +344,11 @@ class App(AppMeta):
click.secho(f"Getting {self.app_name} from cache", fg="yellow") click.secho(f"Getting {self.app_name} from cache", fg="yellow")
with tarfile.open(cache_path, mode) as tar: with tarfile.open(cache_path, mode) as tar:
tar.extractall(app_path.parent) try:
tar.extractall(app_path.parent, filter=get_app_cache_extract_filter())
except:
shutil.rmtree(app_path)
return False
return True return True

View File

@ -9,7 +9,8 @@ from functools import lru_cache
from glob import glob from glob import glob
from pathlib import Path from pathlib import Path
from shlex import split from shlex import split
from typing import List, Optional, Tuple from tarfile import data_filter, AbsoluteLinkError, TarInfo
from typing import Callable, List, Optional, Tuple
# imports - third party imports # imports - third party imports
import click import click
@ -569,3 +570,28 @@ def get_cmd_from_sysargv():
break break
return cmd_from_ctx return cmd_from_ctx
def get_app_cache_extract_filter(
count_threshold: int = 10_000,
size_threshold: int = 1_000_000_000,
) -> Callable[[TarInfo, str], TarInfo | None]:
state = dict(count=0, size=0)
def filter_function(member: TarInfo, dest_path: str) -> Optional[TarInfo]:
state["count"] += 1
state["size"] += member.size
if state["count"] > count_threshold:
raise Exception(f"Number of entries exceeds threshold ({state['count']})")
if state["size"] > size_threshold:
raise Exception(f"Extracted size exceeds threshold ({state['size']})")
try:
return data_filter(member, dest_path)
except AbsoluteLinkError:
# Links created by `frappe` after extraction
return None
return filter_function