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
4 changes: 4 additions & 0 deletions src/networkcloud/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

4.0.0b2
++++++++
* Fixing zip/slip vulnerability in our custom_operations code.

4.0.0b1
++++++++
* This beta version supports NetworkCloud 2025-07-01-preview APIs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@ def _get_az_command():
class CustomActionProperties:
"""Helper class for all POST commands that return extra properties back to the customer"""

@staticmethod
def is_within_directory(directory, target):
"""
Ensure the target path is within the intended directory
"""
abs_directory = os.path.abspath(directory)
abs_target = os.path.abspath(target)
return os.path.commonpath([abs_directory]) == os.path.commonpath(
[abs_directory, abs_target]
)

@staticmethod
def safe_extract(tar, path="."):
"""
Validates each file's path before extraction to prevent malicious files from escaping the target directory
"""
for member in tar.getmembers():
member_path = os.path.join(path, member.name)
if not CustomActionProperties.is_within_directory(path, member_path):
raise ValueError(
f"Path traversal detected: {member_path} is outside target directory {path}"
)
tar.extractall(path)

# Custom handling of response will display the output head and the result_URL/result_ref
# it will also save files into output directory if provided
@staticmethod
Expand Down Expand Up @@ -120,7 +144,7 @@ def _output(parent_cmd, *args, **kwargs): # pylint: disable=unused-argument
try:
with urllib.request.urlopen(result_url) as result:
with tarfile.open(fileobj=result, mode="r:gz") as tar:
tar.extractall(path=output_directory)
CustomActionProperties.safe_extract(tar, output_directory)
logger.warning(
"Extracted results are available in directory: %s",
output_directory,
Expand Down Expand Up @@ -190,7 +214,7 @@ def _output(parent_cmd, *args, **kwargs): # pylint: disable=unused-argument
try:
# Extract the downloaded blob
with tarfile.open(downloaded_blob_name, mode="r:gz") as tar:
tar.extractall(path=output_directory)
CustomActionProperties.safe_extract(tar, output_directory)
logger.warning(
"Extracted results are available in directory: %s",
output_directory,
Expand Down
2 changes: 1 addition & 1 deletion src/networkcloud/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


# HISTORY.rst entry.
VERSION = '4.0.0b1'
VERSION = '4.0.0b2'

# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand Down
Loading