使用os.path.abspath验证不可信文件名的位置安全吗?
我觉得我没有漏掉什么。不过我还是个新手。
def GET(self, filename):
name = urllib.unquote(filename)
full = path.abspath(path.join(STATIC_PATH, filename))
#Make sure request is not tricksy and tries to get out of
#the directory, e.g. filename = "../.ssh/id_rsa". GET OUTTA HERE
assert full[:len(STATIC_PATH)] == STATIC_PATH, "bad path"
return open(full).read()
编辑:我意识到如果文件不存在的话,这样做会返回错误的HTTP错误代码(至少在web.py中是这样)。我会修正这个问题。
3 个回答
0
确保STATIC_PATH
的结尾有一个目录分隔符,或者在full
中紧跟着它的字符是一个目录分隔符。
1
总的来说,处理这类问题真的很麻烦。总是会有一些复杂的路径组合方式,导致程序员意想不到或者没有计划到的情况出现。
一个更好的解决办法通常是确保你的网络服务器是以一个只拥有必要文件访问权限的用户身份运行的。我觉得解决SSH问题的简单方法是不允许这个用户使用SSH登录。如果你真的需要以这个用户身份登录,我建议你先用其他账户登录,然后再用su
命令切换到这个用户。
6
os.path.abspath
本身是相当安全的。不过,如果你在用 python -O
运行代码时,你的 assert
检查会被编译掉,这就带来了一个风险。另外,如果你的 STATIC_PATH
后面没有正确的目录分隔符,你可能会意外地接受一个路径,这个路径恰好以它为前缀。举个例子,如果 STATIC_PATH
是 /foo/bar
,那么你可能错误地接受一个在 /foo/barbie/
下的文件。所以,除非 STATIC_PATH
确实以分隔符结尾,否则你需要做一个更严格的检查,以确保安全性。