@@ -168,7 +168,7 @@ def artifacts(self, raw):
168168 tags = ["body:attachment" , "autoImport:true" ] + h ["tag" ],
169169 )
170170 )
171- filepath = os .path .join (self .job_directory , "output" , h .get ("filename" ))
171+ filepath = os .path .join (self .job_directory , "output" , os . path . basename ( h .get ("filename" , "" ) ))
172172 file_key = ("file" , filepath )
173173 if file_key not in seen :
174174 seen .add (file_key )
@@ -193,6 +193,15 @@ def _add_ioc(ioc_list, data, tags):
193193 ioc_list .append ({"data" : data , "tag" : list (tags )})
194194
195195
196+ def _safe_attachment_filename (raw_name ):
197+ if not raw_name or "\x00 " in raw_name :
198+ raise ValueError ("invalid attachment filename" )
199+ base = os .path .basename (raw_name )
200+ if not base or base in ("." , ".." ) or os .path .isabs (base ) or re .match (r"^[A-Za-z]:" , base ):
201+ raise ValueError ("invalid attachment filename" )
202+ return base
203+
204+
196205def parseEml (filepath , job_directory , wkhtmltoimage , sanitized_rendering ):
197206 ep = eml_parser .EmlParser (include_raw_body = True , include_attachment_data = True )
198207 with open (filepath , "rb" ) as f :
@@ -322,16 +331,15 @@ def parseEml(filepath, job_directory, wkhtmltoimage, sanitized_rendering):
322331 for a in decoded_email .get ("attachment" ):
323332 a ["mime" ] = magic .from_buffer (binascii .a2b_base64 (a .get ("raw" )))
324333 if isinstance (a .get ("raw" ), bytes ):
325- path , filename = os . path . split (a .get ("filename" , "" ))
326- if path != "" :
327- os .umask ( 0 )
328- os .makedirs (
329- f" { job_directory } /output/ { path } " , exist_ok = True , mode = 0o777
330- )
331- filepath = os . path . join ( job_directory , "output" , path , filename )
334+ filename = _safe_attachment_filename (a .get ("filename" , "" ))
335+ out_dir = os . path . join ( job_directory , "output" )
336+ filepath = os .path . join ( out_dir , filename )
337+ if not os .path . realpath ( filepath ). startswith (
338+ os . path . realpath ( out_dir ) + os . sep
339+ ):
340+ raise ValueError ( "attachment path escapes sandbox" )
332341 with open (filepath , "wb" ) as f :
333342 f .write (base64 .b64decode (a ["raw" ]))
334- f .close ()
335343 a ["raw" ] = a .get ("raw" ).decode ("ascii" )
336344 result ["attachments" ].append (a )
337345 iocs ["hash" ].append (
0 commit comments