如何防止来自Python代码的目录遍历攻击
How to prevent directory traversal attack from Python code
我需要使用 Python 阻止 directory traversal attack
从我的代码中获取。我的代码如下:
if request.GET.get('param') is not None and request.GET.get('param') != '':
param = request.GET.get('param')
startdir = os.path.abspath(os.curdir)
requested_path = os.path.relpath(param, startdir)
requested_path = os.path.abspath(requested_path)
print(requested_path)
tfile = open(requested_path, 'rb')
return HttpResponse(content=tfile, content_type="text/plain")
这里我需要用户是运行喜欢http://127.0.0.1:8000/createfile/?param=../../../../../../../../etc/passwd
这样它应该可以防止目录遍历攻击。
假设用户内容全部位于
safe_dir = '/home/saya/server/content/'
以 /
结尾很重要,因为 heinrichj 提到要确保下面的检查与特定目录匹配。
您需要验证最终请求是否在其中:
if os.path.commonprefix((os.path.realpath(requested_path),safe_dir)) != safe_dir:
#Bad user!
如果允许请求的路径是 save_dir
本身,如果 os.path.realpath(requested_path)+'/' == safe_dir
.
,您还需要允许进入
我鼓励您确保用户可以在一个地方访问您想要的所有内容。
你可以试试pathlib.Path
的方法
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
应该return从root_dir
开始的相对路径,或者如果试图进行目录遍历攻击则引发ValueError
测试
param = 'test_file'
Path(root_dir).joinpath(param).relative_to(root_dir)
WindowsPath('test_file')
param = 'test_file/nested'
Path(root_dir).joinpath(param).relative_to(root_dir)
WindowsPath('test_file/nested')
param = 'non_existing/../../data'
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-26-a74379fe1817> in <module>()
....
ValueError: 'C:\python_scripts\PyCharmProjects\data' does not start with 'C:\python_scripts\PyCharmProjects\testproject'
param = 'non_existing/../nested'
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
WindowsPath('nested')
我需要使用 Python 阻止 directory traversal attack
从我的代码中获取。我的代码如下:
if request.GET.get('param') is not None and request.GET.get('param') != '':
param = request.GET.get('param')
startdir = os.path.abspath(os.curdir)
requested_path = os.path.relpath(param, startdir)
requested_path = os.path.abspath(requested_path)
print(requested_path)
tfile = open(requested_path, 'rb')
return HttpResponse(content=tfile, content_type="text/plain")
这里我需要用户是运行喜欢http://127.0.0.1:8000/createfile/?param=../../../../../../../../etc/passwd
这样它应该可以防止目录遍历攻击。
假设用户内容全部位于
safe_dir = '/home/saya/server/content/'
以 /
结尾很重要,因为 heinrichj 提到要确保下面的检查与特定目录匹配。
您需要验证最终请求是否在其中:
if os.path.commonprefix((os.path.realpath(requested_path),safe_dir)) != safe_dir:
#Bad user!
如果允许请求的路径是 save_dir
本身,如果 os.path.realpath(requested_path)+'/' == safe_dir
.
我鼓励您确保用户可以在一个地方访问您想要的所有内容。
你可以试试pathlib.Path
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
应该return从root_dir
开始的相对路径,或者如果试图进行目录遍历攻击则引发ValueError
测试
param = 'test_file'
Path(root_dir).joinpath(param).relative_to(root_dir)
WindowsPath('test_file')
param = 'test_file/nested'
Path(root_dir).joinpath(param).relative_to(root_dir)
WindowsPath('test_file/nested')
param = 'non_existing/../../data'
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-26-a74379fe1817> in <module>() .... ValueError: 'C:\python_scripts\PyCharmProjects\data' does not start with 'C:\python_scripts\PyCharmProjects\testproject'
param = 'non_existing/../nested'
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
WindowsPath('nested')