您的代码不会阻止目录遍历。你可以用以下方法来防范这种情况os.path http://docs.python.org/library/os.path.html module.
>>> 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