【问题标题】:Secure use of shutil.rmtree / os.path.join and Directory Traversal安全使用 shutil.rmtree / os.path.join 和目录遍历
【发布时间】:2013-08-21 12:55:09
【问题描述】:

我有一个预定义的路径,它与用户输入连接以删除特定目录。当前的代码看起来像这样,并且给定这样的用户输入会造成非常严重的伤害:

import os
import shutil
userinput = '../../'
path = os.path.join('/my/self/defined/path', userinput)
shutil.rmtree(path)

这显然允许用户删除任何文件或目录。什么是“监禁”用户的好方法,所以只能输入/my/self/defined/path 下面的任何路径,注意../ 或以/ 开头的字符串以及我可能不认为的所有其他恶意输入的?

【问题讨论】:

    标签: python security path escaping shutil


    【解决方案1】:

    怎么样

    my = os.path.abspath('/my/self/defined/path')
    new = os.path.abspath(path)
    if len(new) < len(my) or not new.startswith(my):
       print 'bzzzt'
    

    http://docs.python.org/2/library/os.path.html

    【讨论】:

    • 这将阻止删除例如/my/self/,但如果用户输入../../some/where/else,他可能会到达定义路径之外的目录,该目录也可能比原始路径长。当然比不过滤要好,但还是太危险了。
    • 在这种情况下,它会触发 new.startswith(my) 测试。
    • 哦,我想知道我怎么会错过阅读第二个条件,对不起。但是长度检查可以完全省略,不是吗?另外,我想知道是否应该首选realpathabspath
    • 可以省去长度检查。
    • 在 os.path.normpath() 中包装 abspath 以删除 ../. realpath 很好,但你也想在 '/my/self/defined/path' 上调用它,以防它的符号链接。
    【解决方案2】:
    import os
    import shutil
    import sys
    userinput = '../../'
    selfdefinedpath = '/my/self/defined/path'
    path = os.path.join(selfdefinedpath, userinput)
    if not selfdefinedpath in os.path.realpath(path):
      print 'not proper path %s' % path
      sys.exit()
    shutil.rmtree(path)
    

    【讨论】:

    • 我会将selfdefinedpath in os.path.realpath(path) 替换为os.path.realpath(path).startswith(selfdefinedpath),否则/some/where/my/self/defined/path/foo/bar 可能会被删除(尽管不太可能)。否则,该解决方案对我来说似乎很可靠,但我会在将其设置为接受之前稍等片刻,也许其他人会发现另一个问题。
    • 是的,您是对的,有人提供此类输入的可能性极小,但如果安全是主要问题,请不要特别冒险。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多