永遠(yuǎn)不要在你的 Downloads 下運(yùn)行 Python!!
本文閱讀需要約 4?分鐘
Hi,我是小帥b。
今天給大家分享一個(gè)關(guān)于使用 Python 時(shí)不太會(huì)注意到的安全隱患。
Python 的一大好處在于,你可以很容易的開(kāi)始編寫(xiě)腳本——只需將一些代碼懟到一個(gè) .py 文件中,然后運(yùn)行 python my_file.py。
同樣的,模塊化也很容易上手:將 myfile.py 拆分成 myapp.py 和 mylib.py,然后你可以從 myapp.py 導(dǎo)入 my_lib,并開(kāi)始將你的代碼組織成模塊。
然而,使其起作用的機(jī)制細(xì)節(jié)會(huì)有一些令人驚訝的地方,有時(shí)甚至是非常關(guān)鍵的安全后果:你從不同的位置執(zhí)行代碼越方便,攻擊者執(zhí)行代碼的機(jī)會(huì)也就越多...
Python 需要一個(gè)安全空間來(lái)加載代碼以下是關(guān)于 Python 安全的三個(gè)關(guān)鍵假設(shè):
1,sys.path 里的每個(gè)路徑都是一個(gè)安全的位置,從中執(zhí)行任意代碼是安全的。?
2,"main 腳本" 所在的目錄總是在 sys.path 上?
3,直接運(yùn)行 Python 的時(shí)候,當(dāng)前目錄為安全 main 位置,即使運(yùn)行 Python 時(shí)傳入 -c 或 -m。
如果你正在運(yùn)行一個(gè)在你電腦已經(jīng)正確安裝了的 Python 程序。那么在你的 Python 或者 virtualenv 之外,唯一會(huì)被自動(dòng)添加到 sys.path 位置的是可執(zhí)行 main 文件或腳本的位置。
舉個(gè)例子,如果你的 pip 安裝在 /usr/bin 下,然后你運(yùn)行 pip, 那么只有 /usr/bin 會(huì)被添加到 sys.path。在 /usr/bin 是個(gè)安全的地方,你可以在這里寫(xiě)入文件讓你的系統(tǒng)運(yùn)行一些東西。
然而,有一個(gè)新的慣例是我們更傾向于使用?python -m pip,以避免安裝東西帶來(lái)的錯(cuò)亂問(wèn)題。
假設(shè)你從一個(gè)非 PyPI 的第三方網(wǎng)站下載一個(gè) Python 包到 Downloads 文件夾下,由于你習(xí)慣使用 python -m pip,所以你會(huì)這么去安裝:

這看起來(lái)似乎是一件合理的事,但你不知道的是,兩周前你訪(fǎng)問(wèn)了一個(gè)帶有 XSS Javascript 的網(wǎng)站,在它上面下載了一個(gè)帶有惡意的 pip.py 到你的 Downloads 文件夾中。
Boom!!!!
這是攻擊的演示:

也許你會(huì)說(shuō),我不把當(dāng)前目錄放到環(huán)境變量 $PYTHONPATH 上不就行了?
不見(jiàn)得哦,我們來(lái)模擬一個(gè)易受攻擊的 Python 程序:
首先我們創(chuàng)建兩個(gè)目錄,分別是 installdir 和 attackerdir:

在 install_dir 下寫(xiě)入 tool.py:

接著我們進(jìn)入 attackerdir,把帶有惡意腳本放進(jìn)去,并把名稱(chēng)改為 tool.py 中導(dǎo)入的模塊 optionextra:

最后我們來(lái)運(yùn)行一下 tool.py:

到目前為止,情況都還好。
但這里有一個(gè)常見(jiàn)的錯(cuò)誤,大多數(shù)都推薦像這樣添加 PYTHONPATH :
export PYTHONPATH="/new/useful/stuff:$PYTHONPATH";
這樣的用法會(huì)有缺陷,第一次調(diào)用時(shí),如果 $PYTHONPATH 之前是空的或者沒(méi)有設(shè)置,這時(shí)就會(huì)包含一個(gè)空的字符串,這個(gè)字符串解析為當(dāng)前目錄,讓我們?cè)囋嚕?/p>

Oh no!為了安全,可以把 $PYTHONPATH unset 一下:

設(shè)置 PYTHONPATH 是設(shè)置 Python 環(huán)境的常用操作,不過(guò) virtualenvs 可以更好的滿(mǎn)足這一需求。當(dāng)然如果你習(xí)慣使用 PYTHONPATH,可以這樣操作:
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}newentry1" export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}newentry2"
結(jié)果是這樣的:
$ echo "${PYTHONPATH}" newentry1:newentry2
這樣就可以保證 $PYTHONPATH 的安全。
最后,如果你仍在使用 $PYTHONPATH, 請(qǐng)確保使用絕對(duì)路徑。
在任何地方運(yùn)行 Python ~/Downloads/anything.py,它會(huì)將 Downloads 路徑添加到 sys.path,使用 Jupyter Notebook 也是一樣,運(yùn)行 jupyter notebook ~/Downloads/anything.ipynb 也會(huì)存在安全隱患。
所以在運(yùn)行下載下來(lái)的腳本之前,最好不要在 Downloads 下直接運(yùn)行。
Downloads 文件路徑并不特殊,它只是一個(gè)有可能潛入攻擊者選擇的地方,要注意的是其他地方是否也是如此。
如果你一定要在 Downloads 下運(yùn)行 Python。
請(qǐng)使用:/path/to/venv/bin/pip。
而不是 /path/to/venv/bin/python -m pip。
最好是避免將 ~/Downloads 作為你當(dāng)前的工作目錄,并在啟動(dòng)前將你的腳本移到更適合的位置。
了解 Python 從哪里獲取將要執(zhí)行的代碼是很重要的,給別人執(zhí)行哪怕一行任意 Python 代碼的能力,就等同于你給他們對(duì)你電腦的完全控制權(quán)。
翻自:
https://glyph.twistedmatrix.com/2020/08/never-run-python-in-your-downloads-folder.html
推薦閱讀:
記得將我的公眾號(hào)設(shè)為?星標(biāo),覺(jué)得本文還不錯(cuò)的話(huà)就來(lái)個(gè)三連,謝啦~
我們下回見(jiàn),peace!

