在 CI/CD pipeline 中加入安全性檢測吧!

莫力全 Kyle Mo
9 min readNov 11, 2022
應該是今年最後一次露營吧!

自己今年文章的產量跟去年比起來少了很多,主要是因為以往都是撰寫一些技術概念,而近期我希望自己能夠透過文章分享一些自身的經驗,畢竟每個人親身經歷的事都是獨一無二無法被複製的,而技術概念則可以在網路上搜尋到許多大同小異的內容,不是說那些內容不重要,而是自己沒有信心可以寫的比其他人還要好。

既然是分享自身經驗,靈感自然就會來自於工作或是空閒時間自己研究的成果,其實大多數時間處理的問題我都不覺得有獨特到可以寫一篇文章紀錄,所以這陣子遇到了「不知道要寫什麼」的瓶頸。好在最近工作又碰了些有趣的東西,趕緊把握機會紀錄一下。

MOPCON 的分享中我有稍微介紹 Web Infra Team,也提到團隊的下一步可能是 Security 相關的主題。其實原先我們導入的工具中就有包含資安相關的檢測了,SonarQube 這個程式碼品質管理工具可以透過掃描程式碼檢測出潛在的問題

From MOPCON Slide

可以看到有些問題被歸類為 Vulnerability 與 Security Hotspot 等資安相關的 issues。SonarQube 的這種檢測方式屬於不用實際執行程式,透過掃描 source code 找出潛在漏洞的「靜態分析 Static Application Security Testing (SAST)」,而這次 Infra Team 的目標則是尋找另一種檢測方式 — 動態分析 Dynamic Application Security Testing (DAST),透過掃描或甚至攻擊「實際運行的應用」來找出潛在的資安問題。其實除了靜態與動態分析,還有另一種較主流的檢測類型叫做「Software Composition Analysis (SCA)」,主要是檢測應用相關 open source dependencies 的 license 資訊與潛在的 vulnerabilities。

看到這裡也許你會認為我們必須在這幾種不同的檢測方式中擇一使用,但其實在開發流程的不同階段可以分別執行這些檢測,更加保障應用的安全性。

DevSecOps

近期 DevSecOps 這個詞其實受到了蠻大的關注,它的概念大概為

DevSecOps 的概念是指使軟體安全性成為整個軟體交付程序的核心部分。

