編寫安全代碼很難。當(dāng)您學(xué)習(xí)一種語言,一種模塊或一種框架時,您將了解應(yīng)該如何使用它。考慮安全性時,您需要考慮如何濫用它。Python也不例外,即使在標(biāo)準(zhǔn)庫中,也記錄了編寫強(qiáng)化應(yīng)用程序的不良做法。但是,當(dāng)我與許多Python開發(fā)人員交談時,他們根本不了解他們。今天本文主要介紹的是Python中的10個常見安全陷阱以及避免方法的信息。
1.輸入注入
注入攻擊非常廣泛并且確實(shí)很常見,并且注入的類型很多。它們影響所有語言,框架和環(huán)境。
SQL注入是直接編寫SQL查詢而不是使用ORM并將字符串文字與變量混合的地方。我讀了很多代碼,其中“轉(zhuǎn)義引號”被認(rèn)為是解決方法。不是,熟悉此備忘單可進(jìn)行SQL注入的所有復(fù)雜方式。
您可以在使用popen,子進(jìn)程,os.system并從變量獲取參數(shù)的任何時候調(diào)用命令注入。調(diào)用本地命令時,有人可能會將這些值設(shè)置為惡意內(nèi)容。
想象一下這個簡單的腳本[credit]。您使用用戶提供的文件名調(diào)用子進(jìn)程:
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!
避免方法:
如果使用的是Web框架隨附的實(shí)用程序,則對輸入內(nèi)容進(jìn)行清理。除非您有充分的理由,否則不要手動構(gòu)造SQL查詢。大多數(shù)ORM具有內(nèi)置的消毒方法。
對于外殼,請使用shlex模塊正確地轉(zhuǎn)義輸入。
2.解析XML
如果您的應(yīng)用程序曾經(jīng)加載并解析XML文件,則很可能您正在使用XML標(biāo)準(zhǔn)庫模塊之一。通過XML有一些常見的攻擊。大多是DoS風(fēng)格的。這些攻擊很常見,尤其是當(dāng)您解析外部XML文件時。
其中之一被稱為“十億個笑聲”,因?yàn)橛行лd荷通常包含很多“笑聲”。基本上,您的想法是可以使用XML進(jìn)行引用實(shí)體,因此,當(dāng)您不使用XML的解析器嘗試將此XML文件加載到內(nèi)存中時,它將占用數(shù)GB的RAM。
另一種攻擊是使用外部實(shí)體擴(kuò)展。XML支持從外部URL引用實(shí)體,XML解析器通常會毫無限制地獲取和加載該資源。“攻擊者可以繞過防火墻并獲得對受限資源的訪問權(quán)限,因?yàn)樗姓埱蠖际菑膬?nèi)部可信賴的IP地址發(fā)出的,而不是從外部發(fā)出的。”
要考慮的另一種情況是您依賴于解碼XML的第三方包,例如配置文件,遠(yuǎn)程API。您甚至可能沒有意識到,您的依賴項(xiàng)之一使自己容易受到這些類型的攻擊。
避免方法:
使用defusedxml替代標(biāo)準(zhǔn)庫模塊。它增加了針對這些類型攻擊的安全防護(hù)。
3.聲明
不要使用assert語句來防止用戶不應(yīng)訪問的代碼段。以這個簡單的例子
def foo(request,user):
斷言user.is_admin,“用戶無權(quán)訪問”
#安全代碼...
現(xiàn)在,默認(rèn)情況下,Python以__debug__true的身份執(zhí)行,但是在生產(chǎn)環(huán)境中,通常會運(yùn)行優(yōu)化。這將跳過assert語句,并直接轉(zhuǎn)到安全代碼,而不管用戶is_admin與否。
避免方法:
僅使用assert語句與其他開發(fā)人員進(jìn)行通信,例如在單元測試中或在防止API使用不正確的情況下。
4.定時攻擊
定時攻擊本質(zhì)上是一種通過定時比較提供的值所花費(fèi)的時間來揭示行為和算法的方法。定時攻擊需要精度,因此它們通常無法在高延遲的遠(yuǎn)程網(wǎng)絡(luò)上工作。由于大多數(shù)Web應(yīng)用程序涉及可變的延遲,因此在HTTP Web服務(wù)器上編寫定時攻擊幾乎是不可能的。
但是,如果您有一個提示輸入密碼的命令行應(yīng)用程序,則攻擊者可以編寫一個簡單的腳本來確定將其值與實(shí)際機(jī)密進(jìn)行比較所花費(fèi)的時間。
避免方法:
使用secrets.compare_digest ,在Python 3.5引入了比較密碼和其他個人價值。
5.污染的站點(diǎn)包或?qū)肼窂?/strong>
Python的導(dǎo)入系統(tǒng)非常靈活。當(dāng)您嘗試為測試編寫猴子補(bǔ)丁或重載核心功能時,這很棒。
但是,這是Python中最大的安全漏洞之一。
無論在虛擬環(huán)境中還是在全局站點(diǎn)程序包(通常不鼓勵使用)中,將第3方程序包安裝到您的站點(diǎn)程序包中都會使您面臨這些程序包中的安全漏洞。
出現(xiàn)了一些與流行的軟件包名稱相似但發(fā)布到PyPi的軟件包,但是會執(zhí)行任意代碼。幸運(yùn)的是,最大的事件沒有害處,只是“指出”該問題并未得到真正解決。
要考慮的另一種情況是您的依存關(guān)系(依此類推)。它們可能包括漏洞,也可能會通過導(dǎo)入系統(tǒng)覆蓋Python中的默認(rèn)行為。
避免方法:
審核您的包裹。查看PyUp.io及其安全服務(wù)。對所有應(yīng)用程序使用虛擬環(huán)境,并確保您的全局站點(diǎn)程序包盡可能干凈。檢查包簽名。
6.臨時文件
要在Python中創(chuàng)建臨時文件,通常需要使用mktemp()函數(shù)生成文件名,然后使用該名稱創(chuàng)建文件。“這是不安全的,因?yàn)樵诘谝粋€進(jìn)程調(diào)用到隨后嘗試創(chuàng)建該文件之間的時間內(nèi),不同的進(jìn)程可能會使用該名稱mktemp()創(chuàng)建文件。” [1]這意味著它可能會欺騙您的應(yīng)用程序以加載錯誤的數(shù)據(jù)或公開其他臨時數(shù)據(jù)。
如果調(diào)用不正確的方法,Python的最新版本將發(fā)出運(yùn)行時警告。
避免方法:
使用該tempfile 模塊,并 mkstemp在需要生成臨時文件時使用。
7.使用yaml.load
引用PyYAML文檔:
警告:yaml.load從不可信來源收到的任何數(shù)據(jù)都無法打電話。yaml.load具有強(qiáng)大的功能pickle.load,因此可以調(diào)用任何Python函數(shù)。”
這個美麗的例子在流行的Python項(xiàng)目Ansible中找到。您可以為Ansible Vault提供此值作為有效YAML。它os.system()使用文件中提供的參數(shù)進(jìn)行調(diào)用。
python/object/apply:os.system ["cat /etc/passwd"]
因此,從用戶提供的值有效加載YAML文件可讓您敞開大門進(jìn)行攻擊。
避免方法:
yaml.safe_load除非您有充分的理由,否則幾乎總是使用。
8.泡菜
反序列化泡菜數(shù)據(jù)與YAML一樣糟糕。Python類可以聲明一個魔術(shù)方法__reduce__,該方法返回一個字符串,或者聲明一個具有可調(diào)用項(xiàng)的元組,以及在腌制時要調(diào)用的參數(shù)。攻擊者可以使用它來包含對子流程模塊之一的引用,以在主機(jī)上運(yùn)行任意命令。
這個奇妙的示例顯示了如何腌制在Python 2中打開外殼程序的類。還有更多有關(guān)如何利用腌制的示例。
導(dǎo)入cPickle
導(dǎo)入子進(jìn)程
導(dǎo)入base64
類RunBinSh(object):
def __reduce __(self):
return(subprocess.Popen ,(('/ bin / sh',),))
打印base64.b64encode(cPickle.dumps(RunBinSh()) )
避免方法:
切勿從不可信或未經(jīng)身份驗(yàn)證的源中獲取數(shù)據(jù)。請改用其他序列化模式,例如JSON。
9.使用系統(tǒng)Python運(yùn)行時而不進(jìn)行修補(bǔ)
大多數(shù)POSIX系統(tǒng)都帶有Python 2版本。通常是一個舊版本。
由于“ Python”即CPython。是用C編寫的,因此Python解釋器本身有時會有漏洞。C語言中的常見安全問題與內(nèi)存分配有關(guān),因此存在緩沖區(qū)溢出錯誤。
多年來,CPython擁有許多溢出或溢出漏洞,每個漏洞都已在后續(xù)發(fā)行版中進(jìn)行了修補(bǔ)和修復(fù)。
所以你很安全。也就是說,如果您修補(bǔ)運(yùn)行時。
這是2.7.13及以下版本的示例,它是一個整數(shù)溢出漏洞,可啟用代碼執(zhí)行。這幾乎是Ubuntu 17之前的任何未修補(bǔ)版本。
避免方法:
為您的生產(chǎn)應(yīng)用程序安裝最新版本的Python,然后對其進(jìn)行修補(bǔ)。
10.不打補(bǔ)丁
與不修補(bǔ)運(yùn)行時類似,您還需要定期修補(bǔ)依賴項(xiàng)。
我發(fā)現(xiàn)在PyPi中“避免方法” Python軟件包版本的做法令人恐懼。這個想法是“ 這些是可行的版本 ”,因此每個人都將其保留。
我上面提到的代碼中的所有漏洞在應(yīng)用程序使用的程序包中都存在時同樣重要。這些軟件包的開發(fā)人員修復(fù)了安全性問題。
避免方法:
使用PyUp.io之類的服務(wù)來檢查更新,向應(yīng)用程序提出拉/合并請求并運(yùn)行測試以使程序包保持最新。
使用InSpec之類的工具可以在生產(chǎn)環(huán)境中驗(yàn)證安裝的版本,并確保修補(bǔ)了最小的版本或版本范圍。
以上就是關(guān)于Python中的10個常見安全陷阱以及避免方法的全部內(nèi)容介紹,想了解更多關(guān)于Python的信息,請繼續(xù)關(guān)注我們。