作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
以下来自 Python WSGI 应用程序的代码片段是否可以避免目录遍历?它读取作为参数传递的文件名并返回命名文件。
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
我将应用安装在 http://localhost:8000/file/{file}
下,并使用 URL http://localhost:8000/file/../发送请求alarm.gif
和 http://localhost:8000/file/%2e%2e%2faarm.gif
。但是我的任何尝试都没有交付(现有)文件。那么我的代码是否已经不受目录遍历的影响了?
新方法
下面的代码似乎阻止了目录遍历:
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
最佳答案
您的代码不会阻止目录遍历。您可以使用 os.path 来防止这种情况发生。模块。
>>> import os.path
>>> os.curdir
'.'
>>> startdir = os.path.abspath(os.curdir)
>>> startdir
'/home/jterrace'
startdir
现在是一个绝对路径,您不希望该路径超出该路径。现在假设我们从用户那里得到一个文件名,他们给了我们恶意的 /etc/passwd
。
>>> filename = "/etc/passwd"
>>> requested_path = os.path.relpath(filename, startdir)
>>> requested_path
'../../etc/passwd'
>>> requested_path = os.path.abspath(requested_path)
>>> requested_path
'/etc/passwd'
我们现在已经将它们的路径转换为相对于我们起始路径的绝对路径。由于它不在起始路径中,因此它没有我们起始路径的前缀。
>>> os.path.commonprefix([requested_path, startdir])
'/'
您可以在代码中检查这一点。如果 commonprefix 函数返回一个不以 startdir
开头的路径,则该路径无效,您不应返回内容。
上面可以像这样包装成一个静态方法:
import os
def is_directory_traversal(file_name):
current_directory = os.path.abspath(os.curdir)
requested_path = os.path.relpath(file_name, start=current_directory)
requested_path = os.path.abspath(requested_path)
common_prefix = os.path.commonprefix([requested_path, current_directory])
return common_prefix != current_directory
关于python - 我的代码会阻止目录遍历吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6803505/
我是一名优秀的程序员,十分优秀!