它算是一種文化而非明確的工具,從名字也可以看出跟我們熟知的 DevOps 有一點淵源。DevSecOps 無法取代 DevOps。它只是將 DevOps 背後的核心概念擴大,亦即開發人員和 IT 團隊應該密切合作來達到安全性,而不是各自作業。有效的 DevSecOps 表示接受 DevOps 並將安全性整合到完整的 CI/CD Pipeline 中。(想了解更多可以看這篇文章

出自這個 Repo

關於 DevSecOps 的解釋有很多版本,也因為它是一種文化或概念,因此也沒有所謂「正確」的實踐方式。不過身為應用端的開發者,我們可以思考如何將這份思想整合進軟體開發流程中,最直覺的方式就是在 CI/CD pipeline 的各個階段導入對應適合的資安檢測流程。

圖片來源

在過去,我們習慣在產品開發週期的末段再去做滲透測試,找出潛在的安全性問題,這時候如果發現一些問題,必須修正後重新跑一遍產品的 Lifecycle 才能解決,缺點很明顯,就是獲得 feedback 的時間太慢了。

實踐 DevSecOps 後(圖片來源同上圖)

如果我們可以導入 DevSecOps 的精神,在產品生命週期的各個 stage 執行對應的安全性檢測,就可以更快的獲得 feedback,也可以盡量避免有漏洞的應用被部署到 production 環境中。

因為整個產品的開發週期其實會需要不同的角色去協作,所以我們先拉回身為開發者最直接可以影響的 CI/CD Pipeline。

如果盡量貫徹 DevSecOps 的話,理想的 CI/CD pipeline 應該會是以下這個樣子:

上方是過往我們在開發時所習慣的 CI/CD 流程

Lint -> Build -> Test -> Deploy

而在這些流程中,其實可以穿插一些合適的 security scan:

  • 在 lint 階段可以利用例如 eslint-plugin-security 等套件避免寫出會造成 security issues 的程式,另外也可以做 dependency 的 security check,不過實際在專案中我們是透過 GitHub 的 Dependabot 來協助檢測 dependencies 的 vulnerabilities。
  • build 階段產生新的 image 後可以透過 trivy 這樣的服務去做掃描
  • test 階段則可以搭配剛剛提過的 SonarQube 做靜態檢測。在我們的專案中因為 SonarQube 會協助紀錄應用的 test coverage 並定期發送資料到 Prometheus,所以會需要先跑完 test 再執行 SonarQube 檢測,兩者是互相依賴的 pipeline steps。
  • Deploy 之後仍然可以透過剛剛提過的工具 trivy 去檢測 container、K8S…等環境的 config 有沒有 vulnerabilities 與 misconfigurations。
  • 部署完後的應用就可以去執行剛剛提過的 DAST 動態分析,看看實際運行的運用是不是有資安相關的問題。

Web Infra Team 這次研究的重點就是最後的 DAST 步驟,希望找到一個可以把動態檢測綁到 CI/CD 流程中的開源工具(免費的最好)。

經過了一段時間的研究,我發現在 DAST 領域最知名的開源「免費」工具是一個名為 ZAP Proxy 的專案(意思是要收費的我們都先不考慮)。

Repo

從上圖的 description 可以看到它提供了各種 docker image 讓我們可以把檢測流程綁到 CI/CD 流程中,看起來非常符合我們的需求。

ZAP 提供了現成的 Docker Image (Link)

使用 ZAP 提供的 Image,它其實提供了很多現成的檢測方案,我們可以直接呼叫它寫好的 script 去對特定網站做檢測,

ZAP image 提供的 packaged scan

例如它提供我們三種檢測方式

  • Baseline Scan:最簡單的方式,會透過一個 Spider 去檢測我們正在運行中的網站。
  • Full Scan:除了包含 Baseline Scan 的檢測以外,還會「實際攻擊」我們的網站看看是否有資安風險。(執行時間非常長,不太適合放到常規 CI/CD 流程裡,較適合定期間隔跑檢測)
  • API Scan:專門對 API 進行資安檢測。

因為我們的專案不是 API 開發,自然不會選擇 API Scan,而 Full Scan 因為執行時間太長,並不適合綁到 CI/CD 流程中,因此看來最適合的就是 Baseline Scan 了。我們根據官方文件提供的指令實際看看:

docker run -t owasp/zap2docker-stable zap-baseline.py -t https://www.example.com

得出的結果如下:

主要是關於網站 Cookie、Response Header、CSP policy…等等相關的資訊,以及告訴我們這些設定是否有正確被設置。

我們也可以建立一個設定檔指定各個 Rule 沒有通過時要 WARN、FAIL 還是 IGNORE。

ZAP rules 設定檔

如果在 CLI 指令中有指定要產出 report,在執行完檢測後可以得到一個 HTML repot 檔,提供了更詳細的資訊。

ZAP repot

最後將 ZAP Baseline 檢測綁到 CI Pipeline 看看

一些 URL 的部分就先塗掉惹

這邊只是隨意建立一個 step 測試看看而已,實際上我認為沒有必要每次 CI Pipeline 都執行 ZAP scan,自己覺得比較理想的執行時機是當應用 deploy 到 RC 環境與 Production 環境之後。

小結

雖然 Web Infra Team 還沒有確定要使用 ZAP Proxy 作為 DAST 的解決方案(還在 survey 階段),不過目前看來它是最符合我們需求的工具,我也因為這次研究的機會,去接觸了 DevSecOpts 的概念,理解了不同的安全性檢測模式。

我們可以理解 Security 這個議題在未來只會變得越來越重要,就算你跟我一樣是應用開發者,也有我們可以做到的事,現在就試著幫你的 CI/CD Pipeline 加入安全性檢測吧!

推薦閱讀

--

--