如何防止Python代码中的目录遍历攻击

如何防止Python代码中的目录遍历攻击,python,directory-traversal,Python,Directory Traversal,我需要使用Python从我的代码中防止目录遍历攻击。我的代码如下: 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) req

我需要使用Python从我的代码中防止
目录遍历攻击。我的代码如下:

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/'
如上所述,以
/
结尾非常重要,以确保下面的检查与特定目录匹配

您需要验证是否存在最终请求:

if os.path.commonprefix((os.path.realpath(requested_path),safe_dir)) != safe_dir: 
    #Bad user!
如果允许请求的路径是
save_dir
本身,那么如果
os.path.realpath(请求的_path)+'/'==safe_dir
,您还需要允许输入


我鼓励您确保用户可以在一个地方访问所有您想要的内容。

您可以尝试

应该返回从
根目录开始的相对路径
,或者在尝试目录遍历攻击时引发
值错误

测试 WindowsPath(“测试文件”)

WindowsPath('测试文件/嵌套')

WindowsPath('嵌套')


不应允许用户访问或修改sudo目录。所以检查路径是否不是sudo dirI,我也需要防止它。你能做到这一点吗?并不是说它是一个好的解决方案,但是有20个根目录,所以检查路径不包含任何一个,就像用户请求包含bin目录的路径,那么不允许你考虑添加<代码> OS。
如果在安全路径中有一个符号链接指向它的外部,则将其添加到安全路径中。@satya更正。通常最好的做法是确保世界上可读的东西都在同一个地方。好的,让我来实现它并让你知道。如果我只需要对我的projrct文件夹授予权限,我是否可以编写
safe\u dir=os.path.abspath(os.curdir)
。@satya否,因为你可能是从其他地方执行的。如果python文件位于“safe”目录中,请使用
safe\u dir=os.path.realpath(\uu file\uu)
,尽管我通常将内容与代码分开。还要注意,正如zwer所提到的,您应该使用realpath。
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())
param = 'test_file'
Path(root_dir).joinpath(param).relative_to(root_dir)
param = 'test_file/nested'
Path(root_dir).joinpath(param).relative_to(root_dir)
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())