本帖最后由 喝酸奶不舔盖 于 2024-7-16 10:53 编辑
今天给大家分享一个关于使用 Python 时不太会注意到的安全隐患。 Python 的一大好处在于,你可以很容易的开始编写脚本——只需将一些代码怼到一个 .py 文件中,然后运行 python my_file.py。 同样的,模块化也很容易上手:将 myfile.py 拆分成 myapp.py 和 mylib.py,然后你可以从 myapp.py 导入 my_lib,并开始将你的代码组织成模块。 然而,使其起作用的机制细节会有一些令人惊讶的地方,有时甚至是非常关键的安全后果:你从不同的位置执行代码越方便,攻击者执行代码的机会也就越多... Python 需要一个安全空间来加载代码以下是关于 Python 安全的三个关键假设: 1,sys.path 里的每个路径都是一个安全的位置,从中执行任意代码是安全的。
2,"main 脚本" 所在的目录总是在 sys.path 上
3,直接运行 Python 的时候,当前目录为安全 main 位置,即使运行 Python 时传入 -c 或 -m。 如果你正在运行一个在你电脑已经正确安装了的 Python 程序。那么在你的 Python 或者 virtualenv 之外,唯一会被自动添加到 sys.path 位置的是可执行 main 文件或脚本的位置。 举个例子,如果你的 pip 安装在 /usr/bin 下,然后你运行 pip, 那么只有 /usr/bin 会被添加到 sys.path。在 /usr/bin 是个安全的地方,你可以在这里写入文件让你的系统运行一些东西。
假设你从一个非 PyPI 的第三方网站下载一个 Python 包到 Downloads 文件夹下,由于你习惯使用 python -m pip,所以你会这么去安装:
这看起来似乎是一件合理的事,但你不知道的是,两周前你访问了一个带有 XSS Javascript 的网站,在它上面下载了一个带有恶意的 pip.py 到你的 Downloads 文件夹中。 Boom!!!! 这是攻击的演示:
也许你会说,我不把当前目录放到环境变量 $PYTHONPATH 上不就行了? 不见得哦,我们来模拟一个易受攻击的 Python 程序: 首先我们创建两个目录,分别是 installdir 和 attackerdir:
在 install_dir 下写入 tool.py:
接着我们进入 attackerdir,把带有恶意脚本放进去,并把名称改为 tool.py 中导入的模块 optionextra:
最后我们来运行一下 tool.py:
到目前为止,情况都还好。 但这里有一个常见的错误,大多数都推荐像这样添加 PYTHONPATH : export PYTHONPATH="/new/useful/stuffPYTHONPATH"; 这样的用法会有缺陷,第一次调用时,如果 $PYTHONPATH 之前是空的或者没有设置,这时就会包含一个空的字符串,这个字符串解析为当前目录,让我们试试:
Oh no!为了安全,可以把 $PYTHONPATH unset 一下:
设置 PYTHONPATH 是设置 Python 环境的常用操作,不过 virtualenvs 可以更好的满足这一需求。当然如果你习惯使用 PYTHONPATH,可以这样操作: export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}newentry1" export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}newentry2" 结果是这样的: $ echo "${PYTHONPATH}" newentry1:newentry2 这样就可以保证 $PYTHONPATH 的安全。
最后,如果你仍在使用 $PYTHONPATH, 请确保使用绝对路径。 在任何地方运行 Python ~/Downloads/anything.py,它会将 Downloads 路径添加到 sys.path,使用 Jupyter Notebook 也是一样,运行 jupyter notebook ~/Downloads/anything.ipynb 也会存在安全隐患。 所以在运行下载下来的脚本之前,最好不要在 Downloads 下直接运行。 Downloads 文件路径并不特殊,它只是一个有可能潜入攻击者选择的地方,要注意的是其他地方是否也是如此。 如果你一定要在 Downloads 下运行 Python。 请使用:/path/to/venv/bin/pip。 而不是 /path/to/venv/bin/python -m pip。 最好是避免将 ~/Downloads 作为你当前的工作目录,并在启动前将你的脚本移到更适合的位置。 了解 Python 从哪里获取将要执行的代码是很重要的,给别人执行哪怕一行任意 Python 代码的能力,就等同于你给他们对你电脑的完全控制权。
文章来自:小帅b |