這是個(gè)什么漏洞
最近(2020年2月20日)Apache Tomcat爆出一個(gè)高危的服務(wù)器文件包含漏洞(CVE-2020-1938)埠居,據(jù)國家信息安全漏洞共享平臺(tái)上的漏洞描述來看呀忧,攻擊者可以利用這個(gè)漏洞讀取或包含 Tomcat 上所有 webapp 目錄下的任意文件泻蚊。
這次的漏洞引起了軒然大波,漏洞被定為高位嵬ǎ可能僅僅是因?yàn)闆]有比這更加高的漏洞危害等級(jí)了口予,我仿佛聞到了類似PM2.5爆表的味道。
是任意文件讀取疤槌蕖沪停!
從漏洞描述來看,這個(gè)漏洞允許攻擊者讀取Tomcat上所有webapp目錄下的任意文件裳涛。敲黑板木张,劃重點(diǎn),注意是讀取webapp目錄下的任意文件端三,而你用java開發(fā)的應(yīng)用程序的war包自然是放在webapp目錄下舷礼,當(dāng)然也能夠被攻擊者讀取到。這意味著郊闯,如果你把數(shù)據(jù)用戶名密碼妻献、連接其他后端服務(wù)的賬號(hào)蛛株、JWT簽名secret、OAuth AppSecret等密鑰信息放在properties文件里的話育拨,那么谨履,攻擊者可能現(xiàn)在也拿到了這些信息,并且正在試著入侵你的服務(wù)器至朗。
泄露的不僅僅只是密鑰剧浸,war包其實(shí)就是個(gè)壓縮文件锹引,解壓后不僅能拿到properties文件,還能獲得class文件唆香,因此攻擊者還能逆向獲取到應(yīng)用程序源碼嫌变,進(jìn)而從源代碼中挖掘出更多其他漏洞加以利用。比如某些隱藏API或者參數(shù)躬它、業(yè)務(wù)邏輯漏洞等腾啥,在有源代碼的情況,能夠極大的縮短攻擊者找到這些漏洞的時(shí)間冯吓。對(duì)了倘待,如果你把密鑰硬編碼到源碼里(希望你早就不這么干了),同樣也會(huì)泄露组贺。
還要一種可能很少遇到但影響確實(shí)很大的場景:如果某家公司對(duì)外提供的服務(wù)主要依賴于其投入巨資打造的算法凸舵,這個(gè)算法是公司的核心競爭力,現(xiàn)在有可能因?yàn)檫@個(gè)漏洞而泄露了源代碼失尖,進(jìn)而導(dǎo)致核心算法流失啊奄,那么這造成的損失恐怕已經(jīng)不能用“巨大”這個(gè)詞來形容了。
不硬編碼密鑰掀潮,并且密鑰抽離到配置文件菇夸,這么做還遠(yuǎn)遠(yuǎn)不夠
?因?yàn)檫@個(gè)漏洞而泄露源代碼的情況不是這篇文章要討論的重點(diǎn),我們收回來仪吧,把關(guān)注點(diǎn)放到密鑰泄露上面庄新。
現(xiàn)如今的應(yīng)用程序,尤其是企業(yè)級(jí)應(yīng)用程序通常都會(huì)和其他系統(tǒng)進(jìn)行交互薯鼠,尤其是微服務(wù)的盛行摄咆,后端系統(tǒng)的數(shù)量變得更為龐大。應(yīng)用程序在集成這些內(nèi)部或外部系統(tǒng)的時(shí)候人断,通常都需要賬號(hào)或者密鑰吭从。與此同時(shí),如果應(yīng)用程序涉及加解密恶迈、簽名功能的話涩金,還需要對(duì)應(yīng)的密鑰谱醇。
為方便描述,讓我們把這些賬號(hào)步做、Key副渴、密碼、密鑰等統(tǒng)稱為密鑰全度。不要把密鑰硬編碼到源代碼里煮剧,這是人盡皆知的共識(shí),一方面是擔(dān)心密鑰隨著源碼泄露而泄露将鸵,另一方面也是便于維護(hù)勉盅,輪換密鑰可以更加容易一些。
既然密鑰不硬編碼到源代碼顶掉,那這些密鑰總要有一個(gè)地方存放吧草娜,大多數(shù)時(shí)候密鑰會(huì)被存放在一個(gè)properties文件里,并且和源代碼存放于同一個(gè)代碼倉庫痒筒。當(dāng)然也有團(tuán)隊(duì)把所有密鑰抽離到一個(gè)單獨(dú)properties文件宰闰,并將其存放到一個(gè)單獨(dú)的代碼倉庫,在部署的時(shí)候再讀取出來并且和應(yīng)用程序合并到一起簿透。
以上做法看上去似乎有助于保護(hù)密鑰不泄露移袍,但這次的Apache Tomcat 文件包含漏洞估計(jì)讓不少團(tuán)隊(duì)嚇出一身冷汗:不管你是硬編碼還是費(fèi)盡心思的通過劃分代碼倉庫來管理properties文件,都沒用老充,一旦war包被攻擊者讀取到葡盗,密鑰也就泄露了。 以上做法只能對(duì)防止開發(fā)階段的密鑰泄露有一定的幫助蚂维。
那你說怎么辦戳粒?
為了更好的保護(hù)密鑰不泄露,建議使用專門的密鑰管理服務(wù)虫啥。你可以選擇云服務(wù)提供商的密鑰管理服務(wù)(比如AWS KMS蔚约、Azure KeyVault、騰訊和阿里等國內(nèi)云服務(wù)提供商也有對(duì)應(yīng)的密鑰管理服務(wù))涂籽,也可以自己基于開源軟件搭建(比如HashiCorp Vault)苹祟。限于篇幅原因,我們就不展開講如何具體配置评雌、使用這些密鑰管理服務(wù)了树枫。
那為什么密鑰管理服務(wù)就能化解這個(gè)問題呢?原因在于景东,密鑰管理服務(wù)將密鑰加密后存儲(chǔ)在專門的安全存儲(chǔ)空間里砂轻,而不是放置在應(yīng)用程序里,比如說war包或jar包中的properties文件里斤吐。在應(yīng)用程序啟動(dòng)時(shí)搔涝,應(yīng)用程序會(huì)從密鑰管理服務(wù)讀取到對(duì)應(yīng)的密鑰厨喂,然后再使用。如此一來庄呈,應(yīng)用程序的properties文件中不再有任何密鑰出現(xiàn)蜕煌,就算攻擊者拿到了這個(gè)文件,也無法讀取到密鑰诬留。
安全原則有時(shí)候說不定能救你一命
如果你的架構(gòu)設(shè)計(jì)遵循了安全原則斜纪,就算你把密鑰硬編碼到源代碼或者放到了properties文件里,那也不意味著就一定會(huì)被攻擊者獲取到(排除運(yùn)氣成分)文兑。
首先是最小權(quán)限原則盒刚。此次漏洞是因?yàn)锳pache Tomcat的AJP協(xié)議的問題,這個(gè)協(xié)議默認(rèn)使用8009端口彩届,但其實(shí)絕大多數(shù)時(shí)候你都用不到這個(gè)協(xié)議伪冰。雖然Apache Tomcat默認(rèn)開啟這個(gè)協(xié)議誓酒,但如果你基于最小權(quán)限原則樟蠕,只對(duì)外開放必要協(xié)議及端口(比如就開HTTP 8080),把其他的統(tǒng)統(tǒng)都禁用掉靠柑,那么你也并不會(huì)受此次漏洞影響寨辩。
然后是縱深防御原則。就算疏忽大意沒有關(guān)閉AJP 8009端口歼冰,但如果你的應(yīng)用程序運(yùn)行在Docker容器里靡狞,那么容器和宿主機(jī)之間的網(wǎng)絡(luò)映射就是一層防御,默認(rèn)只開啟必要服務(wù)的端口隔嫡,比如只開HTTP 8080甸怕。盡管容器中實(shí)際運(yùn)行的是一個(gè)受此次漏洞影響的Tomcat,并且還開啟了AJP 8009端口腮恩,但因?yàn)檫@一層網(wǎng)絡(luò)映射的存在梢杭,攻擊者也無法從外部連接到Tomcat。
再進(jìn)一步秸滴,通常后端應(yīng)用都會(huì)有一個(gè)Ngnix反向代理頂在最前面武契,而在它前面可能還有網(wǎng)絡(luò)防火墻,這兩者也有管理網(wǎng)絡(luò)映射荡含、路由的功能咒唆。因此,在這種場景下释液,Tomcat服務(wù)器至少受到了3層防御工事的保護(hù)全释。除非這3層防御都配置失誤……
小結(jié)
Apache Tomcat CVE-2020-1938這個(gè)漏洞確實(shí)兇猛,攻擊者可以讀取到webapp目錄下的任意文件误债,包括war包浸船。而war包里有properties文件符衔,不少開發(fā)團(tuán)隊(duì)都把連接數(shù)據(jù)庫的用戶名密碼、JWT 簽名secret糟袁、加解密密鑰等重要信息放在這個(gè)文件里判族。這個(gè)漏洞的存在,允許攻擊者可以最終讀取到這些密鑰數(shù)據(jù)项戴,當(dāng)然源碼也是能通過反編譯war包里的class文件得到的形帮。
為了避免密鑰泄露,常規(guī)做法(不要硬編碼密鑰到源代碼周叮、密鑰單獨(dú)放置在properties文件并且和源代碼分別存儲(chǔ)在不同的代碼倉庫)并不奏效辩撑,更為妥善的辦法是使用密鑰管理服務(wù),你可以直接使用云服務(wù)提供商的密鑰管理服務(wù)仿耽,也可以自己搭建一個(gè)合冀。
?安全原則果然是很重要的,尤其是最小權(quán)限和縱深防御原則项贺。在這個(gè)漏洞案例中君躺,就算你使用的Tomcat有問題,但由于相關(guān)端口已經(jīng)關(guān)閉开缎,而且還有好幾層的網(wǎng)絡(luò)映射和路由配置的防御棕叫,所以也不會(huì)受到影響。當(dāng)然奕删,第三方組件安全管理俺泣、安全補(bǔ)丁管理、實(shí)施端口監(jiān)控等手段也有助于減輕或避免這個(gè)漏洞帶來的影響完残,但這就是另一個(gè)話題了伏钠,我們下次再聊。