@@ -87,6 +87,30 @@ def _get_az_command():
8787class CustomActionProperties :
8888 """Helper class for all POST commands that return extra properties back to the customer"""
8989
90+ @staticmethod
91+ def is_within_directory (directory , target ):
92+ """
93+ Ensure the target path is within the intended directory
94+ """
95+ abs_directory = os .path .abspath (directory )
96+ abs_target = os .path .abspath (target )
97+ return os .path .commonpath ([abs_directory ]) == os .path .commonpath (
98+ [abs_directory , abs_target ]
99+ )
100+
101+ @staticmethod
102+ def safe_extract (tar , path = "." ):
103+ """
104+ Validates each file's path before extraction to prevent malicious files from escaping the target directory
105+ """
106+ for member in tar .getmembers ():
107+ member_path = os .path .join (path , member .name )
108+ if not CustomActionProperties .is_within_directory (path , member_path ):
109+ raise Exception (
110+ "Attempted Path Traversal in Tar File"
111+ ) # pylint: disable=broad-exception-raised
112+ tar .extractall (path )
113+
90114 # Custom handling of response will display the output head and the result_URL/result_ref
91115 # it will also save files into output directory if provided
92116 @staticmethod
@@ -120,7 +144,7 @@ def _output(parent_cmd, *args, **kwargs): # pylint: disable=unused-argument
120144 try :
121145 with urllib .request .urlopen (result_url ) as result :
122146 with tarfile .open (fileobj = result , mode = "r:gz" ) as tar :
123- tar . extractall ( path = output_directory )
147+ CustomActionProperties . safe_extract ( tar , output_directory )
124148 logger .warning (
125149 "Extracted results are available in directory: %s" ,
126150 output_directory ,
@@ -190,7 +214,7 @@ def _output(parent_cmd, *args, **kwargs): # pylint: disable=unused-argument
190214 try :
191215 # Extract the downloaded blob
192216 with tarfile .open (downloaded_blob_name , mode = "r:gz" ) as tar :
193- tar . extractall ( path = output_directory )
217+ CustomActionProperties . safe_extract ( tar , output_directory )
194218 logger .warning (
195219 "Extracted results are available in directory: %s" ,
196220 output_directory ,
0 commit comments