Python 如何仅与相对路径连接?

Python 如何仅与相对路径连接?,python,python-3.x,path,filesystems,webserver,Python,Python 3.x,Path,Filesystems,Webserver,对于一个简单的web服务器脚本,我编写了以下函数来解析文件系统的url def resolve(url): url = url.lstrip('/') path = os.path.abspath(os.path.join(os.path.dirname(__file__), url)) return path 下面是\uuu文件

对于一个简单的web服务器脚本,我编写了以下函数来解析文件系统的url

def resolve(url):
    url = url.lstrip('/')
    path = os.path.abspath(os.path.join(os.path.dirname(__file__), url))
    return path 
下面是
\uuu文件
变量
C:\projects\resolve.py
的一些输出示例

/index.html    => C:\projects\index.html
/\index.html   => C:\index.html
/C:\index.html => C:\index.html
第一个例子很好。url将解析为脚本目录中的文件。然而,我没有想到第二个和第三个例子。由于附加路径被解释为绝对路径,因此它完全忽略脚本文件所在的目录

这是一种安全风险,因为文件系统上的所有文件都可以访问,而不仅仅是脚本子目录中的文件。为什么Python的
os.path.join
允许使用绝对路径进行连接?我如何防止它?

os.path.join()
不适合不安全的输入,不。绝对路径忽略前面的参数是经过深思熟虑的;这允许在配置文件中同时支持绝对路径和相对路径,例如,无需测试输入的路径。只要使用
os.path.join(标准位置,配置路径)
它就会为您做正确的事情

查看如何处理不受信任的文件名:

import posixpath
import os.path

_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep]
                    if sep not in (None, '/'))

def safe_join(directory, filename):
    # docstring omitted for brevity
    filename = posixpath.normpath(filename)
    for sep in _os_alt_seps:
        if sep in filename:
            raise NotFound()
    if os.path.isabs(filename) or \
       filename == '..' or \
       filename.startswith('../'):
        raise NotFound()
    return os.path.join(directory, filename)
这首先使用
posixpath
(平台无关
os.path
模块的POSIX实现)来规范URL路径;这将删除任何嵌入的
。/
/
路径段,使其成为完全标准化的相对或绝对路径

则不包括
/
以外的任何替代分离器;例如,不允许使用
/\index.html
。最后但并非最不重要的一点是,绝对文件名或相对文件名也被明确禁止