Container Vulnerability Scanning — Not Just Shift Left Testing

smalltown
Starbugs Weekly 星巴哥技術專欄
13 min readOct 25, 2022

Background

近年來 DevSecOps 與 Shift Left Testing 在 DevOps 相關的技術討論中時常被提及,Container Scanning 便是其中一個相當重要的主題,一般想到的直覺做法就是在 CI/CD Pipeline 中加入 Container Image 掃描的步驟,當 Container Image 建置出來的時候就立即執行安全弱點掃描,假如掃描到風險高的安全弱點就將 CI/CD Pipeline 標為失敗,掃描不到具威脅性的安全弱點就允許部署到正式環境中,不過以資訊安全防禦方的角度來看,這樣就真的足夠了嗎?

答案當然是否定的,那麼要怎麼做會相對更安全,並且讓 DevSecOps 融入在開發流程的基因中,就是這篇文章想要探討的,文章會從什麼是 Container Scanning 開始談起,然後討論 Container 的生命週期,藉此暸解在每一個階段如何確保 Container 的安全無虞,最後提到當在 Container 中發現到安全弱點時該如何處置

What is Container Scanning

所謂的 Container Scanning 就是指利用掃描工具找出隱藏在 Container 中安全弱點的流程,而其具體做法與資安弱點通常會藏在哪裡呢?

📚 Mechanism

相關掃描工具的具體做法是透過逐層分析 Container Image 來找出掩藏於其中的安全弱點,大部分的掃描工具會將常見漏洞和披露公開資訊與找到的安全弱點做連結,例如 National Vulnerability Database (NVD) 和各大 Common Vulnerabilities & Exposures (CVE) 資料庫,如此一來,掃描工具的使用者可以方便地做後續的資訊安全弱點管理工作

🥶 冷知識

💡️ Common Vulnerabilities & Exposures (CVE):用來定義於軟/韌體所發現的資訊安全弱點,他本身並不是一個可以直接使用的資訊安全弱點資料庫

💡️ CVE Numbering Authority (CNA):授與被發現的 CVE 一個 ID 的單位,此 ID 也被稱為 CVE identifier,例如大家常常看到的 Log4j 2 CVE-2021–44228

💡️ Common Vulnerability Scoring System (CVSS):是用來定義 CVE 嚴重程度分級的一套標準,數字從 0.0 到 10.0,分數越高表示越嚴重

📚 Container Vulnerability Source

安全弱點可以透過以下幾種方式進入到 Container 中:

🐛 從 Base Image 和所安裝與使用的軟體與組態

🐛 從運行機器的作業系統

🐛 從 Container 的網路或是儲存裝置而來

🐛 Container 本身,運行 Container 的作業系統,其他運行在同一台主機上的 Container 間的交互作用而產生

不同的 Container 安全弱點來源,當然會需要透過不同的方式來發現,例如常被使用到的 Container Image Scanning 工具就是針對從 Base Image 和所使用的軟體而來的安全弱點去做掃瞄,他同時也是 Container Security 的關鍵點,因為他能夠讓開發,維運和資安團隊在 Containerized Application 部署到正式環境前就將威脅給排除掉

Container Image Lifecycle

所以要怎麼用掃描工具把 Container 給掃好掃滿呢?!當然就是將其安插在 Container Image 的生命週期內,而且不只是在 CI/CD 中而已,為什麼要這樣子做?不是有掃就好了?原因在於高威脅性的 CVE 隨時都有可能會誕生,所以在 Container 生命週期的每一個環節都必須要有可以把安全弱點給排除與監視的能力,而且時間點越早越好,避免任何的安全弱點在正式環境被懷有歹意的人利用

📚 Develop

瞎咪!在開發的時候就可以開始掃描嗎?沒錯,當然就是利用開發人員所使用的 IDE,以目前廣受歡迎的 Visual Studio Code 來說,已經有一些資安弱點掃描 Extension 在市面上推出,所以在寫程式的當下要是引用到具有有安全弱點的函式庫時,開發人員馬上就會知曉;Docker Desktop 的 Command docker scan 也可以在本機端就先掃描建置出來的 Container Image

🛠️ jFrog Xray

🛠️ Snyk Code

🛠️ Trivy Vulnerability Scanner

