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