API安全風險主動感知與度量探索
0x1 背景
隨著應用越來越多,每天大量的代碼變更會帶來很多潛在的安全風險,如果這些風險沒有被挖掘出來帶病上線,那我們暴露出去的風險就會越來越多,如何在代碼變更后及時的感知到這些風險成為非常重要的事情,只有及時的感知,才能確保風險能得到檢測和確認,而目前我們尚沒有這樣的機制來確保代碼變更產生風險時第一時間展示出來并布置更多的跟進處理措施,這樣就會不斷的有新的風險暴露出去。
0x2 及時全面
當src又又收到外部白帽子提交的漏洞時,復盤大會上我們該怎么說呢?
- 這個功能點/api不知道啥時候上線的
- 這個功能點當時測試的沒問題啊(測試case、測試流量都在呢,那這個為什么沒測試到?每個請求對應測試的是哪個類型的漏洞)
- 這個漏洞修復了啊,代碼不知道啥時候回滾了,orz
- 這個當時活太多沒來得及測,orz
- 自動化工具沒有覆蓋這個漏洞的檢測能力(那么我們的自動化檢測工具提供了哪些測試能力能列出來嗎,這塊的檢測能力有改進空間嗎?)
以上回復基本都是因為沒測到、沒來的及測,總結下就是兩個很關鍵的點沒有得到保障
- 測試覆蓋度
- 測試時效性
綜上,當應用更新時只有及時全面的進行安全測試才能確保應用是相對安全的,那么及時和全面就分別對應測試時效性和測試覆蓋度
0x201 測試覆蓋度
先說下測試覆蓋度,安全測試和業務(質量)測試(QUALITY ASSURANCE)同學的工作性質有點類似,如果有個功能點或者api沒測試到根據墨菲定律這個點就很容易會出現問題,那么如何避免這個問題呢,那就是需要有平臺有數據來量化測試覆蓋度,這個平臺有多少api,測試了多少,測試了多少不同類型的case,測試覆蓋度依賴于以上數據。
0x202 測試時效性
如果每次研發同學發布了新的代碼,安全同學如果都是一年以后來檢查這些代碼有沒有新的風險那安全檢測的意義好像就變低了,當然現實中是不可避免的人力不足,比如一個安全同學負責成百上千個應用的安全,如果沒有好用的自動化工具那么安全同學其實是很難應付的過來,安全測試的時效性就很難保障,目前集團有非常棒的掃描平臺來支持我們做白盒掃描/黑盒掃描,同時目前iast模式的灰盒測試也在推廣中了,這些都是非常棒的實踐。
0x3 風險度量
度量的目的是讓我們能夠清楚的知道我們的工作重點應該在哪里,不能為了度量而度量,度量或者分析后面應該跟進很多安全動作,比如新增了接口就需要及時的進行安全測試,這樣就能確保每個新增api及時的得到安全測試,這樣就能覆蓋全部的api,同時保證了時效性。要確保覆蓋度,最重要的一點就是我們需要知道我們的分子、分母分別是什么。不同的應用對外提供服務的方式不一樣,基于目前B/S、C/S架構來講,目前絕大多數風險在S端對應的后端應用上,目前對公網開放應用絕大多數還是通過rest-api的方式提供服務,后端服務除了api還有大量的rpc接口,目前來看webx、springboot、nodejs等框架類應用普及率越來越高,那么我們就拿webx為例來分享下如何做到應用風險可見,那我們思考下,一個應用在merge代碼的時候可能會帶來哪些安全問題,針對使用最多的java應用,我總結了兩點
1 更新了pom文件,引入/消除了新的存在問題的二/三方組件
2 api或者api代碼調用鏈發生了變化
理論上只要我們分析出以上兩個變更就可以非常清楚的知道一次commit到底會不會帶來新的風險,對于一些特殊場景,比如api下線,不僅僅意味著風險的消亡,同樣意味著我們需要去更新我們的資產庫標記相應的api已下線。
0x301 覆蓋率中的變化的分母
要確保一個應用中的api/rpc接口全部得到測試,我們就需要獲取到一個應用中包含的全部api/rpc接口,這是我們計算測試覆蓋度的分母,而且隨著應用代碼的迭代這個分母是變化的,這個分母的變化就會帶來風險。
pom里更新組件帶來的問題目前基于漏洞庫已經基本上覆蓋掉了,那我們說下第二點 api層面的變更和api調用鏈的變化
從上圖我們舉個栗子來講,先從commit1和commit2來講下,假設commit1的時候我們通過自動化、人工確認應用是相對安全的了,那我們標記應用當前的狀態是 safe,當監控到應用有merge時,也就是應用處于commit2狀態時我們通過自動化分析發現api還是3個,但是api2的調用鏈上某個方法發生了變化,這時候我們就需要標注出當前應用因為代碼更新新增的風險是 api2的調用鏈上某個方法發生變更了,這時候就需要我們去確認是否有新增風險。
再比如commit2到commit3 ,新增了一個api4,這時候 新增的這個api4 就是需要我們去關注的風險。
按照上面的邏輯,我們應該可以把新增的風險梳理出來,主要是防止新增風險慢慢變成存量風險,不積硅步無以至千里,哎,好像不大應景。。。
就像前面說的一個應用對外提供服務基本就兩種方式,一個是rest-api,一個是rpc接口,也就是對一個應用而言除去運行環境下,暴露的攻擊面就是各種接口了, 這就是一個應用全部的分母,也就是我們保護的對象。
想要梳理一個應用包含哪些api/rpc接口方法有很多,基于流量、AST分析、插樁、swagger插件都是可以的,從源碼層面分析最簡單的應該是基于AST來獲取,針對常規的springboot項目或者pandoraboot項目,通過AST很容易分析出其中的api變化,當然如果做的精致一些可以基于源碼輸出類似swagger組件輸出一樣的數據,接口、入參名、入參類型、返回類型、返回如果是一個對象、對象的屬性有哪些,這些信息對安全測試而言同樣都是非常有用的信息。
0x302 誰來保證分子
要想保證分子是更加接近分母就需要思考以下問題,
- 這個應用有多少api?(資產庫)
- 這些api測試了嗎?
2.1 誰測試的?
2.2 什么時候測試的?
2.3 測試時候的代碼和現在的代碼一樣嗎?也就是現在的api還是當時的api嗎?不會更新了吧?不會回滾了吧?
2.4 測試記錄還在嗎?(怎么證明你測了!!!)
2.5 測試了哪些姿勢?(這么敏感的接口居然沒測試過越權?自動化工具不支持?) - 代碼更新以后風險能感知到嗎?
- 感知到以后需要哪些能力支持我們去自動化確認這些風險?黑盒、白盒、人工、iast
當前最實際的問題是線上運行的成千上萬的應用中包含的漏洞該怎么挖掘出來,同時怎么防止新增風險變成存量風險。這兩個問題中更重要的應該是怎么防止新增風險變成存量風險,否則我們就會陷入一直在處理存量風險的困境。那么讓新增風險可見就變成了一個非常緊急且重要的事情。要實現風險可見需要幾個關鍵點。
風險可見的關鍵點:
- 自動化分析是否有新增api
- 自動化分析原有api調用鏈以及調用鏈上各個方法是否有變更
而要實現第二點就需要把每個api對應的調用鏈和調用鏈上的各個方法統一存儲進來方便進行比對。
0x4 新增風險分析實踐
此圖為在猿輔導打工時團隊產出的腦圖(手動感謝andr01la、l4yn3liu、T00ls01)
基于上圖拿內部某個應用進行實踐,通過實踐我們可以輸出代碼變更時是否有新的api產生,是否有api對應的調用鏈的變化
0x401 基于ast分析api/rpc接口
0x40101 rest-api
使用AST梳理api可以根據類或者方法注解進行查找,最常見的注解為以下幾類
比如針對以下代碼通過分析注解也可以獲取到類似swagger的數據輸出
0x40102 hsf/dubbo
0x402 調用鏈關系獲取
從某個api開始分析
/contract/buy/queryInfoByEmail.json對應的入口方法是queryInfoByEmail,從該方法做為開始我們通過codeQL獲取其調用鏈上的各個方法
以上我們通過批量、遞歸操作就可以獲取到一個api對應的入口方法開始其中調用鏈上的各個方法和在代碼中的索引值,知道了索引值也就可以從源碼中獲取到每個方法的代碼塊和調用位置,就可以獲取到類似以下的信息
如此就可以獲取到某個應用某個commitid下api對應的調用鏈信息和每個方法的具體代碼了,當應用被更新時,重新執行以上流程就可以獲取到在新的commitid下api信息以及調用鏈信息,對信息進行比對就可以獲取到差異,而風險就存在于變化之中。
0x403 產品化
以上我們可以獲取到api以及api調用上的變化,那么這些變化就是需要確認的風險點,通過產品或者平臺將這些信息展示出來我們就可以很直觀的看到風險點,下一步就是確認這些風險是否是需要進一步處理的,最原始的方法就是人工確認,最起碼這就有了一個可以做動作的入口。同時如果通過自動化手段可以把api、api調用鏈變化信息、調用鏈中每個方法的源碼、api測試樣例都能在一套平臺里展示出來,那都將極大的提升審查漏洞、復核漏洞的效率。
0x5 需要的能力
0x501 API發現能力
一部分通過AST解析獲取代碼中的api,另一部分來自于流量清洗獲取。 這兩種方式各有優劣,ast準確率高但是缺少請求樣例,流量中解析需要做歸一化處理,如果處理不好一個應用下就變成了有十幾萬API,優勢就是有請求樣例(request、response),如果ast和流量解析出來的請求能統一起來,那么我們就可以獲取到指定應用下有多少api、api入口類和方法、請求樣例、對應的響應樣例,這樣一個應用下基礎信息就有了。后續每個api會透出什么信息、是哪類敏感信息就都可以做了。
0x502 檢測能力量化
不管是所謂的大廠還是小廠,真正接觸過后才知道很多應用其實是根本沒有做過安全測試的,有些是沒有流量觸發不了掃描,有些是post接口擔心影響業務不敢掃,假如有了前面的api列表信息,并且黑盒能夠標注哪些做過檢測了,檢測的漏洞類型是什么都記錄下來,那么我們就可以很清晰的知道咱們應用哪些漏洞類型還沒有做檢測,沒有做的檢測就需要我們黑白盒、安全運營工程師一起努力來打造、提升檢測能力;另一方面外部提交漏洞時也可以快速的復盤知道這個api我們內部到底有沒有測試到這個api、何時、何人測試的。
0x503 接口變更感知能力
前面同樣鋪墊過了,所有的變化都是需要能被感知到的,并且需要有能力檢測到哪些變更會帶來風險,帶來的風險需要誰去判斷是否真正存在漏洞,誰來卡點?是統一在一個平臺比如soc處理,還是需要安全工程師來回切換,比如接口是mtop發布然后就需要去mtop看接口信息、看入參、出參?
是不是可以根據過往數據來分析呢?比如新增了一個api返回的數據類型和另一個已發布接口的數據類型是一樣的,比如都是某個Order類型的對象,那是不是就可以作為參考呢?
0x6 總結
以上是最近在安全運營工作中在遇到一些迷惑之處的思考,大佬們有其他意見和建議也可以在下方留言或者wx(m0l1ce)