0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python中的十個(gè)安全陷阱(一)

python爬蟲知識(shí)分享 ? 來(lái)源:python爬蟲知識(shí)分享 ? 作者:python爬蟲知識(shí)分享 ? 2022-03-24 16:42 ? 次閱讀

Python 開(kāi)發(fā)者們?cè)谑褂脴?biāo)準(zhǔn)庫(kù)和通用框架時(shí),都以為自己的程序具有可靠的安全性。然而,在 Python 中,就像在任何其它編程語(yǔ)言中一樣,有一些特性可能會(huì)被開(kāi)發(fā)者們誤解或誤用。通常而言,只有極少的微妙之處或細(xì)節(jié)會(huì)使開(kāi)發(fā)者們疏忽大意,從而在代碼中引入嚴(yán)重的安全漏洞。

在這篇博文中,我們將分享在實(shí)際 Python 項(xiàng)目中遇到的 10 個(gè)安全陷阱。我們選擇了一些在技術(shù)圈中不太為人所知的陷阱。通過(guò)介紹每個(gè)問(wèn)題及其造成的影響,我們希望提高人們對(duì)這些問(wèn)題的感知,并提高大家的安全意識(shí)。如果你正在使用這些特性,請(qǐng)一定要排查你的 Python 代碼!

1.被優(yōu)化掉的斷言

Python 支持以優(yōu)化的方式執(zhí)行代碼。這使代碼運(yùn)行得更快,內(nèi)存用得更少。當(dāng)程序被大規(guī)模使用,或者可用的資源很少時(shí),這種方法尤其有效。一些預(yù)打包的 Python 程序提供了優(yōu)化的字節(jié)碼。

然而,當(dāng)代碼被優(yōu)化時(shí),所有的 assert 語(yǔ)句都會(huì)被忽略。開(kāi)發(fā)者有時(shí)會(huì)使用它們來(lái)判斷代碼中的某些條件。例如,如果使用斷言來(lái)作身份驗(yàn)證檢查,則可能導(dǎo)致安全繞過(guò)。

defsuperuser_action(request,user):
assertuser.is_super_user
#executeactionassuperuser

在這個(gè)例子中,第 2 行中的 assert 語(yǔ)句將被忽略,導(dǎo)致非超級(jí)用戶也可以運(yùn)行到下一行代碼。不推薦使用 assert 語(yǔ)句進(jìn)行安全相關(guān)的檢查,但我們確實(shí)在實(shí)際的項(xiàng)目中看到過(guò)它們。

2. MakeDirs 權(quán)限

os.makdirs 函數(shù)可以在操作系統(tǒng)中創(chuàng)建一個(gè)或多個(gè)文件夾。它的第二個(gè)參數(shù) mode 用于指定創(chuàng)建的文件夾的默認(rèn)權(quán)限。在下面代碼的第 2 行中,文件夾 A/B/C 是用 rwx------ (0o700) 權(quán)限創(chuàng)建的。這意味著只有當(dāng)前用戶(所有者)擁有這些文件夾的讀、寫和執(zhí)行權(quán)限。

definit_directories(request):
os.makedirs("A/B/C",mode=0o700)
returnHttpResponse("Done!")

在 Python < 3.6 版本中,創(chuàng)建出的文件夾 A、B 和 C 的權(quán)限都是 700。但是,在 Python > 3.6 版本中,只有最后一個(gè)文件夾 C 的權(quán)限為 700,其它文件夾 A 和 B 的權(quán)限為默認(rèn)的 755。

因此,在 Python > 3.6 中,os.makdirs 函數(shù)等價(jià)于 Linux 的這條命令:mkdir -m 700 -p A/B/C。有些開(kāi)發(fā)者沒(méi)有意識(shí)到版本之間的差異,這已經(jīng)在 Django 中造成了一個(gè)權(quán)限越級(jí)漏洞(cve - 2022 -24583),無(wú)獨(dú)有偶,這在 WordPress 中也造成了一個(gè)加固繞過(guò)問(wèn)題。

3.絕對(duì)路徑拼接

os.path.join(path, *paths) 函數(shù)用于將多個(gè)文件路徑連接成一個(gè)組合的路徑。第一個(gè)參數(shù)通常包含了基礎(chǔ)路徑,而之后的每個(gè)參數(shù)都被當(dāng)做組件拼接到基礎(chǔ)路徑后。

