Python 安全使用shutil.rmtree/os.path.join和目录遍历

Python 安全使用shutil.rmtree/os.path.join和目录遍历,python,security,path,escaping,shutil,Python,Security,Path,Escaping,Shutil,我有一个预定义的路径,它与userinput连接以删除特定的目录。当前的代码如下所示,如果用户输入了这样的内容,将会造成非常严重的危害: import os import shutil userinput = '../../' path = os.path.join('/my/self/defined/path', userinput) shutil.rmtree(path) 这显然允许用户删除任何文件或目录。“囚禁”用户的好方法是什么,这样就只能输入/my/self/defined/path

我有一个预定义的路径,它与userinput连接以删除特定的目录。当前的代码如下所示,如果用户输入了这样的内容,将会造成非常严重的危害:

import os
import shutil
userinput = '../../'
path = os.path.join('/my/self/defined/path', userinput)
shutil.rmtree(path)
这显然允许用户删除任何文件或目录。“囚禁”用户的好方法是什么,这样就只能输入
/my/self/defined/path
下面的任何路径,处理
。/
或以
/
和我可能想不到的所有其他恶意输入开始字符串?

怎么样

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'
my=os.path.abspath(“/my/self/defined/path”)
new=os.path.abspath(路径)
如果len(新)

这将阻止删除,例如
/my/self/
,但如果用户输入
。/../some/where/else
,他可能会到达定义路径之外的目录,该路径也可能比原始路径长。当然总比不过滤好,但还是太危险了。那样的话,新的.startswith(我的)测试就会失败。哦,我想知道我怎么会错过阅读第二个条件,对不起。但是长度的检查可以完全省略,不是吗?另外,我想知道是否应该首选
realpath
abspath
。可以取消长度检查。在os.path.normpath()中包装abspath以删除../之类的内容。realpath很好,但是如果它是符号链接的,您还需要在“/my/self/defined/path”上调用它。我会将os.path.realpath(path)
中的
selfdefinedpath替换为
os.path.realpath(path)。startswith(selfdefinedpath)
,否则
/some/where/my/self/defined/path/foo/bar
(虽然不太可能)。否则,解决方案对我来说似乎很可靠,但我会在将其设置为“接受”之前等待一段时间,也许其他人会发现另一个问题。是的,你是wright,很可能有人会提供这样的输入,但如果安全是主要问题,则永远不要冒险。
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)