🛠️ Docker Desktop (docker scan) Integrate With Snyk

🛠 Haskell Dockerfile Linter

️ 🛠

當程式碼被推送到 Version Control System 時,其實也可以自動做安全弱點的掃描,換句話說,就是在程式碼被建置成 Container Image 前,就可以發現安全弱點

🛠️ GitHub

🛠️ GitLab

🛠️

📚 Build

DevSecOps 常常會提到的 (文章一開始也有提到),也就是將 Container Scanning 加在 CI/CD Pipeline 中,以自己看到目前的主流做法來說,這個掃描的動作通常會在 Container Image Registry 上面被執行,也就是說當 CI 工具將 Container Image 建置出來之後,將其推送到 Container Image Registry 去做安全弱點掃描,接著再根據掃描的結果去做對應的處置

相對嚴謹的做法會把同一個 Container Image 的 Registry 拆成測試與正式環境兩個 Registry,CI 工具先將建置完的 Container Image 推送到測試環境的 Container Image Registry 做安全弱點掃描,待確認掃描結果出來確認沒有高威脅性的安全弱點後,CI 工具再將 Container Image 推送到正式環境的 Container Image Registry

📚 Deploy

CI 工具將 Container Image 建置完成後,下一步就是透過 CD 工具將其部署到 Kubernetes 中,或是其他的 Container Orchestration Platform (此處以最多人使用的 K8s 來舉例),有沒有可能在 K8s 將 Pod 運行起來之前就把有安全弱點的 Container Image 給排除掉,不讓他成功運行起來;以 K8s 來說的話,可以利用 Admission Controller 來達成,因為其可以攔截任何發送到 K8s API 的請求,因此就可以開發一個 Admission Controller 來幫忙去跟 Image Scanner 確認,當 K8s 準備運行的 Container Image 具有高風險性安全弱點就不讓他運行成功

不過必須要注意到一點,並不是等 Admission Controller 去通知 Container Image Scanner 時才做掃瞄,這邊只是確認掃描結果是否符合預期;這邊建議整合 Open Policy Agent (OPA) 類似的角色來達成,讓 K8s 運行 Container Image 的政策可以更彈性,而不是只遵從 Container Image Scanner 的結果,例如可以針對開發環境和正式環境的 K8s Cluster 給予不同的政策,開發環境可以給予比較寬鬆的政策,正式環境當然就給予相對嚴格的政策

不過這樣不對啊,在上一個 Container Image 建置步驟時不是已經針對具有高風險安全弱點的 Container Image 做過相對應的處置了,為什麼這邊還需要再確認一次?因為在某些緊急狀況之下,手動部署有可能還是免不了,所以當沒有透過 CD 工具部署 Container Image 到正式環境的 K8s 叢集時,就會需要透過此種方式才能夠阻擋安全弱點跑到正式環境中

📚 Running

通過前面層層關卡開始運行的 Container 還是有可能具有安全弱點,只是還沒有被發現而已,例如本來使用到的某些函式庫突然爆發出高風險的安全弱點,此時就必須要趕緊去修復他,因為正式環境上具有高風險弱點是可以隨是被惡意人士利用的

所以就算是已經部署到 K8s 叢集內的 Container Image 還是要隨時去掃描,也就是說不只是 Shift Left Testing 把 Container Scanning 放到 CI/CD 的流程中而已,還要達到 Continuous Container Scanning/Monitoring 的境界,其實不少資安公司都已經有推出類似的商業解決方案,要是可以接受開源軟體的話,可以試試看 Trivy Operator

Vulnerability Management

談了許多如何將 Container Image 的安全弱點給找出來,但找出來之後該怎麼辦呢?而且假如同時爆發出多個 CVE 的話,哪一個要先進行修復的動作?這時候就需要有人來對這些安全弱點做管理的工作,也就是所謂的 Vulnerability Management,它通常分為四個階段來處理安全弱點,分別是…

📚 Identification

其實就是上面提到的 Container Scanning,不過組織內可能不止使用 Container 解決方案,或是具有不同的運行環境 (On-Premises vs. Cloud),所以會部署很多不同種類的 Scanner 在不同的地方,這個階段主要就是透過這些 Scanner 將安全弱點給抓出來

📚 Prioritization