然而,這個(gè)函數(shù)有一個(gè)少有人知的特性。如果拼接的某個(gè)路徑以 / 開(kāi)頭,那么包括基礎(chǔ)路徑在內(nèi)的所有前綴路徑都將被刪除,該路徑將被視為絕對(duì)路徑。下面的示例揭示了開(kāi)發(fā)者可能遇到的這個(gè)陷阱。

defread_file(request):
filename=request.POST['filename']
file_path=os.path.join("var","lib",filename)
iffile_path.find(".")!=-1:
    returnHttpResponse("Failed!")
withopen(file_path)asf:
    returnHttpResponse(f.read(),content_type='text/plain')

在第 3 行中,我們使用 os.path.join 函數(shù)將用戶輸入的文件名構(gòu)造出目標(biāo)路徑。在第 4 行中,檢查生成的路徑是否包含”.“,防止出現(xiàn)路徑遍歷漏洞。

但是,如果攻擊者傳入的文件名參數(shù)為”/a/b/c.txt“,那么第 3 行得到的變量 file_path 會(huì)是一個(gè)絕對(duì)路徑(/a/b/c.txt)。即 os.path.join 會(huì)忽略掉”var/lib“部分,攻擊者可以不使用“.”字符就讀取到任何文件。盡管 os.path.join 的文檔中描述了這種行為,但這還是導(dǎo)致了許多漏洞(Cuckoo Sandbox Evasion, CVE-2020-35736)。

4. 任意的臨時(shí)文件

tempfile.NamedTemporaryFile 函數(shù)用于創(chuàng)建具有特定名稱的臨時(shí)文件。但是,prefix(前綴)和 suffix(后綴)參數(shù)很容易受到路徑遍歷攻擊(Issue 35278)。如果攻擊者控制了這些參數(shù)之一,他就可以在文件系統(tǒng)中的任意位置創(chuàng)建出一個(gè)臨時(shí)文件。下面的示例揭示了開(kāi)發(fā)者可能遇到的一個(gè)陷阱。

def touch_tmp_file(request):
    id = request.GET['id']
    tmp_file = tempfile.NamedTemporaryFile(prefix=id)
    return HttpResponse(f"tmp file: {tmp_file} created!", content_type='text/plain')

在第 3 行中,用戶輸入的 id 被當(dāng)作臨時(shí)文件的前綴。如果攻擊者傳入的 id 參數(shù)是“/../var/www/test”,則會(huì)創(chuàng)建出這樣的臨時(shí)文件:/var/www/test_zdllj17。粗看起來(lái),這可能是無(wú)害的,但它會(huì)為攻擊者創(chuàng)造出挖掘更復(fù)雜的漏洞的基礎(chǔ)。

5.擴(kuò)展的 Zip Slip

在 Web 應(yīng)用中,通常需要解壓上傳后的壓縮文件。在 Python 中,很多人都知道 TarFile.extractall 與 TarFile.extract 函數(shù)容易受到 Zip Slip 攻擊。攻擊者通過(guò)篡改壓縮包中的文件名,使其包含路徑遍歷(../)字符,從而發(fā)起攻擊。

這就是為什么壓縮文件應(yīng)該始終被視為不受信來(lái)源的原因。zipfile.extractall 與 zipfile.extract 函數(shù)可以對(duì) zip 內(nèi)容進(jìn)行清洗,從而防止這類路徑遍歷漏洞。

但是,這并不意味著在 ZipFile 庫(kù)中不會(huì)出現(xiàn)路徑遍歷漏洞。下面是一段解壓縮文件的代碼。

def extract_html(request):
    filename = request.FILES['filename']
    zf = zipfile.ZipFile(filename.temporary_file_path(), "r")
    for entry in zf.namelist():
        if entry.endswith(".html"):
            file_content = zf.read(entry)
            with open(entry, "wb") as fp:
                fp.write(file_content)
    zf.close()
    return HttpResponse("HTML files extracted!")

第 3 行代碼根據(jù)用戶上傳文件的臨時(shí)路徑,創(chuàng)建出一個(gè) ZipFile 處理器。第 4 - 8 行代碼將所有以“.html”結(jié)尾的壓縮項(xiàng)提取出來(lái)。第 4 行中的 zf.namelist 函數(shù)會(huì)取到 zip 內(nèi)壓縮項(xiàng)的名稱。注意,只有 zipfile.extract 與 zipfile.extractall 函數(shù)會(huì)對(duì)壓縮項(xiàng)進(jìn)行清洗,其它任何函數(shù)都不會(huì)。

