New submission from Thomas: SimpleHTTPServer and http.server allow directory traversal on Windows. To exploit this vulnerability, replace all ".." in URLs with "c:c:c:..".
Example: Run python -m http.server and visit 127.0.0.1:8000/c:c:c:../secret_file_that_should_be_secret_but_is_not.txt There is a warning that those modules are not secure in the module docs, but for some reason they do not appear in the online docs: https://docs.python.org/3/library/http.server.html https://docs.python.org/2/library/simplehttpserver.html It would be nice if that warning was as apparent as for example here: https://docs.python.org/2/library/xml.etree.elementtree.html There are a lot of other URLs that are insecure as well, which can all be traced back to here: https://hg.python.org/cpython/file/tip/Lib/http/server.py#l766 The splitdrive and split functions, which should make sure that the final output is free of ".." are only called once which leads to this control flow: --------------------------------------------------------------- path = "c:/secret/public" word = "c:c:c:.." _, word = os.path.splitdrive(word) # word = "c:c:.." _, word = os.path.split(word) # word = "c:.." path = os.path.join(path, word) # path = "c:/secret/public\\.." --------------------------------------------------------------- Iterating splitdrive and split seems safer: --------------------------------------------------------------- for word in words: # Call split and splitdrive multiple times until # word does not change anymore. has_changed = True while has_changed: previous_word = word _, word = os.path.split(word) _, word = os.path.splitdrive(word) has_changed = word != previous_word --------------------------------------------------------------- There is another weird thing which I am not quite sure about here: https://hg.python.org/cpython/file/tip/Lib/http/server.py#l761 --------------------------------------------------------------- path = posixpath.normpath(path) words = path.split('/') --------------------------------------------------------------- posixpath.normpath does not do anything with backslashes and then the path is split by forward slashes, so it may still contain backslashes. Maybe replacing posixpath.normpath with os.path.normpath and then splitting by os.sep would work, but I don't have enough different operating systems to test this, so someone else should have a look. I have attached some simple fuzzing test that tries a few weird URLs and sees if they lead where they shouldn't. Disclaimer: Might still contain other bugs. ---------- components: Library (Lib) files: fuzz.py messages: 262572 nosy: Thomas priority: normal severity: normal status: open title: Directory traversal with http.server and SimpleHTTPServer on windows type: security versions: Python 3.6 Added file: http://bugs.python.org/file42315/fuzz.py _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue26657> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com