當組織內系統眾多的狀況之下,同時有多個安全弱點在不同的環境中是很常見的現象,每一個的威脅性也不同,這時候需要視安全弱點對於組織的風險高低去排優先權將其修復;簡單來說可以透過 CVSS 分數來決定優先權,但還是要基於組織內的實際需求來做決定,例如某個 CVE 的 CVSS 為 10.0,但是只存在於某個在內部使用的次要系統,而不是在正式環境的機器中,這時候修復的優先權當然就會被排的後面一些

📚 Treatment

決定好優先權之後,就是要開始進行安全弱點的修復工作,通常會有底下幾種做法

🛠️ Upgrade/Patch: 假如不是大版本升級的話,這應該是最輕鬆的修復方式,所以就可以隨一般軟體的升級政策,先從測試環境開始升級起,確定沒有問題再將正式環境升級

🛠️ Workaround: 有時可能沒有新的版本可供升級,這時候就會透過一些避開安全弱點的方式,例如修改組態,把某個 Port 關掉…等方式來讓安全弱點無法被使用

🛠️ Not Fix: 在某些狀況之下的修復方式是接受此安全弱點的存在,前提當然大家都了解而且接受此安全弱點不會對組織造成威脅

📚 Verification and reporting

就像程式需要測試一樣,修復好之後當然需要驗證安全弱點是不是真的消失了,這個步驟其實沒有想像中的容易,因為組織內不同團隊所提供的服務都有其自有的生態系,所以都要先了解其如何運行與使用才能夠進行有效的驗證

Container Build Best Practices

除了在 Container 每一個生命週期將藏在其中的安全弱點給找出來之外,最後當然也要提一下,如何減少將安全弱點引進到 Container 中的一些做法 (Container Build Best Practices 其實用一篇文章也說不完,這邊主要專注在如何減少從第三方引進安全弱點的作法)

📚️ Right Base Image

首先當然要選擇正確的 Base Image,不過什麼叫做正確的?

🛠️ Small: 不需要的東西就不要讓他存在於 Container Image 中,所以請盡量選擇越小的 Container Image 來當 Base Image 越好

🛠️ Trusted: 選擇官方發佈的 Container Image 來當 Base Image,而不是莫名其妙來源的 Container Image,避免安全弱點在 Dockerfile 的第一行就被引進

🛠️ Distroless: 考慮使用 Distroless Container Image 來當 Base Image,這類型的 Container Image 沒有包含 Package Manager, Shell 或是任何其他的程式,換句話說就是人類使用起來很難用XD

🛠️ Classification: 測試和正式環境使用不同的 Base Image,理論上測試環境的 Container Image 會需要比較多的開發工具,但正式環境並不需要才對,所以正式環境的 Base Image 就可以將這些開發工具給移除掉

📚 Using Multi-Stage Builds

Docker 有個叫做 Multi-Stage Builds 的功能,它讓開發者可以同時使用多個 Container Image 去建置 Artifact,並且選擇性地從特定的 Container Image 中複製所需要的 Artifact 即可,把建置過程中需要的工具用完即丟,確保你的最終 Container Image 維持最小的容量

📚 Layer Ordering

最後一點跟減少安全弱點無關,但可以加快安全弱點的掃描效率,就是盡量將會對 Container Image 造成巨大改變的指令移動到 Dockerfile 後面一點才執行,例如編譯完的最終執行檔案,然後不會改變的部分放置在 Dockerfile 前面一點執行,這樣可以讓 Container Image Cache 發揮最大效用,加快 Container Image 的建置速度,同時也會提升 Container Scanning 的效率

Conclusion

自己覺得管理資訊安全弱點就是將風險控制在組織可接受的合理範圍內,所以盡量利用所擁有的資源去做最大努力,優先將對組織威脅性高的安全弱點給排除掉;然後一定要將 Container Scanning 的工作給自動化,不然就愧對 DevSecOps 這個 Buzzword 了 (誤) 其實是假如沒有自動化的話,這一堆事情要花的人力太多,而且也無法運行的精確與長久!

--

--

smalltown
Starbugs Weekly 星巴哥技術專欄

原來只是一介草 QA,但開始研究自動化維運雲端服務後,便一頭栽進 DevOps 的世界裏,熱愛鑽研各種可以提升雲端服務品質及增進團隊開發效率的開源技術