在這種情況下,攻擊者可以創(chuàng)建一個(gè)文件名,例如“../../../var/www/html”,內(nèi)容隨意填。該惡意文件的內(nèi)容會(huì)在第 6 行被讀取,并在第 7-8 行寫入被攻擊者控制的路徑。因此,攻擊者可以在整個(gè)服務(wù)器上創(chuàng)建任意的 HTML 文件。

如上所述,壓縮包中的文件應(yīng)該被看作是不受信任的。如果你不使用 zipfile.extractall 或者 zipfile.extract,你就必須對(duì) zip 內(nèi)文件的名稱進(jìn)行“消毒”,例如使用 os.path.basename。否則,它可能導(dǎo)致嚴(yán)重的安全漏洞,就像在 NLTK Downloader (CVE-2019-14751)中發(fā)現(xiàn)的那樣。
審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3789

    瀏覽量

    81134
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4797

    瀏覽量

    68707
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4797

    瀏覽量

    84787
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    一個(gè)月速成python+OpenCV圖像處理

    OpenCV是個(gè)廣受歡迎且極為流行的計(jì)算機(jī)視覺(jué)庫(kù),它因其強(qiáng)大的功能、靈活性和開(kāi)源特性而在開(kāi)發(fā)者和研究者備受青睞。學(xué)習(xí)OpenCV主要就是學(xué)習(xí)里面的計(jì)算機(jī)視覺(jué)算法。要學(xué)習(xí)這些算法的原理,知道它們
    的頭像 發(fā)表于 11-29 18:27 ?158次閱讀
    <b class='flag-5'>一個(gè)</b>月速成<b class='flag-5'>python</b>+OpenCV圖像處理

    Pythondict支持多個(gè)key的方法

    ? 在Python,字典(dict)是種非常強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),它允許我們通過(guò)鍵(key)來(lái)存儲(chǔ)和檢索值(value)。有時(shí)候,我們可能想要根據(jù)多個(gè)鍵來(lái)檢索或操作字典的數(shù)據(jù)。雖然
    的頭像 發(fā)表于 11-29 15:59 ?182次閱讀

    C++新手容易犯的十個(gè)編程錯(cuò)誤

    簡(jiǎn)單的總結(jié)下?C++ 新手容易犯的些編程錯(cuò)誤,給新人們提供個(gè)參考。 1 有些關(guān)鍵字在 cpp 文件多寫了 對(duì)于 C++ 類,
    的頭像 發(fā)表于 11-15 12:42 ?402次閱讀

    Python多線程和多進(jìn)程的區(qū)別

    Python作為種高級(jí)編程語(yǔ)言,提供了多種并發(fā)編程的方式,其中多線程與多進(jìn)程是最常見(jiàn)的兩種方式之。在本文中,我們將探討Python多線
    的頭像 發(fā)表于 10-23 11:48 ?415次閱讀
    <b class='flag-5'>Python</b><b class='flag-5'>中</b>多線程和多進(jìn)程的區(qū)別

    【每天學(xué)點(diǎn)AI】個(gè)例子帶你了解Python裝飾器到底在干嘛!

    進(jìn)行“加料”呢?Python裝飾器提供了個(gè)更為優(yōu)雅的方式來(lái)增強(qiáng)現(xiàn)有函數(shù)的行為,并且不需要修改現(xiàn)有的函數(shù)代碼及調(diào)用方式。接下來(lái)通過(guò)個(gè)案例來(lái)
    的頭像 發(fā)表于 09-20 16:54 ?565次閱讀
    【每天學(xué)點(diǎn)AI】<b class='flag-5'>一</b><b class='flag-5'>個(gè)</b>例子帶你了解<b class='flag-5'>Python</b>裝飾器到底在干嘛!

    Python在AI的應(yīng)用實(shí)例

    Python在人工智能(AI)領(lǐng)域的應(yīng)用極為廣泛且深入,從基礎(chǔ)的數(shù)據(jù)處理、模型訓(xùn)練到高級(jí)的應(yīng)用部署,Python都扮演著至關(guān)重要的角色。以下將詳細(xì)探討Python在AI的幾個(gè)關(guān)鍵應(yīng)用
    的頭像 發(fā)表于 07-19 17:16 ?1145次閱讀

    opencv-python和opencv樣嗎

    樣。OpenCV(Open Source Computer Vision Library)是個(gè)開(kāi)源的計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)軟件庫(kù),它提供了大量的圖像和視頻處理功能。OpenCV-Pytho
    的頭像 發(fā)表于 07-16 10:38 ?1250次閱讀

    如何在Python開(kāi)發(fā)人工智能

    Python開(kāi)發(fā)人工智能(AI)是個(gè)廣泛而深入的主題,它涵蓋了從基礎(chǔ)的數(shù)據(jù)處理到復(fù)雜的機(jī)器學(xué)習(xí)、深度學(xué)習(xí)以及自然語(yǔ)言處理等多個(gè)領(lǐng)域。
    的頭像 發(fā)表于 07-15 15:01 ?2221次閱讀

    python訓(xùn)練出的模型怎么調(diào)用

    Python,訓(xùn)練出的模型可以通過(guò)多種方式進(jìn)行調(diào)用。 1. 模型保存與加載 在Python,訓(xùn)練好的模型需要被保存,以便在其他程序或會(huì)話中使用。以下是
    的頭像 發(fā)表于 07-11 10:15 ?2017次閱讀

    用pycharm進(jìn)行python爬蟲的步驟

    以下是使用PyCharm進(jìn)行Python爬蟲的步驟: 安裝PyCharm和Python 首先,您需要安裝PyCharm和Python。PyCharm是
    的頭像 發(fā)表于 07-11 10:11 ?880次閱讀

    具有十個(gè)解碼輸出的進(jìn)位計(jì)數(shù)器/除法器數(shù)據(jù)表

    電子發(fā)燒友網(wǎng)站提供《具有十個(gè)解碼輸出的進(jìn)位計(jì)數(shù)器/除法器數(shù)據(jù)表.pdf》資料免費(fèi)下載
    發(fā)表于 05-17 10:47 ?0次下載
    具有<b class='flag-5'>十個(gè)</b>解碼輸出的<b class='flag-5'>十</b>進(jìn)位計(jì)數(shù)器/除法器數(shù)據(jù)表

    如何使用linux下gdb來(lái)調(diào)試python程序

    如何使用linux下gdb來(lái)調(diào)試python程序? 在Linux下,可以使用GDB(GNU調(diào)試器)來(lái)調(diào)試Python程序。GDB是個(gè)強(qiáng)大的調(diào)試工具,可以幫助開(kāi)發(fā)者診斷和修復(fù)程序
    的頭像 發(fā)表于 01-31 10:41 ?2654次閱讀

    pythonopen函數(shù)的用法詳解

    pythonopen函數(shù)的用法詳解 Python的open()函數(shù)用于打開(kāi)文件。它接受文件名和模式作為參數(shù),并返回
    的頭像 發(fā)表于 01-30 15:31 ?2155次閱讀

    中國(guó)工業(yè)軟件產(chǎn)業(yè)發(fā)展的十個(gè)誤區(qū)

    對(duì)于工業(yè)軟件,多數(shù)人直忽略了個(gè)核心問(wèn)題:我們真的需要做出大鱷們樣厲害的軟件么?我們經(jīng)常講對(duì)標(biāo),到底應(yīng)該對(duì)什么標(biāo)?現(xiàn)在每天講突破“卡脖子”困局,講國(guó)產(chǎn)替代,于是,就想當(dāng)然地對(duì)標(biāo)國(guó)際
    的頭像 發(fā)表于 01-14 09:29 ?850次閱讀
    中國(guó)工業(yè)軟件產(chǎn)業(yè)發(fā)展的<b class='flag-5'>十個(gè)</b>誤區(qū)

    如何解決Python爬蟲中文亂碼問(wèn)題?Python爬蟲中文亂碼的解決方法

    如何解決Python爬蟲中文亂碼問(wèn)題?Python爬蟲中文亂碼的解決方法 在Python爬蟲過(guò)程,遇到中文亂碼問(wèn)題是常見(jiàn)的情況。亂碼問(wèn)題主要是由于編碼不
    的頭像 發(fā)表于 01-12 15:11 ?2451次閱讀