Skip to content

Commit

Permalink
Fix z-wave device db download
Browse files Browse the repository at this point in the history
  • Loading branch information
natekspencer committed Nov 22, 2022
1 parent 173c35d commit 6b8396b
Show file tree
Hide file tree
Showing 2 changed files with 626 additions and 400 deletions.
33 changes: 12 additions & 21 deletions script/gen_zjs_device_config_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,23 @@ def _device_config_db_file_exists() -> bool:
def _extract_zjs_config_files() -> None:
"""Extract the Z-Wave JSON config files."""

def _members(tar_file: tarfile.TarFile) -> Generator[tarfile.TarInfo, Any, Any]:
def _members(
tar_file: tarfile.TarFile, path: str = "."
) -> Generator[tarfile.TarInfo, Any, Any]:
def _is_within_directory(target):
abs_directory = os.path.abspath(path)
abs_target = os.path.abspath(target)
prefix = os.path.commonprefix([abs_directory, abs_target])
return prefix == abs_directory

assert (firstmember := tar_file.next())
assert _is_within_directory(os.path.join(path, firstmember.name))
base_path = f"{firstmember.path}{ZJS_TAR_CONFIG_BASE}"
manufacturers_path = f"{base_path}manufacturers.json"
devices_path = f"{base_path}devices/"
base_length = len(base_path)
for member in tar_file.getmembers():
assert _is_within_directory(os.path.join(path, member.name))
if member.path.startswith(manufacturers_path) or (
member.path.startswith(devices_path)
and member.path.endswith(".json")
Expand All @@ -115,26 +125,7 @@ def _members(tar_file: tarfile.TarFile) -> Generator[tarfile.TarInfo, Any, Any]:

logging.debug("Extracting config files from download")
with tarfile.open(ZJS_TAR_FILE) as tar:
def is_within_directory(directory, target):

abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)

prefix = os.path.commonprefix([abs_directory, abs_target])

return prefix == abs_directory

def safe_extract(tar, path=".", members=None, *, numeric_owner=False):

for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not is_within_directory(path, member_path):
raise Exception("Attempted Path Traversal in Tar File")

tar.extractall(path, members, numeric_owner=numeric_owner)


safe_extract(tar, members=_members(tar), path=TMP_DIR)
tar.extractall(TMP_DIR, members=_members(tar, TMP_DIR), numeric_owner=False)


def _load_db_from_file() -> dict[str, str | dict[str, str]]:
Expand Down
Loading

0 comments on commit 6b8396b

Please sign in to comment.