Is the following code snippet from a Python WSGI app safe from directory traversal? It reads a file name passed as parameter and returns the named file.
file_name = request.path_params["file"]
file = open(file_name, "rb")
mime_type = mimetypes.guess_type(file_name)[0]
start_response(status.OK, [('Content-Type', mime_type)])
return file
I mounted the app under http://localhost:8000/file/{file}
and sent requests with the URLs http://localhost:8000/file/../alarm.gif
and http://localhost:8000/file/%2e%2e%2falarm.gif
. But none of my attempts delivered the (existing) file. So is my code already safe from directory traversal?
New approach
It seems like the following code prevents directory traversal:
file_name = request.path_params["file"]
absolute_path = os.path.join(self.base_directory, file_name)
normalized_path = os.path.normpath(absolute_path)
# security check to prevent directory traversal
if not normalized_path.startswith(self.base_directory):
raise IOError()
file = open(normalized_path, "rb")
mime_type = mimetypes.guess_type(normalized_path)[0]
start_response(status.OK, [('Content-Type', mime_type)])
return file