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

时间:2017-07-19 11:05:59

标签: python directory-traversal

我需要使用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一样运行,这样可以防止目录遍历攻击。

2 个答案:

答案 0 :(得分:5)

假设用户内容全部位于

safe_dir = '/home/saya/server/content'

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

if os.path.commonprefix((os.path.realpath(requested_path),safe_dir)) != safe_dir: 
    #Bad user!

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

答案 1 :(得分:0)

你可以试试pathlib.Path

的方法
Path(root_dir).joinpath(param).resolve().relative_to(root_dir.resolve())

应返回从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里面/嵌套')

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( '嵌套')