繁体   English   中英

如何仅与相对路径连接?

[英]How to join with relative paths only?

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

def resolve(url):
    url = url.lstrip('/')
    path = os.path.abspath(os.path.join(os.path.dirname(__file__), url))
    return path 

以下是__file__变量的一些示例输出,即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(standard_location, config_path) ,它就会为你做正确的事情。

看看Flask的safe_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 最后但并非最不重要的是,绝对文件名或相对文件名也是特别禁止的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM